blob: 2ea5e2def9acff8c2c0e132a95fa803c5ba57095 [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));
Victor Stinner68d29802017-03-09 18:43:39 +01001935#if defined(HAVE_LARGEFILE_SUPPORT) || defined(MS_WINDOWS)
1936 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 PyStructSequence_SET_ITEM(v, 1,
Victor Stinner68d29802017-03-09 18:43:39 +01001938 PyLong_FromUnsignedLongLong(st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001939#else
Victor Stinner68d29802017-03-09 18:43:39 +01001940 Py_BUILD_ASSERT(sizeof(unsigned long) >= sizeof(st->st_ino));
1941 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLong(st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001942#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001943#ifdef MS_WINDOWS
1944 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001945#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001946 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001947#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001948 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001949#if defined(MS_WINDOWS)
1950 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1951 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1952#else
1953 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1954 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1955#endif
Fred Drake699f3522000-06-29 21:12:41 +00001956#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001957 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001958 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001959#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001960 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001961#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001962
Martin v. Löwis14694662006-02-03 12:54:16 +00001963#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 ansec = st->st_atim.tv_nsec;
1965 mnsec = st->st_mtim.tv_nsec;
1966 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001967#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 ansec = st->st_atimespec.tv_nsec;
1969 mnsec = st->st_mtimespec.tv_nsec;
1970 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001971#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001972 ansec = st->st_atime_nsec;
1973 mnsec = st->st_mtime_nsec;
1974 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001975#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001977#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001978 fill_time(v, 7, st->st_atime, ansec);
1979 fill_time(v, 8, st->st_mtime, mnsec);
1980 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001981
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001982#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1984 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001985#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001986#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1988 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001989#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001990#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1992 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001993#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001994#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001995 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1996 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001997#endif
1998#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001999 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002000 PyObject *val;
2001 unsigned long bsec,bnsec;
2002 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002003#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002004 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002005#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002006 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002007#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002008 if (_stat_float_times) {
2009 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2010 } else {
2011 val = PyLong_FromLong((long)bsec);
2012 }
2013 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2014 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002017#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002018 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2019 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002020#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002021#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2022 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2023 PyLong_FromUnsignedLong(st->st_file_attributes));
2024#endif
Fred Drake699f3522000-06-29 21:12:41 +00002025
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 if (PyErr_Occurred()) {
2027 Py_DECREF(v);
2028 return NULL;
2029 }
Fred Drake699f3522000-06-29 21:12:41 +00002030
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002032}
2033
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002034/* POSIX methods */
2035
Guido van Rossum94f6f721999-01-06 18:42:14 +00002036
2037static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002038posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002039 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002040{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002041 STRUCT_STAT st;
2042 int result;
2043
2044#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2045 if (follow_symlinks_specified(function_name, follow_symlinks))
2046 return NULL;
2047#endif
2048
2049 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2050 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2051 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2052 return NULL;
2053
2054 Py_BEGIN_ALLOW_THREADS
2055 if (path->fd != -1)
2056 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002057#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002058 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002059 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002060 else
Steve Dowercc16be82016-09-08 10:35:16 -07002061 result = win32_lstat(path->wide, &st);
2062#else
2063 else
2064#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002065 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2066 result = LSTAT(path->narrow, &st);
2067 else
Steve Dowercc16be82016-09-08 10:35:16 -07002068#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002069#ifdef HAVE_FSTATAT
2070 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2071 result = fstatat(dir_fd, path->narrow, &st,
2072 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2073 else
Steve Dowercc16be82016-09-08 10:35:16 -07002074#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002076#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002077 Py_END_ALLOW_THREADS
2078
Victor Stinner292c8352012-10-30 02:17:38 +01002079 if (result != 0) {
2080 return path_error(path);
2081 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002082
2083 return _pystat_fromstructstat(&st);
2084}
2085
Larry Hastings2f936352014-08-05 14:04:04 +10002086/*[python input]
2087
2088for s in """
2089
2090FACCESSAT
2091FCHMODAT
2092FCHOWNAT
2093FSTATAT
2094LINKAT
2095MKDIRAT
2096MKFIFOAT
2097MKNODAT
2098OPENAT
2099READLINKAT
2100SYMLINKAT
2101UNLINKAT
2102
2103""".strip().split():
2104 s = s.strip()
2105 print("""
2106#ifdef HAVE_{s}
2107 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002108#else
Larry Hastings2f936352014-08-05 14:04:04 +10002109 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002110#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002111""".rstrip().format(s=s))
2112
2113for s in """
2114
2115FCHDIR
2116FCHMOD
2117FCHOWN
2118FDOPENDIR
2119FEXECVE
2120FPATHCONF
2121FSTATVFS
2122FTRUNCATE
2123
2124""".strip().split():
2125 s = s.strip()
2126 print("""
2127#ifdef HAVE_{s}
2128 #define PATH_HAVE_{s} 1
2129#else
2130 #define PATH_HAVE_{s} 0
2131#endif
2132
2133""".rstrip().format(s=s))
2134[python start generated code]*/
2135
2136#ifdef HAVE_FACCESSAT
2137 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2138#else
2139 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2140#endif
2141
2142#ifdef HAVE_FCHMODAT
2143 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2144#else
2145 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2146#endif
2147
2148#ifdef HAVE_FCHOWNAT
2149 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2150#else
2151 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2152#endif
2153
2154#ifdef HAVE_FSTATAT
2155 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2156#else
2157 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2158#endif
2159
2160#ifdef HAVE_LINKAT
2161 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2162#else
2163 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2164#endif
2165
2166#ifdef HAVE_MKDIRAT
2167 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2168#else
2169 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2170#endif
2171
2172#ifdef HAVE_MKFIFOAT
2173 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2174#else
2175 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2176#endif
2177
2178#ifdef HAVE_MKNODAT
2179 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2180#else
2181 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2182#endif
2183
2184#ifdef HAVE_OPENAT
2185 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2186#else
2187 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2188#endif
2189
2190#ifdef HAVE_READLINKAT
2191 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2192#else
2193 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2194#endif
2195
2196#ifdef HAVE_SYMLINKAT
2197 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2198#else
2199 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2200#endif
2201
2202#ifdef HAVE_UNLINKAT
2203 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2204#else
2205 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2206#endif
2207
2208#ifdef HAVE_FCHDIR
2209 #define PATH_HAVE_FCHDIR 1
2210#else
2211 #define PATH_HAVE_FCHDIR 0
2212#endif
2213
2214#ifdef HAVE_FCHMOD
2215 #define PATH_HAVE_FCHMOD 1
2216#else
2217 #define PATH_HAVE_FCHMOD 0
2218#endif
2219
2220#ifdef HAVE_FCHOWN
2221 #define PATH_HAVE_FCHOWN 1
2222#else
2223 #define PATH_HAVE_FCHOWN 0
2224#endif
2225
2226#ifdef HAVE_FDOPENDIR
2227 #define PATH_HAVE_FDOPENDIR 1
2228#else
2229 #define PATH_HAVE_FDOPENDIR 0
2230#endif
2231
2232#ifdef HAVE_FEXECVE
2233 #define PATH_HAVE_FEXECVE 1
2234#else
2235 #define PATH_HAVE_FEXECVE 0
2236#endif
2237
2238#ifdef HAVE_FPATHCONF
2239 #define PATH_HAVE_FPATHCONF 1
2240#else
2241 #define PATH_HAVE_FPATHCONF 0
2242#endif
2243
2244#ifdef HAVE_FSTATVFS
2245 #define PATH_HAVE_FSTATVFS 1
2246#else
2247 #define PATH_HAVE_FSTATVFS 0
2248#endif
2249
2250#ifdef HAVE_FTRUNCATE
2251 #define PATH_HAVE_FTRUNCATE 1
2252#else
2253 #define PATH_HAVE_FTRUNCATE 0
2254#endif
2255/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002256
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002257#ifdef MS_WINDOWS
2258 #undef PATH_HAVE_FTRUNCATE
2259 #define PATH_HAVE_FTRUNCATE 1
2260#endif
Larry Hastings31826802013-10-19 00:09:25 -07002261
Larry Hastings61272b72014-01-07 12:41:53 -08002262/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002263
2264class path_t_converter(CConverter):
2265
2266 type = "path_t"
2267 impl_by_reference = True
2268 parse_by_reference = True
2269
2270 converter = 'path_converter'
2271
2272 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002273 # right now path_t doesn't support default values.
2274 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002275 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002276 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002277
Larry Hastings2f936352014-08-05 14:04:04 +10002278 if self.c_default not in (None, 'Py_None'):
2279 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002280
2281 self.nullable = nullable
2282 self.allow_fd = allow_fd
2283
Larry Hastings7726ac92014-01-31 22:03:12 -08002284 def pre_render(self):
2285 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002286 if isinstance(value, str):
2287 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002288 return str(int(bool(value)))
2289
2290 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002291 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002292 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002293 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002294 strify(self.nullable),
2295 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002296 )
2297
2298 def cleanup(self):
2299 return "path_cleanup(&" + self.name + ");\n"
2300
2301
2302class dir_fd_converter(CConverter):
2303 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002304
Larry Hastings2f936352014-08-05 14:04:04 +10002305 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002306 if self.default in (unspecified, None):
2307 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002308 if isinstance(requires, str):
2309 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2310 else:
2311 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002312
Larry Hastings2f936352014-08-05 14:04:04 +10002313class fildes_converter(CConverter):
2314 type = 'int'
2315 converter = 'fildes_converter'
2316
2317class uid_t_converter(CConverter):
2318 type = "uid_t"
2319 converter = '_Py_Uid_Converter'
2320
2321class gid_t_converter(CConverter):
2322 type = "gid_t"
2323 converter = '_Py_Gid_Converter'
2324
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002325class dev_t_converter(CConverter):
2326 type = 'dev_t'
2327 converter = '_Py_Dev_Converter'
2328
2329class dev_t_return_converter(unsigned_long_return_converter):
2330 type = 'dev_t'
2331 conversion_fn = '_PyLong_FromDev'
2332 unsigned_cast = '(dev_t)'
2333
Larry Hastings2f936352014-08-05 14:04:04 +10002334class FSConverter_converter(CConverter):
2335 type = 'PyObject *'
2336 converter = 'PyUnicode_FSConverter'
2337 def converter_init(self):
2338 if self.default is not unspecified:
2339 fail("FSConverter_converter does not support default values")
2340 self.c_default = 'NULL'
2341
2342 def cleanup(self):
2343 return "Py_XDECREF(" + self.name + ");\n"
2344
2345class pid_t_converter(CConverter):
2346 type = 'pid_t'
2347 format_unit = '" _Py_PARSE_PID "'
2348
2349class idtype_t_converter(int_converter):
2350 type = 'idtype_t'
2351
2352class id_t_converter(CConverter):
2353 type = 'id_t'
2354 format_unit = '" _Py_PARSE_PID "'
2355
Benjamin Petersonca470632016-09-06 13:47:26 -07002356class intptr_t_converter(CConverter):
2357 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002358 format_unit = '" _Py_PARSE_INTPTR "'
2359
2360class Py_off_t_converter(CConverter):
2361 type = 'Py_off_t'
2362 converter = 'Py_off_t_converter'
2363
2364class Py_off_t_return_converter(long_return_converter):
2365 type = 'Py_off_t'
2366 conversion_fn = 'PyLong_FromPy_off_t'
2367
2368class path_confname_converter(CConverter):
2369 type="int"
2370 converter="conv_path_confname"
2371
2372class confstr_confname_converter(path_confname_converter):
2373 converter='conv_confstr_confname'
2374
2375class sysconf_confname_converter(path_confname_converter):
2376 converter="conv_sysconf_confname"
2377
2378class sched_param_converter(CConverter):
2379 type = 'struct sched_param'
2380 converter = 'convert_sched_param'
2381 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002382
Larry Hastings61272b72014-01-07 12:41:53 -08002383[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002384/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002385
Larry Hastings61272b72014-01-07 12:41:53 -08002386/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002387
Larry Hastings2a727912014-01-16 11:32:01 -08002388os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002389
2390 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002391 Path to be examined; can be string, bytes, path-like object or
2392 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002393
2394 *
2395
Larry Hastings2f936352014-08-05 14:04:04 +10002396 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002397 If not None, it should be a file descriptor open to a directory,
2398 and path should be a relative string; path will then be relative to
2399 that directory.
2400
2401 follow_symlinks: bool = True
2402 If False, and the last element of the path is a symbolic link,
2403 stat will examine the symbolic link itself instead of the file
2404 the link points to.
2405
2406Perform a stat system call on the given path.
2407
2408dir_fd and follow_symlinks may not be implemented
2409 on your platform. If they are unavailable, using them will raise a
2410 NotImplementedError.
2411
2412It's an error to use dir_fd or follow_symlinks when specifying path as
2413 an open file descriptor.
2414
Larry Hastings61272b72014-01-07 12:41:53 -08002415[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002416
Larry Hastings31826802013-10-19 00:09:25 -07002417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002418os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002419/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002420{
2421 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2422}
2423
Larry Hastings2f936352014-08-05 14:04:04 +10002424
2425/*[clinic input]
2426os.lstat
2427
2428 path : path_t
2429
2430 *
2431
2432 dir_fd : dir_fd(requires='fstatat') = None
2433
2434Perform a stat system call on the given path, without following symbolic links.
2435
2436Like stat(), but do not follow symbolic links.
2437Equivalent to stat(path, follow_symlinks=False).
2438[clinic start generated code]*/
2439
Larry Hastings2f936352014-08-05 14:04:04 +10002440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002441os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2442/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002443{
2444 int follow_symlinks = 0;
2445 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2446}
Larry Hastings31826802013-10-19 00:09:25 -07002447
Larry Hastings2f936352014-08-05 14:04:04 +10002448
Larry Hastings61272b72014-01-07 12:41:53 -08002449/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002450os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002451
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002452 path: path_t
2453 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002454
2455 mode: int
2456 Operating-system mode bitfield. Can be F_OK to test existence,
2457 or the inclusive-OR of R_OK, W_OK, and X_OK.
2458
2459 *
2460
Larry Hastings2f936352014-08-05 14:04:04 +10002461 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002462 If not None, it should be a file descriptor open to a directory,
2463 and path should be relative; path will then be relative to that
2464 directory.
2465
2466 effective_ids: bool = False
2467 If True, access will use the effective uid/gid instead of
2468 the real uid/gid.
2469
2470 follow_symlinks: bool = True
2471 If False, and the last element of the path is a symbolic link,
2472 access will examine the symbolic link itself instead of the file
2473 the link points to.
2474
2475Use the real uid/gid to test for access to a path.
2476
2477{parameters}
2478dir_fd, effective_ids, and follow_symlinks may not be implemented
2479 on your platform. If they are unavailable, using them will raise a
2480 NotImplementedError.
2481
2482Note that most operations will use the effective uid/gid, therefore this
2483 routine can be used in a suid/sgid environment to test if the invoking user
2484 has the specified access to the path.
2485
Larry Hastings61272b72014-01-07 12:41:53 -08002486[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002487
Larry Hastings2f936352014-08-05 14:04:04 +10002488static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002489os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002490 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002491/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002492{
Larry Hastings2f936352014-08-05 14:04:04 +10002493 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002494
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002495#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002496 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002497#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002498 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002499#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500
Larry Hastings9cf065c2012-06-22 16:30:09 -07002501#ifndef HAVE_FACCESSAT
2502 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002503 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002504
2505 if (effective_ids) {
2506 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002507 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508 }
2509#endif
2510
2511#ifdef MS_WINDOWS
2512 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002513 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002514 Py_END_ALLOW_THREADS
2515
2516 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002517 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002518 * * we didn't get a -1, and
2519 * * write access wasn't requested,
2520 * * or the file isn't read-only,
2521 * * or it's a directory.
2522 * (Directories cannot be read-only on Windows.)
2523 */
Larry Hastings2f936352014-08-05 14:04:04 +10002524 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002525 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002526 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002527 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002528#else
2529
2530 Py_BEGIN_ALLOW_THREADS
2531#ifdef HAVE_FACCESSAT
2532 if ((dir_fd != DEFAULT_DIR_FD) ||
2533 effective_ids ||
2534 !follow_symlinks) {
2535 int flags = 0;
2536 if (!follow_symlinks)
2537 flags |= AT_SYMLINK_NOFOLLOW;
2538 if (effective_ids)
2539 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002540 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 }
2542 else
2543#endif
Larry Hastings31826802013-10-19 00:09:25 -07002544 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002545 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002546 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002547#endif
2548
Larry Hastings9cf065c2012-06-22 16:30:09 -07002549 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002550}
2551
Guido van Rossumd371ff11999-01-25 16:12:23 +00002552#ifndef F_OK
2553#define F_OK 0
2554#endif
2555#ifndef R_OK
2556#define R_OK 4
2557#endif
2558#ifndef W_OK
2559#define W_OK 2
2560#endif
2561#ifndef X_OK
2562#define X_OK 1
2563#endif
2564
Larry Hastings31826802013-10-19 00:09:25 -07002565
Guido van Rossumd371ff11999-01-25 16:12:23 +00002566#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002567/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002568os.ttyname -> DecodeFSDefault
2569
2570 fd: int
2571 Integer file descriptor handle.
2572
2573 /
2574
2575Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002576[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002577
Larry Hastings31826802013-10-19 00:09:25 -07002578static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002579os_ttyname_impl(PyObject *module, int fd)
2580/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002581{
2582 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002583
Larry Hastings31826802013-10-19 00:09:25 -07002584 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002585 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002586 posix_error();
2587 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002588}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002589#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002590
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002591#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002592/*[clinic input]
2593os.ctermid
2594
2595Return the name of the controlling terminal for this process.
2596[clinic start generated code]*/
2597
Larry Hastings2f936352014-08-05 14:04:04 +10002598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002599os_ctermid_impl(PyObject *module)
2600/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002601{
Victor Stinner8c62be82010-05-06 00:08:46 +00002602 char *ret;
2603 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002604
Greg Wardb48bc172000-03-01 21:51:56 +00002605#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002606 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002607#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002608 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002609#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002610 if (ret == NULL)
2611 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002612 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002613}
Larry Hastings2f936352014-08-05 14:04:04 +10002614#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002615
Larry Hastings2f936352014-08-05 14:04:04 +10002616
2617/*[clinic input]
2618os.chdir
2619
2620 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2621
2622Change the current working directory to the specified path.
2623
2624path may always be specified as a string.
2625On some platforms, path may also be specified as an open file descriptor.
2626 If this functionality is unavailable, using it raises an exception.
2627[clinic start generated code]*/
2628
Larry Hastings2f936352014-08-05 14:04:04 +10002629static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002630os_chdir_impl(PyObject *module, path_t *path)
2631/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002632{
2633 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634
2635 Py_BEGIN_ALLOW_THREADS
2636#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002637 /* on unix, success = 0, on windows, success = !0 */
2638 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002639#else
2640#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002641 if (path->fd != -1)
2642 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643 else
2644#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002645 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646#endif
2647 Py_END_ALLOW_THREADS
2648
2649 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002650 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002651 }
2652
Larry Hastings2f936352014-08-05 14:04:04 +10002653 Py_RETURN_NONE;
2654}
2655
2656
2657#ifdef HAVE_FCHDIR
2658/*[clinic input]
2659os.fchdir
2660
2661 fd: fildes
2662
2663Change to the directory of the given file descriptor.
2664
2665fd must be opened on a directory, not a file.
2666Equivalent to os.chdir(fd).
2667
2668[clinic start generated code]*/
2669
Fred Drake4d1e64b2002-04-15 19:40:07 +00002670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002671os_fchdir_impl(PyObject *module, int fd)
2672/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002673{
Larry Hastings2f936352014-08-05 14:04:04 +10002674 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002675}
2676#endif /* HAVE_FCHDIR */
2677
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002678
Larry Hastings2f936352014-08-05 14:04:04 +10002679/*[clinic input]
2680os.chmod
2681
2682 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2683 Path to be modified. May always be specified as a str or bytes.
2684 On some platforms, path may also be specified as an open file descriptor.
2685 If this functionality is unavailable, using it raises an exception.
2686
2687 mode: int
2688 Operating-system mode bitfield.
2689
2690 *
2691
2692 dir_fd : dir_fd(requires='fchmodat') = None
2693 If not None, it should be a file descriptor open to a directory,
2694 and path should be relative; path will then be relative to that
2695 directory.
2696
2697 follow_symlinks: bool = True
2698 If False, and the last element of the path is a symbolic link,
2699 chmod will modify the symbolic link itself instead of the file
2700 the link points to.
2701
2702Change the access permissions of a file.
2703
2704It is an error to use dir_fd or follow_symlinks when specifying path as
2705 an open file descriptor.
2706dir_fd and follow_symlinks may not be implemented on your platform.
2707 If they are unavailable, using them will raise a NotImplementedError.
2708
2709[clinic start generated code]*/
2710
Larry Hastings2f936352014-08-05 14:04:04 +10002711static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002712os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002713 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002714/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002715{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002718#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002719 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002720#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002721
Larry Hastings9cf065c2012-06-22 16:30:09 -07002722#ifdef HAVE_FCHMODAT
2723 int fchmodat_nofollow_unsupported = 0;
2724#endif
2725
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2727 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002728 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729#endif
2730
2731#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002732 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002733 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002734 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735 result = 0;
2736 else {
2737 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002738 attr &= ~FILE_ATTRIBUTE_READONLY;
2739 else
2740 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002741 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002742 }
2743 Py_END_ALLOW_THREADS
2744
2745 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002746 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002747 }
2748#else /* MS_WINDOWS */
2749 Py_BEGIN_ALLOW_THREADS
2750#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002751 if (path->fd != -1)
2752 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753 else
2754#endif
2755#ifdef HAVE_LCHMOD
2756 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002757 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002758 else
2759#endif
2760#ifdef HAVE_FCHMODAT
2761 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2762 /*
2763 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2764 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002765 * and then says it isn't implemented yet.
2766 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002767 *
2768 * Once it is supported, os.chmod will automatically
2769 * support dir_fd and follow_symlinks=False. (Hopefully.)
2770 * Until then, we need to be careful what exception we raise.
2771 */
Larry Hastings2f936352014-08-05 14:04:04 +10002772 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002773 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2774 /*
2775 * But wait! We can't throw the exception without allowing threads,
2776 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2777 */
2778 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002779 result &&
2780 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2781 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002782 }
2783 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002784#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002785 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786 Py_END_ALLOW_THREADS
2787
2788 if (result) {
2789#ifdef HAVE_FCHMODAT
2790 if (fchmodat_nofollow_unsupported) {
2791 if (dir_fd != DEFAULT_DIR_FD)
2792 dir_fd_and_follow_symlinks_invalid("chmod",
2793 dir_fd, follow_symlinks);
2794 else
2795 follow_symlinks_specified("chmod", follow_symlinks);
2796 }
2797 else
2798#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002799 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800 }
2801#endif
2802
Larry Hastings2f936352014-08-05 14:04:04 +10002803 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002804}
2805
Larry Hastings9cf065c2012-06-22 16:30:09 -07002806
Christian Heimes4e30a842007-11-30 22:12:06 +00002807#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002808/*[clinic input]
2809os.fchmod
2810
2811 fd: int
2812 mode: int
2813
2814Change the access permissions of the file given by file descriptor fd.
2815
2816Equivalent to os.chmod(fd, mode).
2817[clinic start generated code]*/
2818
Larry Hastings2f936352014-08-05 14:04:04 +10002819static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002820os_fchmod_impl(PyObject *module, int fd, int mode)
2821/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002822{
2823 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002824 int async_err = 0;
2825
2826 do {
2827 Py_BEGIN_ALLOW_THREADS
2828 res = fchmod(fd, mode);
2829 Py_END_ALLOW_THREADS
2830 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2831 if (res != 0)
2832 return (!async_err) ? posix_error() : NULL;
2833
Victor Stinner8c62be82010-05-06 00:08:46 +00002834 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002835}
2836#endif /* HAVE_FCHMOD */
2837
Larry Hastings2f936352014-08-05 14:04:04 +10002838
Christian Heimes4e30a842007-11-30 22:12:06 +00002839#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002840/*[clinic input]
2841os.lchmod
2842
2843 path: path_t
2844 mode: int
2845
2846Change the access permissions of a file, without following symbolic links.
2847
2848If path is a symlink, this affects the link itself rather than the target.
2849Equivalent to chmod(path, mode, follow_symlinks=False)."
2850[clinic start generated code]*/
2851
Larry Hastings2f936352014-08-05 14:04:04 +10002852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002853os_lchmod_impl(PyObject *module, path_t *path, int mode)
2854/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002855{
Victor Stinner8c62be82010-05-06 00:08:46 +00002856 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002858 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002860 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002861 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002862 return NULL;
2863 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002864 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002865}
2866#endif /* HAVE_LCHMOD */
2867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002868
Thomas Wouterscf297e42007-02-23 15:07:44 +00002869#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002870/*[clinic input]
2871os.chflags
2872
2873 path: path_t
2874 flags: unsigned_long(bitwise=True)
2875 follow_symlinks: bool=True
2876
2877Set file flags.
2878
2879If follow_symlinks is False, and the last element of the path is a symbolic
2880 link, chflags will change flags on the symbolic link itself instead of the
2881 file the link points to.
2882follow_symlinks may not be implemented on your platform. If it is
2883unavailable, using it will raise a NotImplementedError.
2884
2885[clinic start generated code]*/
2886
Larry Hastings2f936352014-08-05 14:04:04 +10002887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002888os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002889 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002890/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002891{
2892 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893
2894#ifndef HAVE_LCHFLAGS
2895 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002896 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897#endif
2898
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900#ifdef HAVE_LCHFLAGS
2901 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002902 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002903 else
2904#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002905 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002907
Larry Hastings2f936352014-08-05 14:04:04 +10002908 if (result)
2909 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910
Larry Hastings2f936352014-08-05 14:04:04 +10002911 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002912}
2913#endif /* HAVE_CHFLAGS */
2914
Larry Hastings2f936352014-08-05 14:04:04 +10002915
Thomas Wouterscf297e42007-02-23 15:07:44 +00002916#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002917/*[clinic input]
2918os.lchflags
2919
2920 path: path_t
2921 flags: unsigned_long(bitwise=True)
2922
2923Set file flags.
2924
2925This function will not follow symbolic links.
2926Equivalent to chflags(path, flags, follow_symlinks=False).
2927[clinic start generated code]*/
2928
Larry Hastings2f936352014-08-05 14:04:04 +10002929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002930os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2931/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002932{
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002935 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002937 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002938 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002939 }
Victor Stinner292c8352012-10-30 02:17:38 +01002940 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002941}
2942#endif /* HAVE_LCHFLAGS */
2943
Larry Hastings2f936352014-08-05 14:04:04 +10002944
Martin v. Löwis244edc82001-10-04 22:44:26 +00002945#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002946/*[clinic input]
2947os.chroot
2948 path: path_t
2949
2950Change root directory to path.
2951
2952[clinic start generated code]*/
2953
Larry Hastings2f936352014-08-05 14:04:04 +10002954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002955os_chroot_impl(PyObject *module, path_t *path)
2956/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002957{
2958 int res;
2959 Py_BEGIN_ALLOW_THREADS
2960 res = chroot(path->narrow);
2961 Py_END_ALLOW_THREADS
2962 if (res < 0)
2963 return path_error(path);
2964 Py_RETURN_NONE;
2965}
2966#endif /* HAVE_CHROOT */
2967
Martin v. Löwis244edc82001-10-04 22:44:26 +00002968
Guido van Rossum21142a01999-01-08 21:05:37 +00002969#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002970/*[clinic input]
2971os.fsync
2972
2973 fd: fildes
2974
2975Force write of fd to disk.
2976[clinic start generated code]*/
2977
Larry Hastings2f936352014-08-05 14:04:04 +10002978static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002979os_fsync_impl(PyObject *module, int fd)
2980/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002981{
2982 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002983}
2984#endif /* HAVE_FSYNC */
2985
Larry Hastings2f936352014-08-05 14:04:04 +10002986
Ross Lagerwall7807c352011-03-17 20:20:30 +02002987#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002988/*[clinic input]
2989os.sync
2990
2991Force write of everything to disk.
2992[clinic start generated code]*/
2993
Larry Hastings2f936352014-08-05 14:04:04 +10002994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002995os_sync_impl(PyObject *module)
2996/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002997{
2998 Py_BEGIN_ALLOW_THREADS
2999 sync();
3000 Py_END_ALLOW_THREADS
3001 Py_RETURN_NONE;
3002}
Larry Hastings2f936352014-08-05 14:04:04 +10003003#endif /* HAVE_SYNC */
3004
Ross Lagerwall7807c352011-03-17 20:20:30 +02003005
Guido van Rossum21142a01999-01-08 21:05:37 +00003006#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003007#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003008extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3009#endif
3010
Larry Hastings2f936352014-08-05 14:04:04 +10003011/*[clinic input]
3012os.fdatasync
3013
3014 fd: fildes
3015
3016Force write of fd to disk without forcing update of metadata.
3017[clinic start generated code]*/
3018
Larry Hastings2f936352014-08-05 14:04:04 +10003019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003020os_fdatasync_impl(PyObject *module, int fd)
3021/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003022{
3023 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003024}
3025#endif /* HAVE_FDATASYNC */
3026
3027
Fredrik Lundh10723342000-07-10 16:38:09 +00003028#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003029/*[clinic input]
3030os.chown
3031
3032 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3033 Path to be examined; can be string, bytes, or open-file-descriptor int.
3034
3035 uid: uid_t
3036
3037 gid: gid_t
3038
3039 *
3040
3041 dir_fd : dir_fd(requires='fchownat') = None
3042 If not None, it should be a file descriptor open to a directory,
3043 and path should be relative; path will then be relative to that
3044 directory.
3045
3046 follow_symlinks: bool = True
3047 If False, and the last element of the path is a symbolic link,
3048 stat will examine the symbolic link itself instead of the file
3049 the link points to.
3050
3051Change the owner and group id of path to the numeric uid and gid.\
3052
3053path may always be specified as a string.
3054On some platforms, path may also be specified as an open file descriptor.
3055 If this functionality is unavailable, using it raises an exception.
3056If dir_fd is not None, it should be a file descriptor open to a directory,
3057 and path should be relative; path will then be relative to that directory.
3058If follow_symlinks is False, and the last element of the path is a symbolic
3059 link, chown will modify the symbolic link itself instead of the file the
3060 link points to.
3061It is an error to use dir_fd or follow_symlinks when specifying path as
3062 an open file descriptor.
3063dir_fd and follow_symlinks may not be implemented on your platform.
3064 If they are unavailable, using them will raise a NotImplementedError.
3065
3066[clinic start generated code]*/
3067
Larry Hastings2f936352014-08-05 14:04:04 +10003068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003069os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003070 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003071/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003072{
3073 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003074
3075#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3076 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003077 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003078#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003079 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3080 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3081 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003082
3083#ifdef __APPLE__
3084 /*
3085 * This is for Mac OS X 10.3, which doesn't have lchown.
3086 * (But we still have an lchown symbol because of weak-linking.)
3087 * It doesn't have fchownat either. So there's no possibility
3088 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003089 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090 if ((!follow_symlinks) && (lchown == NULL)) {
3091 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003092 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003093 }
3094#endif
3095
Victor Stinner8c62be82010-05-06 00:08:46 +00003096 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003098 if (path->fd != -1)
3099 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003100 else
3101#endif
3102#ifdef HAVE_LCHOWN
3103 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003104 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105 else
3106#endif
3107#ifdef HAVE_FCHOWNAT
3108 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003109 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3111 else
3112#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003113 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003114 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003115
Larry Hastings2f936352014-08-05 14:04:04 +10003116 if (result)
3117 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003118
Larry Hastings2f936352014-08-05 14:04:04 +10003119 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003120}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003121#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003122
Larry Hastings2f936352014-08-05 14:04:04 +10003123
Christian Heimes4e30a842007-11-30 22:12:06 +00003124#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003125/*[clinic input]
3126os.fchown
3127
3128 fd: int
3129 uid: uid_t
3130 gid: gid_t
3131
3132Change the owner and group id of the file specified by file descriptor.
3133
3134Equivalent to os.chown(fd, uid, gid).
3135
3136[clinic start generated code]*/
3137
Larry Hastings2f936352014-08-05 14:04:04 +10003138static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003139os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3140/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003141{
Victor Stinner8c62be82010-05-06 00:08:46 +00003142 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003143 int async_err = 0;
3144
3145 do {
3146 Py_BEGIN_ALLOW_THREADS
3147 res = fchown(fd, uid, gid);
3148 Py_END_ALLOW_THREADS
3149 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3150 if (res != 0)
3151 return (!async_err) ? posix_error() : NULL;
3152
Victor Stinner8c62be82010-05-06 00:08:46 +00003153 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003154}
3155#endif /* HAVE_FCHOWN */
3156
Larry Hastings2f936352014-08-05 14:04:04 +10003157
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003158#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003159/*[clinic input]
3160os.lchown
3161
3162 path : path_t
3163 uid: uid_t
3164 gid: gid_t
3165
3166Change the owner and group id of path to the numeric uid and gid.
3167
3168This function will not follow symbolic links.
3169Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3170[clinic start generated code]*/
3171
Larry Hastings2f936352014-08-05 14:04:04 +10003172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003173os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3174/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003175{
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003178 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003179 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003180 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003181 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003182 }
Larry Hastings2f936352014-08-05 14:04:04 +10003183 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003184}
3185#endif /* HAVE_LCHOWN */
3186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003187
Barry Warsaw53699e91996-12-10 23:23:01 +00003188static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003189posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003190{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003191 char *buf, *tmpbuf;
3192 char *cwd;
3193 const size_t chunk = 1024;
3194 size_t buflen = 0;
3195 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003196
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003197#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003199 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003200 wchar_t *wbuf2 = wbuf;
3201 PyObject *resobj;
3202 DWORD len;
3203 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003204 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 /* If the buffer is large enough, len does not include the
3206 terminating \0. If the buffer is too small, len includes
3207 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003208 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003209 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003210 if (wbuf2)
3211 len = GetCurrentDirectoryW(len, wbuf2);
3212 }
3213 Py_END_ALLOW_THREADS
3214 if (!wbuf2) {
3215 PyErr_NoMemory();
3216 return NULL;
3217 }
3218 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003219 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003220 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003221 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003222 }
3223 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003224 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003225 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 return resobj;
3227 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003228
3229 if (win32_warn_bytes_api())
3230 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003231#endif
3232
Victor Stinner4403d7d2015-04-25 00:16:10 +02003233 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003235 do {
3236 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003237#ifdef MS_WINDOWS
3238 if (buflen > INT_MAX) {
3239 PyErr_NoMemory();
3240 break;
3241 }
3242#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003243 tmpbuf = PyMem_RawRealloc(buf, buflen);
3244 if (tmpbuf == NULL)
3245 break;
3246
3247 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003248#ifdef MS_WINDOWS
3249 cwd = getcwd(buf, (int)buflen);
3250#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003251 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003252#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003253 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003255
3256 if (cwd == NULL) {
3257 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003259 }
3260
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003262 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3263 else
3264 obj = PyUnicode_DecodeFSDefault(buf);
3265 PyMem_RawFree(buf);
3266
3267 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003268}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003269
Larry Hastings2f936352014-08-05 14:04:04 +10003270
3271/*[clinic input]
3272os.getcwd
3273
3274Return a unicode string representing the current working directory.
3275[clinic start generated code]*/
3276
Larry Hastings2f936352014-08-05 14:04:04 +10003277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003278os_getcwd_impl(PyObject *module)
3279/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003280{
3281 return posix_getcwd(0);
3282}
3283
Larry Hastings2f936352014-08-05 14:04:04 +10003284
3285/*[clinic input]
3286os.getcwdb
3287
3288Return a bytes string representing the current working directory.
3289[clinic start generated code]*/
3290
Larry Hastings2f936352014-08-05 14:04:04 +10003291static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003292os_getcwdb_impl(PyObject *module)
3293/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003294{
3295 return posix_getcwd(1);
3296}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003297
Larry Hastings2f936352014-08-05 14:04:04 +10003298
Larry Hastings9cf065c2012-06-22 16:30:09 -07003299#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3300#define HAVE_LINK 1
3301#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003302
Guido van Rossumb6775db1994-08-01 11:34:53 +00003303#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003304/*[clinic input]
3305
3306os.link
3307
3308 src : path_t
3309 dst : path_t
3310 *
3311 src_dir_fd : dir_fd = None
3312 dst_dir_fd : dir_fd = None
3313 follow_symlinks: bool = True
3314
3315Create a hard link to a file.
3316
3317If either src_dir_fd or dst_dir_fd is not None, it should be a file
3318 descriptor open to a directory, and the respective path string (src or dst)
3319 should be relative; the path will then be relative to that directory.
3320If follow_symlinks is False, and the last element of src is a symbolic
3321 link, link will create a link to the symbolic link itself instead of the
3322 file the link points to.
3323src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3324 platform. If they are unavailable, using them will raise a
3325 NotImplementedError.
3326[clinic start generated code]*/
3327
Larry Hastings2f936352014-08-05 14:04:04 +10003328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003329os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003330 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003331/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003332{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003334 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003335#else
3336 int result;
3337#endif
3338
Larry Hastings9cf065c2012-06-22 16:30:09 -07003339#ifndef HAVE_LINKAT
3340 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3341 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003342 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003343 }
3344#endif
3345
Steve Dowercc16be82016-09-08 10:35:16 -07003346#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003347 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348 PyErr_SetString(PyExc_NotImplementedError,
3349 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003350 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003351 }
Steve Dowercc16be82016-09-08 10:35:16 -07003352#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003353
Brian Curtin1b9df392010-11-24 20:24:31 +00003354#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003355 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003356 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003358
Larry Hastings2f936352014-08-05 14:04:04 +10003359 if (!result)
3360 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003361#else
3362 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003363#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3365 (dst_dir_fd != DEFAULT_DIR_FD) ||
3366 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003367 result = linkat(src_dir_fd, src->narrow,
3368 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003369 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3370 else
Steve Dowercc16be82016-09-08 10:35:16 -07003371#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003372 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003374
Larry Hastings2f936352014-08-05 14:04:04 +10003375 if (result)
3376 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003377#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378
Larry Hastings2f936352014-08-05 14:04:04 +10003379 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003380}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381#endif
3382
Brian Curtin1b9df392010-11-24 20:24:31 +00003383
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003384#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003385static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003386_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003387{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 PyObject *v;
3389 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3390 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003391 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003393 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395
Steve Dowercc16be82016-09-08 10:35:16 -07003396 WIN32_FIND_DATAW wFileData;
3397 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003398
Steve Dowercc16be82016-09-08 10:35:16 -07003399 if (!path->wide) { /* Default arg: "." */
3400 po_wchars = L".";
3401 len = 1;
3402 } else {
3403 po_wchars = path->wide;
3404 len = wcslen(path->wide);
3405 }
3406 /* The +5 is so we can append "\\*.*\0" */
3407 wnamebuf = PyMem_New(wchar_t, len + 5);
3408 if (!wnamebuf) {
3409 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 }
Steve Dowercc16be82016-09-08 10:35:16 -07003412 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003413 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003414 wchar_t wch = wnamebuf[len-1];
3415 if (wch != SEP && wch != ALTSEP && wch != L':')
3416 wnamebuf[len++] = SEP;
3417 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 }
Steve Dowercc16be82016-09-08 10:35:16 -07003419 if ((list = PyList_New(0)) == NULL) {
3420 goto exit;
3421 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003422 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003423 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003424 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 if (hFindFile == INVALID_HANDLE_VALUE) {
3426 int error = GetLastError();
3427 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 goto exit;
3429 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003430 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 }
3433 do {
3434 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003435 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3436 wcscmp(wFileData.cFileName, L"..") != 0) {
3437 v = PyUnicode_FromWideChar(wFileData.cFileName,
3438 wcslen(wFileData.cFileName));
3439 if (path->narrow && v) {
3440 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3441 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 Py_DECREF(list);
3444 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 break;
3446 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449 Py_DECREF(list);
3450 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 break;
3452 }
3453 Py_DECREF(v);
3454 }
3455 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003456 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 Py_END_ALLOW_THREADS
3458 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3459 it got to the end of the directory. */
3460 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003462 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 }
3465 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003466
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467exit:
3468 if (hFindFile != INVALID_HANDLE_VALUE) {
3469 if (FindClose(hFindFile) == FALSE) {
3470 if (list != NULL) {
3471 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003472 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473 }
3474 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003476 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003477
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003479} /* end of _listdir_windows_no_opendir */
3480
3481#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3482
3483static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003484_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003485{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003486 PyObject *v;
3487 DIR *dirp = NULL;
3488 struct dirent *ep;
3489 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003490#ifdef HAVE_FDOPENDIR
3491 int fd = -1;
3492#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003493
Victor Stinner8c62be82010-05-06 00:08:46 +00003494 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003496 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003498 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003499 if (fd == -1)
3500 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501
Larry Hastingsfdaea062012-06-25 04:42:23 -07003502 return_str = 1;
3503
Larry Hastings9cf065c2012-06-22 16:30:09 -07003504 Py_BEGIN_ALLOW_THREADS
3505 dirp = fdopendir(fd);
3506 Py_END_ALLOW_THREADS
3507 }
3508 else
3509#endif
3510 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003511 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003512 if (path->narrow) {
3513 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003514 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003515 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003516 }
3517 else {
3518 name = ".";
3519 return_str = 1;
3520 }
3521
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 Py_BEGIN_ALLOW_THREADS
3523 dirp = opendir(name);
3524 Py_END_ALLOW_THREADS
3525 }
3526
3527 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003528 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003529#ifdef HAVE_FDOPENDIR
3530 if (fd != -1) {
3531 Py_BEGIN_ALLOW_THREADS
3532 close(fd);
3533 Py_END_ALLOW_THREADS
3534 }
3535#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 goto exit;
3537 }
3538 if ((list = PyList_New(0)) == NULL) {
3539 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 }
3541 for (;;) {
3542 errno = 0;
3543 Py_BEGIN_ALLOW_THREADS
3544 ep = readdir(dirp);
3545 Py_END_ALLOW_THREADS
3546 if (ep == NULL) {
3547 if (errno == 0) {
3548 break;
3549 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003551 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 }
3554 }
3555 if (ep->d_name[0] == '.' &&
3556 (NAMLEN(ep) == 1 ||
3557 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3558 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003559 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003560 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3561 else
3562 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 break;
3566 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 break;
3571 }
3572 Py_DECREF(v);
3573 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003574
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575exit:
3576 if (dirp != NULL) {
3577 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003578#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 if (fd > -1)
3580 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003581#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003582 closedir(dirp);
3583 Py_END_ALLOW_THREADS
3584 }
3585
Larry Hastings9cf065c2012-06-22 16:30:09 -07003586 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003587} /* end of _posix_listdir */
3588#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003589
Larry Hastings2f936352014-08-05 14:04:04 +10003590
3591/*[clinic input]
3592os.listdir
3593
3594 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3595
3596Return a list containing the names of the files in the directory.
3597
3598path can be specified as either str or bytes. If path is bytes,
3599 the filenames returned will also be bytes; in all other circumstances
3600 the filenames returned will be str.
3601If path is None, uses the path='.'.
3602On some platforms, path may also be specified as an open file descriptor;\
3603 the file descriptor must refer to a directory.
3604 If this functionality is unavailable, using it raises NotImplementedError.
3605
3606The list is in arbitrary order. It does not include the special
3607entries '.' and '..' even if they are present in the directory.
3608
3609
3610[clinic start generated code]*/
3611
Larry Hastings2f936352014-08-05 14:04:04 +10003612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003613os_listdir_impl(PyObject *module, path_t *path)
3614/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003615{
3616#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3617 return _listdir_windows_no_opendir(path, NULL);
3618#else
3619 return _posix_listdir(path, NULL);
3620#endif
3621}
3622
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003623#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003624/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003625/*[clinic input]
3626os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003627
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003628 path: path_t
3629 /
3630
3631[clinic start generated code]*/
3632
3633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003634os__getfullpathname_impl(PyObject *module, path_t *path)
3635/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003636{
Steve Dowercc16be82016-09-08 10:35:16 -07003637 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3638 wchar_t *wtemp;
3639 DWORD result;
3640 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003641
Steve Dowercc16be82016-09-08 10:35:16 -07003642 result = GetFullPathNameW(path->wide,
3643 Py_ARRAY_LENGTH(woutbuf),
3644 woutbuf, &wtemp);
3645 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3646 woutbufp = PyMem_New(wchar_t, result);
3647 if (!woutbufp)
3648 return PyErr_NoMemory();
3649 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003650 }
Steve Dowercc16be82016-09-08 10:35:16 -07003651 if (result) {
3652 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3653 if (path->narrow)
3654 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3655 } else
3656 v = win32_error_object("GetFullPathNameW", path->object);
3657 if (woutbufp != woutbuf)
3658 PyMem_Free(woutbufp);
3659 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003660}
Brian Curtind40e6f72010-07-08 21:39:08 +00003661
Brian Curtind25aef52011-06-13 15:16:04 -05003662
Larry Hastings2f936352014-08-05 14:04:04 +10003663/*[clinic input]
3664os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003665
Larry Hastings2f936352014-08-05 14:04:04 +10003666 path: unicode
3667 /
3668
3669A helper function for samepath on windows.
3670[clinic start generated code]*/
3671
Larry Hastings2f936352014-08-05 14:04:04 +10003672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003673os__getfinalpathname_impl(PyObject *module, PyObject *path)
3674/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003675{
3676 HANDLE hFile;
3677 int buf_size;
3678 wchar_t *target_path;
3679 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003680 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003681 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003682
Larry Hastings2f936352014-08-05 14:04:04 +10003683 path_wchar = PyUnicode_AsUnicode(path);
3684 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003685 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003686
Brian Curtind40e6f72010-07-08 21:39:08 +00003687 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003688 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003689 0, /* desired access */
3690 0, /* share mode */
3691 NULL, /* security attributes */
3692 OPEN_EXISTING,
3693 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3694 FILE_FLAG_BACKUP_SEMANTICS,
3695 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003696
Victor Stinnereb5657a2011-09-30 01:44:27 +02003697 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003698 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003699
3700 /* We have a good handle to the target, use it to determine the
3701 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003702 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003703
3704 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003705 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003706
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003707 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003708 if(!target_path)
3709 return PyErr_NoMemory();
3710
Steve Dower2ea51c92015-03-20 21:49:12 -07003711 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3712 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003713 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003714 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003715
3716 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003717 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003718
3719 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003720 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003721 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003722 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003723}
Brian Curtin62857742010-09-06 17:07:27 +00003724
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003725/*[clinic input]
3726os._isdir
3727
3728 path: path_t
3729 /
3730
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003731Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003732[clinic start generated code]*/
3733
Brian Curtin9c669cc2011-06-08 18:17:18 -05003734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003735os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003736/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003737{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003738 DWORD attributes;
3739
Steve Dowerb22a6772016-07-17 20:49:38 -07003740 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003741 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003742 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003743
Brian Curtin9c669cc2011-06-08 18:17:18 -05003744 if (attributes == INVALID_FILE_ATTRIBUTES)
3745 Py_RETURN_FALSE;
3746
Brian Curtin9c669cc2011-06-08 18:17:18 -05003747 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3748 Py_RETURN_TRUE;
3749 else
3750 Py_RETURN_FALSE;
3751}
Tim Golden6b528062013-08-01 12:44:00 +01003752
Tim Golden6b528062013-08-01 12:44:00 +01003753
Larry Hastings2f936352014-08-05 14:04:04 +10003754/*[clinic input]
3755os._getvolumepathname
3756
3757 path: unicode
3758
3759A helper function for ismount on Win32.
3760[clinic start generated code]*/
3761
Larry Hastings2f936352014-08-05 14:04:04 +10003762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003763os__getvolumepathname_impl(PyObject *module, PyObject *path)
3764/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003765{
3766 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003767 const wchar_t *path_wchar;
3768 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003769 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003770 BOOL ret;
3771
Larry Hastings2f936352014-08-05 14:04:04 +10003772 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3773 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003774 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003775 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003776
3777 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003778 buflen = Py_MAX(buflen, MAX_PATH);
3779
3780 if (buflen > DWORD_MAX) {
3781 PyErr_SetString(PyExc_OverflowError, "path too long");
3782 return NULL;
3783 }
3784
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003785 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003786 if (mountpath == NULL)
3787 return PyErr_NoMemory();
3788
3789 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003790 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003791 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003792 Py_END_ALLOW_THREADS
3793
3794 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003795 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003796 goto exit;
3797 }
3798 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3799
3800exit:
3801 PyMem_Free(mountpath);
3802 return result;
3803}
Tim Golden6b528062013-08-01 12:44:00 +01003804
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003805#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003806
Larry Hastings2f936352014-08-05 14:04:04 +10003807
3808/*[clinic input]
3809os.mkdir
3810
3811 path : path_t
3812
3813 mode: int = 0o777
3814
3815 *
3816
3817 dir_fd : dir_fd(requires='mkdirat') = None
3818
3819# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3820
3821Create a directory.
3822
3823If dir_fd is not None, it should be a file descriptor open to a directory,
3824 and path should be relative; path will then be relative to that directory.
3825dir_fd may not be implemented on your platform.
3826 If it is unavailable, using it will raise a NotImplementedError.
3827
3828The mode argument is ignored on Windows.
3829[clinic start generated code]*/
3830
Larry Hastings2f936352014-08-05 14:04:04 +10003831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003832os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3833/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003834{
3835 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003836
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003837#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003839 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003841
Larry Hastings2f936352014-08-05 14:04:04 +10003842 if (!result)
3843 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003844#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003845 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003846#if HAVE_MKDIRAT
3847 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003848 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003849 else
3850#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003851#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003852 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003853#else
Larry Hastings2f936352014-08-05 14:04:04 +10003854 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003855#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003856 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003857 if (result < 0)
3858 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003859#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003860 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003861}
3862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003863
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003864/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3865#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003866#include <sys/resource.h>
3867#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003868
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003869
3870#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003871/*[clinic input]
3872os.nice
3873
3874 increment: int
3875 /
3876
3877Add increment to the priority of process and return the new priority.
3878[clinic start generated code]*/
3879
Larry Hastings2f936352014-08-05 14:04:04 +10003880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003881os_nice_impl(PyObject *module, int increment)
3882/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003883{
3884 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003885
Victor Stinner8c62be82010-05-06 00:08:46 +00003886 /* There are two flavours of 'nice': one that returns the new
3887 priority (as required by almost all standards out there) and the
3888 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3889 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003890
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 If we are of the nice family that returns the new priority, we
3892 need to clear errno before the call, and check if errno is filled
3893 before calling posix_error() on a returnvalue of -1, because the
3894 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003895
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 errno = 0;
3897 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003898#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003899 if (value == 0)
3900 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003901#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 if (value == -1 && errno != 0)
3903 /* either nice() or getpriority() returned an error */
3904 return posix_error();
3905 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003906}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003907#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003908
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003909
3910#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003911/*[clinic input]
3912os.getpriority
3913
3914 which: int
3915 who: int
3916
3917Return program scheduling priority.
3918[clinic start generated code]*/
3919
Larry Hastings2f936352014-08-05 14:04:04 +10003920static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003921os_getpriority_impl(PyObject *module, int which, int who)
3922/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003923{
3924 int retval;
3925
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003926 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003927 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003928 if (errno != 0)
3929 return posix_error();
3930 return PyLong_FromLong((long)retval);
3931}
3932#endif /* HAVE_GETPRIORITY */
3933
3934
3935#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003936/*[clinic input]
3937os.setpriority
3938
3939 which: int
3940 who: int
3941 priority: int
3942
3943Set program scheduling priority.
3944[clinic start generated code]*/
3945
Larry Hastings2f936352014-08-05 14:04:04 +10003946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003947os_setpriority_impl(PyObject *module, int which, int who, int priority)
3948/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003949{
3950 int retval;
3951
3952 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003953 if (retval == -1)
3954 return posix_error();
3955 Py_RETURN_NONE;
3956}
3957#endif /* HAVE_SETPRIORITY */
3958
3959
Barry Warsaw53699e91996-12-10 23:23:01 +00003960static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003961internal_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 +00003962{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003963 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003964 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003965
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003966#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003967 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003968 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003969#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003971#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972
Larry Hastings9cf065c2012-06-22 16:30:09 -07003973 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3974 (dst_dir_fd != DEFAULT_DIR_FD);
3975#ifndef HAVE_RENAMEAT
3976 if (dir_fd_specified) {
3977 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003978 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979 }
3980#endif
3981
Larry Hastings9cf065c2012-06-22 16:30:09 -07003982#ifdef MS_WINDOWS
3983 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003984 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003985 Py_END_ALLOW_THREADS
3986
Larry Hastings2f936352014-08-05 14:04:04 +10003987 if (!result)
3988 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989
3990#else
Steve Dowercc16be82016-09-08 10:35:16 -07003991 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3992 PyErr_Format(PyExc_ValueError,
3993 "%s: src and dst must be the same type", function_name);
3994 return NULL;
3995 }
3996
Larry Hastings9cf065c2012-06-22 16:30:09 -07003997 Py_BEGIN_ALLOW_THREADS
3998#ifdef HAVE_RENAMEAT
3999 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004000 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001 else
4002#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004003 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004004 Py_END_ALLOW_THREADS
4005
Larry Hastings2f936352014-08-05 14:04:04 +10004006 if (result)
4007 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004008#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004009 Py_RETURN_NONE;
4010}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004011
Larry Hastings2f936352014-08-05 14:04:04 +10004012
4013/*[clinic input]
4014os.rename
4015
4016 src : path_t
4017 dst : path_t
4018 *
4019 src_dir_fd : dir_fd = None
4020 dst_dir_fd : dir_fd = None
4021
4022Rename a file or directory.
4023
4024If either src_dir_fd or dst_dir_fd is not None, it should be a file
4025 descriptor open to a directory, and the respective path string (src or dst)
4026 should be relative; the path will then be relative to that directory.
4027src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4028 If they are unavailable, using them will raise a NotImplementedError.
4029[clinic start generated code]*/
4030
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004032os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004033 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004034/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004035{
Larry Hastings2f936352014-08-05 14:04:04 +10004036 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004037}
4038
Larry Hastings2f936352014-08-05 14:04:04 +10004039
4040/*[clinic input]
4041os.replace = os.rename
4042
4043Rename a file or directory, overwriting the destination.
4044
4045If either src_dir_fd or dst_dir_fd is not None, it should be a file
4046 descriptor open to a directory, and the respective path string (src or dst)
4047 should be relative; the path will then be relative to that directory.
4048src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4049 If they are unavailable, using them will raise a NotImplementedError."
4050[clinic start generated code]*/
4051
Larry Hastings2f936352014-08-05 14:04:04 +10004052static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004053os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4054 int dst_dir_fd)
4055/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004056{
4057 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4058}
4059
4060
4061/*[clinic input]
4062os.rmdir
4063
4064 path: path_t
4065 *
4066 dir_fd: dir_fd(requires='unlinkat') = None
4067
4068Remove a directory.
4069
4070If dir_fd is not None, it should be a file descriptor open to a directory,
4071 and path should be relative; path will then be relative to that directory.
4072dir_fd may not be implemented on your platform.
4073 If it is unavailable, using it will raise a NotImplementedError.
4074[clinic start generated code]*/
4075
Larry Hastings2f936352014-08-05 14:04:04 +10004076static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004077os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4078/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004079{
4080 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004081
4082 Py_BEGIN_ALLOW_THREADS
4083#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004084 /* Windows, success=1, UNIX, success=0 */
4085 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004086#else
4087#ifdef HAVE_UNLINKAT
4088 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004089 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004090 else
4091#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004092 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004093#endif
4094 Py_END_ALLOW_THREADS
4095
Larry Hastings2f936352014-08-05 14:04:04 +10004096 if (result)
4097 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004098
Larry Hastings2f936352014-08-05 14:04:04 +10004099 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004100}
4101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004102
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004103#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004104#ifdef MS_WINDOWS
4105/*[clinic input]
4106os.system -> long
4107
4108 command: Py_UNICODE
4109
4110Execute the command in a subshell.
4111[clinic start generated code]*/
4112
Larry Hastings2f936352014-08-05 14:04:04 +10004113static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004114os_system_impl(PyObject *module, Py_UNICODE *command)
4115/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004116{
4117 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004118 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004119 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004120 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004121 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004122 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004123 return result;
4124}
4125#else /* MS_WINDOWS */
4126/*[clinic input]
4127os.system -> long
4128
4129 command: FSConverter
4130
4131Execute the command in a subshell.
4132[clinic start generated code]*/
4133
Larry Hastings2f936352014-08-05 14:04:04 +10004134static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004135os_system_impl(PyObject *module, PyObject *command)
4136/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004137{
4138 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004139 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004140 Py_BEGIN_ALLOW_THREADS
4141 result = system(bytes);
4142 Py_END_ALLOW_THREADS
4143 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004144}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004145#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004146#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004148
Larry Hastings2f936352014-08-05 14:04:04 +10004149/*[clinic input]
4150os.umask
4151
4152 mask: int
4153 /
4154
4155Set the current numeric umask and return the previous umask.
4156[clinic start generated code]*/
4157
Larry Hastings2f936352014-08-05 14:04:04 +10004158static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004159os_umask_impl(PyObject *module, int mask)
4160/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004161{
4162 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004163 if (i < 0)
4164 return posix_error();
4165 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004166}
4167
Brian Curtind40e6f72010-07-08 21:39:08 +00004168#ifdef MS_WINDOWS
4169
4170/* override the default DeleteFileW behavior so that directory
4171symlinks can be removed with this function, the same as with
4172Unix symlinks */
4173BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4174{
4175 WIN32_FILE_ATTRIBUTE_DATA info;
4176 WIN32_FIND_DATAW find_data;
4177 HANDLE find_data_handle;
4178 int is_directory = 0;
4179 int is_link = 0;
4180
4181 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4182 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004183
Brian Curtind40e6f72010-07-08 21:39:08 +00004184 /* Get WIN32_FIND_DATA structure for the path to determine if
4185 it is a symlink */
4186 if(is_directory &&
4187 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4188 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4189
4190 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004191 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4192 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4193 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4194 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004195 FindClose(find_data_handle);
4196 }
4197 }
4198 }
4199
4200 if (is_directory && is_link)
4201 return RemoveDirectoryW(lpFileName);
4202
4203 return DeleteFileW(lpFileName);
4204}
4205#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004207
Larry Hastings2f936352014-08-05 14:04:04 +10004208/*[clinic input]
4209os.unlink
4210
4211 path: path_t
4212 *
4213 dir_fd: dir_fd(requires='unlinkat')=None
4214
4215Remove a file (same as remove()).
4216
4217If dir_fd is not None, it should be a file descriptor open to a directory,
4218 and path should be relative; path will then be relative to that directory.
4219dir_fd may not be implemented on your platform.
4220 If it is unavailable, using it will raise a NotImplementedError.
4221
4222[clinic start generated code]*/
4223
Larry Hastings2f936352014-08-05 14:04:04 +10004224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004225os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4226/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004227{
4228 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004229
4230 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004231 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004232#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004233 /* Windows, success=1, UNIX, success=0 */
4234 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004235#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004236#ifdef HAVE_UNLINKAT
4237 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004239 else
4240#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004241 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004242#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004243 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244 Py_END_ALLOW_THREADS
4245
Larry Hastings2f936352014-08-05 14:04:04 +10004246 if (result)
4247 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004248
Larry Hastings2f936352014-08-05 14:04:04 +10004249 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004250}
4251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004252
Larry Hastings2f936352014-08-05 14:04:04 +10004253/*[clinic input]
4254os.remove = os.unlink
4255
4256Remove a file (same as unlink()).
4257
4258If dir_fd is not None, it should be a file descriptor open to a directory,
4259 and path should be relative; path will then be relative to that directory.
4260dir_fd may not be implemented on your platform.
4261 If it is unavailable, using it will raise a NotImplementedError.
4262[clinic start generated code]*/
4263
Larry Hastings2f936352014-08-05 14:04:04 +10004264static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004265os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4266/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004267{
4268 return os_unlink_impl(module, path, dir_fd);
4269}
4270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004271
Larry Hastings605a62d2012-06-24 04:33:36 -07004272static PyStructSequence_Field uname_result_fields[] = {
4273 {"sysname", "operating system name"},
4274 {"nodename", "name of machine on network (implementation-defined)"},
4275 {"release", "operating system release"},
4276 {"version", "operating system version"},
4277 {"machine", "hardware identifier"},
4278 {NULL}
4279};
4280
4281PyDoc_STRVAR(uname_result__doc__,
4282"uname_result: Result from os.uname().\n\n\
4283This object may be accessed either as a tuple of\n\
4284 (sysname, nodename, release, version, machine),\n\
4285or via the attributes sysname, nodename, release, version, and machine.\n\
4286\n\
4287See os.uname for more information.");
4288
4289static PyStructSequence_Desc uname_result_desc = {
4290 "uname_result", /* name */
4291 uname_result__doc__, /* doc */
4292 uname_result_fields,
4293 5
4294};
4295
4296static PyTypeObject UnameResultType;
4297
4298
4299#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004300/*[clinic input]
4301os.uname
4302
4303Return an object identifying the current operating system.
4304
4305The object behaves like a named tuple with the following fields:
4306 (sysname, nodename, release, version, machine)
4307
4308[clinic start generated code]*/
4309
Larry Hastings2f936352014-08-05 14:04:04 +10004310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004311os_uname_impl(PyObject *module)
4312/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004313{
Victor Stinner8c62be82010-05-06 00:08:46 +00004314 struct utsname u;
4315 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004316 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004317
Victor Stinner8c62be82010-05-06 00:08:46 +00004318 Py_BEGIN_ALLOW_THREADS
4319 res = uname(&u);
4320 Py_END_ALLOW_THREADS
4321 if (res < 0)
4322 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004323
4324 value = PyStructSequence_New(&UnameResultType);
4325 if (value == NULL)
4326 return NULL;
4327
4328#define SET(i, field) \
4329 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004330 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004331 if (!o) { \
4332 Py_DECREF(value); \
4333 return NULL; \
4334 } \
4335 PyStructSequence_SET_ITEM(value, i, o); \
4336 } \
4337
4338 SET(0, u.sysname);
4339 SET(1, u.nodename);
4340 SET(2, u.release);
4341 SET(3, u.version);
4342 SET(4, u.machine);
4343
4344#undef SET
4345
4346 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004347}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004348#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004349
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004350
Larry Hastings9cf065c2012-06-22 16:30:09 -07004351
4352typedef struct {
4353 int now;
4354 time_t atime_s;
4355 long atime_ns;
4356 time_t mtime_s;
4357 long mtime_ns;
4358} utime_t;
4359
4360/*
Victor Stinner484df002014-10-09 13:52:31 +02004361 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004362 * they also intentionally leak the declaration of a pointer named "time"
4363 */
4364#define UTIME_TO_TIMESPEC \
4365 struct timespec ts[2]; \
4366 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004367 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368 time = NULL; \
4369 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004370 ts[0].tv_sec = ut->atime_s; \
4371 ts[0].tv_nsec = ut->atime_ns; \
4372 ts[1].tv_sec = ut->mtime_s; \
4373 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374 time = ts; \
4375 } \
4376
4377#define UTIME_TO_TIMEVAL \
4378 struct timeval tv[2]; \
4379 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004380 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004381 time = NULL; \
4382 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004383 tv[0].tv_sec = ut->atime_s; \
4384 tv[0].tv_usec = ut->atime_ns / 1000; \
4385 tv[1].tv_sec = ut->mtime_s; \
4386 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004387 time = tv; \
4388 } \
4389
4390#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004391 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004393 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394 time = NULL; \
4395 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004396 u.actime = ut->atime_s; \
4397 u.modtime = ut->mtime_s; \
4398 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399 }
4400
4401#define UTIME_TO_TIME_T \
4402 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004403 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004404 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004405 time = NULL; \
4406 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004407 timet[0] = ut->atime_s; \
4408 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004409 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004410 } \
4411
4412
Victor Stinner528a9ab2015-09-03 21:30:26 +02004413#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004414
4415static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004416utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004417{
4418#ifdef HAVE_UTIMENSAT
4419 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4420 UTIME_TO_TIMESPEC;
4421 return utimensat(dir_fd, path, time, flags);
4422#elif defined(HAVE_FUTIMESAT)
4423 UTIME_TO_TIMEVAL;
4424 /*
4425 * follow_symlinks will never be false here;
4426 * we only allow !follow_symlinks and dir_fd together
4427 * if we have utimensat()
4428 */
4429 assert(follow_symlinks);
4430 return futimesat(dir_fd, path, time);
4431#endif
4432}
4433
Larry Hastings2f936352014-08-05 14:04:04 +10004434 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4435#else
4436 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004437#endif
4438
Victor Stinner528a9ab2015-09-03 21:30:26 +02004439#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004440
4441static int
Victor Stinner484df002014-10-09 13:52:31 +02004442utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004443{
4444#ifdef HAVE_FUTIMENS
4445 UTIME_TO_TIMESPEC;
4446 return futimens(fd, time);
4447#else
4448 UTIME_TO_TIMEVAL;
4449 return futimes(fd, time);
4450#endif
4451}
4452
Larry Hastings2f936352014-08-05 14:04:04 +10004453 #define PATH_UTIME_HAVE_FD 1
4454#else
4455 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456#endif
4457
Victor Stinner5ebae872015-09-22 01:29:33 +02004458#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4459# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4460#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004461
Victor Stinner4552ced2015-09-21 22:37:15 +02004462#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463
4464static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004465utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004466{
4467#ifdef HAVE_UTIMENSAT
4468 UTIME_TO_TIMESPEC;
4469 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4470#else
4471 UTIME_TO_TIMEVAL;
4472 return lutimes(path, time);
4473#endif
4474}
4475
4476#endif
4477
4478#ifndef MS_WINDOWS
4479
4480static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004481utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004482{
4483#ifdef HAVE_UTIMENSAT
4484 UTIME_TO_TIMESPEC;
4485 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4486#elif defined(HAVE_UTIMES)
4487 UTIME_TO_TIMEVAL;
4488 return utimes(path, time);
4489#elif defined(HAVE_UTIME_H)
4490 UTIME_TO_UTIMBUF;
4491 return utime(path, time);
4492#else
4493 UTIME_TO_TIME_T;
4494 return utime(path, time);
4495#endif
4496}
4497
4498#endif
4499
Larry Hastings76ad59b2012-05-03 00:30:07 -07004500static int
4501split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4502{
4503 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004504 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004505 divmod = PyNumber_Divmod(py_long, billion);
4506 if (!divmod)
4507 goto exit;
4508 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4509 if ((*s == -1) && PyErr_Occurred())
4510 goto exit;
4511 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004512 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004513 goto exit;
4514
4515 result = 1;
4516exit:
4517 Py_XDECREF(divmod);
4518 return result;
4519}
4520
Larry Hastings2f936352014-08-05 14:04:04 +10004521
4522/*[clinic input]
4523os.utime
4524
4525 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4526 times: object = NULL
4527 *
4528 ns: object = NULL
4529 dir_fd: dir_fd(requires='futimensat') = None
4530 follow_symlinks: bool=True
4531
Martin Panter0ff89092015-09-09 01:56:53 +00004532# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004533
4534Set the access and modified time of path.
4535
4536path may always be specified as a string.
4537On some platforms, path may also be specified as an open file descriptor.
4538 If this functionality is unavailable, using it raises an exception.
4539
4540If times is not None, it must be a tuple (atime, mtime);
4541 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004542If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004543 atime_ns and mtime_ns should be expressed as integer nanoseconds
4544 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004545If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004546Specifying tuples for both times and ns is an error.
4547
4548If dir_fd is not None, it should be a file descriptor open to a directory,
4549 and path should be relative; path will then be relative to that directory.
4550If follow_symlinks is False, and the last element of the path is a symbolic
4551 link, utime will modify the symbolic link itself instead of the file the
4552 link points to.
4553It is an error to use dir_fd or follow_symlinks when specifying path
4554 as an open file descriptor.
4555dir_fd and follow_symlinks may not be available on your platform.
4556 If they are unavailable, using them will raise a NotImplementedError.
4557
4558[clinic start generated code]*/
4559
Larry Hastings2f936352014-08-05 14:04:04 +10004560static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004561os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4562 int dir_fd, int follow_symlinks)
4563/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004564{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565#ifdef MS_WINDOWS
4566 HANDLE hFile;
4567 FILETIME atime, mtime;
4568#else
4569 int result;
4570#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004571
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004573 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004574
Christian Heimesb3c87242013-08-01 00:08:16 +02004575 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004576
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577 if (times && (times != Py_None) && ns) {
4578 PyErr_SetString(PyExc_ValueError,
4579 "utime: you may specify either 'times'"
4580 " or 'ns' but not both");
4581 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004582 }
4583
4584 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004585 time_t a_sec, m_sec;
4586 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004587 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 PyErr_SetString(PyExc_TypeError,
4589 "utime: 'times' must be either"
4590 " a tuple of two ints or None");
4591 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004592 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004593 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004594 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004595 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004596 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004597 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004599 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004600 utime.atime_s = a_sec;
4601 utime.atime_ns = a_nsec;
4602 utime.mtime_s = m_sec;
4603 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004604 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004606 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607 PyErr_SetString(PyExc_TypeError,
4608 "utime: 'ns' must be a tuple of two ints");
4609 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004610 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004612 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004614 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615 &utime.mtime_s, &utime.mtime_ns)) {
4616 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004617 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004618 }
4619 else {
4620 /* times and ns are both None/unspecified. use "now". */
4621 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004622 }
4623
Victor Stinner4552ced2015-09-21 22:37:15 +02004624#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004625 if (follow_symlinks_specified("utime", follow_symlinks))
4626 goto exit;
4627#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004628
Larry Hastings2f936352014-08-05 14:04:04 +10004629 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4630 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4631 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004633
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634#if !defined(HAVE_UTIMENSAT)
4635 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004636 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637 "utime: cannot use dir_fd and follow_symlinks "
4638 "together on this platform");
4639 goto exit;
4640 }
4641#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004642
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004643#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004644 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004645 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4646 NULL, OPEN_EXISTING,
4647 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648 Py_END_ALLOW_THREADS
4649 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004650 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004652 }
4653
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004655 GetSystemTimeAsFileTime(&mtime);
4656 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004657 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004658 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004659 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4660 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004661 }
4662 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4663 /* Avoid putting the file name into the error here,
4664 as that may confuse the user into believing that
4665 something is wrong with the file, when it also
4666 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004667 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004669 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004670#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004672
Victor Stinner4552ced2015-09-21 22:37:15 +02004673#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004675 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004676 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004677#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678
Victor Stinner528a9ab2015-09-03 21:30:26 +02004679#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004681 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 else
4683#endif
4684
Victor Stinner528a9ab2015-09-03 21:30:26 +02004685#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004686 if (path->fd != -1)
4687 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 else
4689#endif
4690
Larry Hastings2f936352014-08-05 14:04:04 +10004691 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692
4693 Py_END_ALLOW_THREADS
4694
4695 if (result < 0) {
4696 /* see previous comment about not putting filename in error here */
4697 return_value = posix_error();
4698 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004699 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004700
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004701#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702
4703 Py_INCREF(Py_None);
4704 return_value = Py_None;
4705
4706exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707#ifdef MS_WINDOWS
4708 if (hFile != INVALID_HANDLE_VALUE)
4709 CloseHandle(hFile);
4710#endif
4711 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004712}
4713
Guido van Rossum3b066191991-06-04 19:40:25 +00004714/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004715
Larry Hastings2f936352014-08-05 14:04:04 +10004716
4717/*[clinic input]
4718os._exit
4719
4720 status: int
4721
4722Exit to the system with specified status, without normal exit processing.
4723[clinic start generated code]*/
4724
Larry Hastings2f936352014-08-05 14:04:04 +10004725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004726os__exit_impl(PyObject *module, int status)
4727/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004728{
4729 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004730 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004731}
4732
Steve Dowercc16be82016-09-08 10:35:16 -07004733#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4734#define EXECV_CHAR wchar_t
4735#else
4736#define EXECV_CHAR char
4737#endif
4738
Martin v. Löwis114619e2002-10-07 06:44:21 +00004739#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4740static void
Steve Dowercc16be82016-09-08 10:35:16 -07004741free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004742{
Victor Stinner8c62be82010-05-06 00:08:46 +00004743 Py_ssize_t i;
4744 for (i = 0; i < count; i++)
4745 PyMem_Free(array[i]);
4746 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004747}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004748
Berker Peksag81816462016-09-15 20:19:47 +03004749static int
4750fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004751{
Victor Stinner8c62be82010-05-06 00:08:46 +00004752 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004753 PyObject *ub;
4754 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004755#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004756 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004757 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004758 *out = PyUnicode_AsWideCharString(ub, &size);
4759 if (*out)
4760 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004761#else
Berker Peksag81816462016-09-15 20:19:47 +03004762 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004763 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004764 size = PyBytes_GET_SIZE(ub);
4765 *out = PyMem_Malloc(size + 1);
4766 if (*out) {
4767 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4768 result = 1;
4769 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004770 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004771#endif
Berker Peksag81816462016-09-15 20:19:47 +03004772 Py_DECREF(ub);
4773 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004774}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004775#endif
4776
Ross Lagerwall7807c352011-03-17 20:20:30 +02004777#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004778static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004779parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4780{
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 Py_ssize_t i, pos, envc;
4782 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004783 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004784 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004785
Victor Stinner8c62be82010-05-06 00:08:46 +00004786 i = PyMapping_Size(env);
4787 if (i < 0)
4788 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004789 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004790 if (envlist == NULL) {
4791 PyErr_NoMemory();
4792 return NULL;
4793 }
4794 envc = 0;
4795 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004796 if (!keys)
4797 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004799 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004800 goto error;
4801 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4802 PyErr_Format(PyExc_TypeError,
4803 "env.keys() or env.values() is not a list");
4804 goto error;
4805 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004806
Victor Stinner8c62be82010-05-06 00:08:46 +00004807 for (pos = 0; pos < i; pos++) {
4808 key = PyList_GetItem(keys, pos);
4809 val = PyList_GetItem(vals, pos);
4810 if (!key || !val)
4811 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004812
Berker Peksag81816462016-09-15 20:19:47 +03004813#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4814 if (!PyUnicode_FSDecoder(key, &key2))
4815 goto error;
4816 if (!PyUnicode_FSDecoder(val, &val2)) {
4817 Py_DECREF(key2);
4818 goto error;
4819 }
4820 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4821#else
4822 if (!PyUnicode_FSConverter(key, &key2))
4823 goto error;
4824 if (!PyUnicode_FSConverter(val, &val2)) {
4825 Py_DECREF(key2);
4826 goto error;
4827 }
4828 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4829 PyBytes_AS_STRING(val2));
4830#endif
4831 Py_DECREF(key2);
4832 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004833 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004835
4836 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4837 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 goto error;
4839 }
Berker Peksag81816462016-09-15 20:19:47 +03004840
Steve Dowercc16be82016-09-08 10:35:16 -07004841 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 }
4843 Py_DECREF(vals);
4844 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004845
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 envlist[envc] = 0;
4847 *envc_ptr = envc;
4848 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004849
4850error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 Py_XDECREF(keys);
4852 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004853 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004855}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004856
Steve Dowercc16be82016-09-08 10:35:16 -07004857static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004858parse_arglist(PyObject* argv, Py_ssize_t *argc)
4859{
4860 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004861 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004862 if (argvlist == NULL) {
4863 PyErr_NoMemory();
4864 return NULL;
4865 }
4866 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004867 PyObject* item = PySequence_ITEM(argv, i);
4868 if (item == NULL)
4869 goto fail;
4870 if (!fsconvert_strdup(item, &argvlist[i])) {
4871 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004872 goto fail;
4873 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004874 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004875 }
4876 argvlist[*argc] = NULL;
4877 return argvlist;
4878fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004879 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004880 free_string_array(argvlist, *argc);
4881 return NULL;
4882}
Steve Dowercc16be82016-09-08 10:35:16 -07004883
Ross Lagerwall7807c352011-03-17 20:20:30 +02004884#endif
4885
Larry Hastings2f936352014-08-05 14:04:04 +10004886
Ross Lagerwall7807c352011-03-17 20:20:30 +02004887#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004888/*[clinic input]
4889os.execv
4890
Steve Dowercc16be82016-09-08 10:35:16 -07004891 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004892 Path of executable file.
4893 argv: object
4894 Tuple or list of strings.
4895 /
4896
4897Execute an executable path with arguments, replacing current process.
4898[clinic start generated code]*/
4899
Larry Hastings2f936352014-08-05 14:04:04 +10004900static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004901os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4902/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004903{
Steve Dowercc16be82016-09-08 10:35:16 -07004904 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004905 Py_ssize_t argc;
4906
4907 /* execv has two arguments: (path, argv), where
4908 argv is a list or tuple of strings. */
4909
Ross Lagerwall7807c352011-03-17 20:20:30 +02004910 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4911 PyErr_SetString(PyExc_TypeError,
4912 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004913 return NULL;
4914 }
4915 argc = PySequence_Size(argv);
4916 if (argc < 1) {
4917 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004918 return NULL;
4919 }
4920
4921 argvlist = parse_arglist(argv, &argc);
4922 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004923 return NULL;
4924 }
Steve Dowerbce26262016-11-19 19:17:26 -08004925 if (!argvlist[0][0]) {
4926 PyErr_SetString(PyExc_ValueError,
4927 "execv() arg 2 first element cannot be empty");
4928 free_string_array(argvlist, argc);
4929 return NULL;
4930 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004931
Steve Dowerbce26262016-11-19 19:17:26 -08004932 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004933#ifdef HAVE_WEXECV
4934 _wexecv(path->wide, argvlist);
4935#else
4936 execv(path->narrow, argvlist);
4937#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004938 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004939
4940 /* If we get here it's definitely an error */
4941
4942 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004943 return posix_error();
4944}
4945
Larry Hastings2f936352014-08-05 14:04:04 +10004946
4947/*[clinic input]
4948os.execve
4949
4950 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4951 Path of executable file.
4952 argv: object
4953 Tuple or list of strings.
4954 env: object
4955 Dictionary of strings mapping to strings.
4956
4957Execute an executable path with arguments, replacing current process.
4958[clinic start generated code]*/
4959
Larry Hastings2f936352014-08-05 14:04:04 +10004960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004961os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4962/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004963{
Steve Dowercc16be82016-09-08 10:35:16 -07004964 EXECV_CHAR **argvlist = NULL;
4965 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004966 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004967
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 /* execve has three arguments: (path, argv, env), where
4969 argv is a list or tuple of strings and env is a dictionary
4970 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004971
Ross Lagerwall7807c352011-03-17 20:20:30 +02004972 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974 "execve: argv must be a tuple or list");
4975 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004976 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004977 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08004978 if (argc < 1) {
4979 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
4980 return NULL;
4981 }
4982
Victor Stinner8c62be82010-05-06 00:08:46 +00004983 if (!PyMapping_Check(env)) {
4984 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 "execve: environment must be a mapping object");
4986 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004988
Ross Lagerwall7807c352011-03-17 20:20:30 +02004989 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004991 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 }
Steve Dowerbce26262016-11-19 19:17:26 -08004993 if (!argvlist[0][0]) {
4994 PyErr_SetString(PyExc_ValueError,
4995 "execve: argv first element cannot be empty");
4996 goto fail;
4997 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004998
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 envlist = parse_envlist(env, &envc);
5000 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001 goto fail;
5002
Steve Dowerbce26262016-11-19 19:17:26 -08005003 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005004#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005005 if (path->fd > -1)
5006 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005007 else
5008#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005009#ifdef HAVE_WEXECV
5010 _wexecve(path->wide, argvlist, envlist);
5011#else
Larry Hastings2f936352014-08-05 14:04:04 +10005012 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005013#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005014 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015
5016 /* If we get here it's definitely an error */
5017
Larry Hastings2f936352014-08-05 14:04:04 +10005018 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019
Steve Dowercc16be82016-09-08 10:35:16 -07005020 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005021 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005022 if (argvlist)
5023 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005024 return NULL;
5025}
Steve Dowercc16be82016-09-08 10:35:16 -07005026
Larry Hastings9cf065c2012-06-22 16:30:09 -07005027#endif /* HAVE_EXECV */
5028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005029
Steve Dowercc16be82016-09-08 10:35:16 -07005030#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005031/*[clinic input]
5032os.spawnv
5033
5034 mode: int
5035 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005036 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005037 Path of executable file.
5038 argv: object
5039 Tuple or list of strings.
5040 /
5041
5042Execute the program specified by path in a new process.
5043[clinic start generated code]*/
5044
Larry Hastings2f936352014-08-05 14:04:04 +10005045static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005046os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5047/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005048{
Steve Dowercc16be82016-09-08 10:35:16 -07005049 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005050 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005052 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005054
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 /* spawnv has three arguments: (mode, path, argv), where
5056 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005057
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 if (PyList_Check(argv)) {
5059 argc = PyList_Size(argv);
5060 getitem = PyList_GetItem;
5061 }
5062 else if (PyTuple_Check(argv)) {
5063 argc = PyTuple_Size(argv);
5064 getitem = PyTuple_GetItem;
5065 }
5066 else {
5067 PyErr_SetString(PyExc_TypeError,
5068 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 return NULL;
5070 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005071 if (argc == 0) {
5072 PyErr_SetString(PyExc_ValueError,
5073 "spawnv() arg 2 cannot be empty");
5074 return NULL;
5075 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005076
Steve Dowercc16be82016-09-08 10:35:16 -07005077 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 return PyErr_NoMemory();
5080 }
5081 for (i = 0; i < argc; i++) {
5082 if (!fsconvert_strdup((*getitem)(argv, i),
5083 &argvlist[i])) {
5084 free_string_array(argvlist, i);
5085 PyErr_SetString(
5086 PyExc_TypeError,
5087 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005088 return NULL;
5089 }
Steve Dower93ff8722016-11-19 19:03:54 -08005090 if (i == 0 && !argvlist[0][0]) {
5091 free_string_array(argvlist, i);
5092 PyErr_SetString(
5093 PyExc_ValueError,
5094 "spawnv() arg 2 first element cannot be empty");
5095 return NULL;
5096 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 }
5098 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005099
Victor Stinner8c62be82010-05-06 00:08:46 +00005100 if (mode == _OLD_P_OVERLAY)
5101 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005102
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005104 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005105#ifdef HAVE_WSPAWNV
5106 spawnval = _wspawnv(mode, path->wide, argvlist);
5107#else
5108 spawnval = _spawnv(mode, path->narrow, argvlist);
5109#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005110 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005112
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005114
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 if (spawnval == -1)
5116 return posix_error();
5117 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005118 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005119}
5120
5121
Larry Hastings2f936352014-08-05 14:04:04 +10005122/*[clinic input]
5123os.spawnve
5124
5125 mode: int
5126 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005127 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005128 Path of executable file.
5129 argv: object
5130 Tuple or list of strings.
5131 env: object
5132 Dictionary of strings mapping to strings.
5133 /
5134
5135Execute the program specified by path in a new process.
5136[clinic start generated code]*/
5137
Larry Hastings2f936352014-08-05 14:04:04 +10005138static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005139os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005140 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005141/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005142{
Steve Dowercc16be82016-09-08 10:35:16 -07005143 EXECV_CHAR **argvlist;
5144 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005146 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005147 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5149 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005150
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 /* spawnve has four arguments: (mode, path, argv, env), where
5152 argv is a list or tuple of strings and env is a dictionary
5153 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005154
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 if (PyList_Check(argv)) {
5156 argc = PyList_Size(argv);
5157 getitem = PyList_GetItem;
5158 }
5159 else if (PyTuple_Check(argv)) {
5160 argc = PyTuple_Size(argv);
5161 getitem = PyTuple_GetItem;
5162 }
5163 else {
5164 PyErr_SetString(PyExc_TypeError,
5165 "spawnve() arg 2 must be a tuple or list");
5166 goto fail_0;
5167 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005168 if (argc == 0) {
5169 PyErr_SetString(PyExc_ValueError,
5170 "spawnve() arg 2 cannot be empty");
5171 goto fail_0;
5172 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 if (!PyMapping_Check(env)) {
5174 PyErr_SetString(PyExc_TypeError,
5175 "spawnve() arg 3 must be a mapping object");
5176 goto fail_0;
5177 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005178
Steve Dowercc16be82016-09-08 10:35:16 -07005179 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005180 if (argvlist == NULL) {
5181 PyErr_NoMemory();
5182 goto fail_0;
5183 }
5184 for (i = 0; i < argc; i++) {
5185 if (!fsconvert_strdup((*getitem)(argv, i),
5186 &argvlist[i]))
5187 {
5188 lastarg = i;
5189 goto fail_1;
5190 }
Steve Dowerbce26262016-11-19 19:17:26 -08005191 if (i == 0 && !argvlist[0][0]) {
5192 lastarg = i;
5193 PyErr_SetString(
5194 PyExc_ValueError,
5195 "spawnv() arg 2 first element cannot be empty");
5196 goto fail_1;
5197 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 }
5199 lastarg = argc;
5200 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005201
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 envlist = parse_envlist(env, &envc);
5203 if (envlist == NULL)
5204 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 if (mode == _OLD_P_OVERLAY)
5207 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005208
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005210 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005211#ifdef HAVE_WSPAWNV
5212 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5213#else
5214 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5215#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005216 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005218
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 if (spawnval == -1)
5220 (void) posix_error();
5221 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005222 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005223
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 while (--envc >= 0)
5225 PyMem_DEL(envlist[envc]);
5226 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005227 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005229 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005231}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005232
Guido van Rossuma1065681999-01-25 23:20:23 +00005233#endif /* HAVE_SPAWNV */
5234
5235
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005236#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005237/*[clinic input]
5238os.fork1
5239
5240Fork a child process with a single multiplexed (i.e., not bound) thread.
5241
5242Return 0 to child process and PID of child to parent process.
5243[clinic start generated code]*/
5244
Larry Hastings2f936352014-08-05 14:04:04 +10005245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005246os_fork1_impl(PyObject *module)
5247/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005248{
Victor Stinner8c62be82010-05-06 00:08:46 +00005249 pid_t pid;
5250 int result = 0;
5251 _PyImport_AcquireLock();
5252 pid = fork1();
5253 if (pid == 0) {
5254 /* child: this clobbers and resets the import lock. */
5255 PyOS_AfterFork();
5256 } else {
5257 /* parent: release the import lock. */
5258 result = _PyImport_ReleaseLock();
5259 }
5260 if (pid == -1)
5261 return posix_error();
5262 if (result < 0) {
5263 /* Don't clobber the OSError if the fork failed. */
5264 PyErr_SetString(PyExc_RuntimeError,
5265 "not holding the import lock");
5266 return NULL;
5267 }
5268 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005269}
Larry Hastings2f936352014-08-05 14:04:04 +10005270#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005271
5272
Guido van Rossumad0ee831995-03-01 10:34:45 +00005273#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005274/*[clinic input]
5275os.fork
5276
5277Fork a child process.
5278
5279Return 0 to child process and PID of child to parent process.
5280[clinic start generated code]*/
5281
Larry Hastings2f936352014-08-05 14:04:04 +10005282static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005283os_fork_impl(PyObject *module)
5284/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005285{
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 pid_t pid;
5287 int result = 0;
5288 _PyImport_AcquireLock();
5289 pid = fork();
5290 if (pid == 0) {
5291 /* child: this clobbers and resets the import lock. */
5292 PyOS_AfterFork();
5293 } else {
5294 /* parent: release the import lock. */
5295 result = _PyImport_ReleaseLock();
5296 }
5297 if (pid == -1)
5298 return posix_error();
5299 if (result < 0) {
5300 /* Don't clobber the OSError if the fork failed. */
5301 PyErr_SetString(PyExc_RuntimeError,
5302 "not holding the import lock");
5303 return NULL;
5304 }
5305 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005306}
Larry Hastings2f936352014-08-05 14:04:04 +10005307#endif /* HAVE_FORK */
5308
Guido van Rossum85e3b011991-06-03 12:42:10 +00005309
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005310#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005311#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005312/*[clinic input]
5313os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005314
Larry Hastings2f936352014-08-05 14:04:04 +10005315 policy: int
5316
5317Get the maximum scheduling priority for policy.
5318[clinic start generated code]*/
5319
Larry Hastings2f936352014-08-05 14:04:04 +10005320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005321os_sched_get_priority_max_impl(PyObject *module, int policy)
5322/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005323{
5324 int max;
5325
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005326 max = sched_get_priority_max(policy);
5327 if (max < 0)
5328 return posix_error();
5329 return PyLong_FromLong(max);
5330}
5331
Larry Hastings2f936352014-08-05 14:04:04 +10005332
5333/*[clinic input]
5334os.sched_get_priority_min
5335
5336 policy: int
5337
5338Get the minimum scheduling priority for policy.
5339[clinic start generated code]*/
5340
Larry Hastings2f936352014-08-05 14:04:04 +10005341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005342os_sched_get_priority_min_impl(PyObject *module, int policy)
5343/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005344{
5345 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005346 if (min < 0)
5347 return posix_error();
5348 return PyLong_FromLong(min);
5349}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005350#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5351
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005352
Larry Hastings2f936352014-08-05 14:04:04 +10005353#ifdef HAVE_SCHED_SETSCHEDULER
5354/*[clinic input]
5355os.sched_getscheduler
5356 pid: pid_t
5357 /
5358
5359Get the scheduling policy for the process identifiedy by pid.
5360
5361Passing 0 for pid returns the scheduling policy for the calling process.
5362[clinic start generated code]*/
5363
Larry Hastings2f936352014-08-05 14:04:04 +10005364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005365os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5366/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005367{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005368 int policy;
5369
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005370 policy = sched_getscheduler(pid);
5371 if (policy < 0)
5372 return posix_error();
5373 return PyLong_FromLong(policy);
5374}
Larry Hastings2f936352014-08-05 14:04:04 +10005375#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005376
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005377
5378#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005379/*[clinic input]
5380class os.sched_param "PyObject *" "&SchedParamType"
5381
5382@classmethod
5383os.sched_param.__new__
5384
5385 sched_priority: object
5386 A scheduling parameter.
5387
5388Current has only one field: sched_priority");
5389[clinic start generated code]*/
5390
Larry Hastings2f936352014-08-05 14:04:04 +10005391static PyObject *
5392os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005393/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005394{
5395 PyObject *res;
5396
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005397 res = PyStructSequence_New(type);
5398 if (!res)
5399 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005400 Py_INCREF(sched_priority);
5401 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005402 return res;
5403}
5404
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005405
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005406PyDoc_VAR(os_sched_param__doc__);
5407
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005408static PyStructSequence_Field sched_param_fields[] = {
5409 {"sched_priority", "the scheduling priority"},
5410 {0}
5411};
5412
5413static PyStructSequence_Desc sched_param_desc = {
5414 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005415 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005416 sched_param_fields,
5417 1
5418};
5419
5420static int
5421convert_sched_param(PyObject *param, struct sched_param *res)
5422{
5423 long priority;
5424
5425 if (Py_TYPE(param) != &SchedParamType) {
5426 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5427 return 0;
5428 }
5429 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5430 if (priority == -1 && PyErr_Occurred())
5431 return 0;
5432 if (priority > INT_MAX || priority < INT_MIN) {
5433 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5434 return 0;
5435 }
5436 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5437 return 1;
5438}
Larry Hastings2f936352014-08-05 14:04:04 +10005439#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005440
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005441
5442#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005443/*[clinic input]
5444os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005445
Larry Hastings2f936352014-08-05 14:04:04 +10005446 pid: pid_t
5447 policy: int
5448 param: sched_param
5449 /
5450
5451Set the scheduling policy for the process identified by pid.
5452
5453If pid is 0, the calling process is changed.
5454param is an instance of sched_param.
5455[clinic start generated code]*/
5456
Larry Hastings2f936352014-08-05 14:04:04 +10005457static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005458os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005459 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005460/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005461{
Jesus Cea9c822272011-09-10 01:40:52 +02005462 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005463 ** sched_setscheduler() returns 0 in Linux, but the previous
5464 ** scheduling policy under Solaris/Illumos, and others.
5465 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005466 */
Larry Hastings2f936352014-08-05 14:04:04 +10005467 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005468 return posix_error();
5469 Py_RETURN_NONE;
5470}
Larry Hastings2f936352014-08-05 14:04:04 +10005471#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005472
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005473
5474#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005475/*[clinic input]
5476os.sched_getparam
5477 pid: pid_t
5478 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005479
Larry Hastings2f936352014-08-05 14:04:04 +10005480Returns scheduling parameters for the process identified by pid.
5481
5482If pid is 0, returns parameters for the calling process.
5483Return value is an instance of sched_param.
5484[clinic start generated code]*/
5485
Larry Hastings2f936352014-08-05 14:04:04 +10005486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005487os_sched_getparam_impl(PyObject *module, pid_t pid)
5488/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005489{
5490 struct sched_param param;
5491 PyObject *result;
5492 PyObject *priority;
5493
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005494 if (sched_getparam(pid, &param))
5495 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005496 result = PyStructSequence_New(&SchedParamType);
5497 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005498 return NULL;
5499 priority = PyLong_FromLong(param.sched_priority);
5500 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005501 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005502 return NULL;
5503 }
Larry Hastings2f936352014-08-05 14:04:04 +10005504 PyStructSequence_SET_ITEM(result, 0, priority);
5505 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005506}
5507
Larry Hastings2f936352014-08-05 14:04:04 +10005508
5509/*[clinic input]
5510os.sched_setparam
5511 pid: pid_t
5512 param: sched_param
5513 /
5514
5515Set scheduling parameters for the process identified by pid.
5516
5517If pid is 0, sets parameters for the calling process.
5518param should be an instance of sched_param.
5519[clinic start generated code]*/
5520
Larry Hastings2f936352014-08-05 14:04:04 +10005521static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005522os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005523 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005524/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005525{
5526 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005527 return posix_error();
5528 Py_RETURN_NONE;
5529}
Larry Hastings2f936352014-08-05 14:04:04 +10005530#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005531
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005532
5533#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005534/*[clinic input]
5535os.sched_rr_get_interval -> double
5536 pid: pid_t
5537 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005538
Larry Hastings2f936352014-08-05 14:04:04 +10005539Return the round-robin quantum for the process identified by pid, in seconds.
5540
5541Value returned is a float.
5542[clinic start generated code]*/
5543
Larry Hastings2f936352014-08-05 14:04:04 +10005544static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005545os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5546/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005547{
5548 struct timespec interval;
5549 if (sched_rr_get_interval(pid, &interval)) {
5550 posix_error();
5551 return -1.0;
5552 }
5553 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5554}
5555#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005556
Larry Hastings2f936352014-08-05 14:04:04 +10005557
5558/*[clinic input]
5559os.sched_yield
5560
5561Voluntarily relinquish the CPU.
5562[clinic start generated code]*/
5563
Larry Hastings2f936352014-08-05 14:04:04 +10005564static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005565os_sched_yield_impl(PyObject *module)
5566/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005567{
5568 if (sched_yield())
5569 return posix_error();
5570 Py_RETURN_NONE;
5571}
5572
Benjamin Peterson2740af82011-08-02 17:41:34 -05005573#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005574/* The minimum number of CPUs allocated in a cpu_set_t */
5575static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005576
Larry Hastings2f936352014-08-05 14:04:04 +10005577/*[clinic input]
5578os.sched_setaffinity
5579 pid: pid_t
5580 mask : object
5581 /
5582
5583Set the CPU affinity of the process identified by pid to mask.
5584
5585mask should be an iterable of integers identifying CPUs.
5586[clinic start generated code]*/
5587
Larry Hastings2f936352014-08-05 14:04:04 +10005588static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005589os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5590/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005591{
Antoine Pitrou84869872012-08-04 16:16:35 +02005592 int ncpus;
5593 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005594 cpu_set_t *cpu_set = NULL;
5595 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005596
Larry Hastings2f936352014-08-05 14:04:04 +10005597 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005598 if (iterator == NULL)
5599 return NULL;
5600
5601 ncpus = NCPUS_START;
5602 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005603 cpu_set = CPU_ALLOC(ncpus);
5604 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005605 PyErr_NoMemory();
5606 goto error;
5607 }
Larry Hastings2f936352014-08-05 14:04:04 +10005608 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005609
5610 while ((item = PyIter_Next(iterator))) {
5611 long cpu;
5612 if (!PyLong_Check(item)) {
5613 PyErr_Format(PyExc_TypeError,
5614 "expected an iterator of ints, "
5615 "but iterator yielded %R",
5616 Py_TYPE(item));
5617 Py_DECREF(item);
5618 goto error;
5619 }
5620 cpu = PyLong_AsLong(item);
5621 Py_DECREF(item);
5622 if (cpu < 0) {
5623 if (!PyErr_Occurred())
5624 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5625 goto error;
5626 }
5627 if (cpu > INT_MAX - 1) {
5628 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5629 goto error;
5630 }
5631 if (cpu >= ncpus) {
5632 /* Grow CPU mask to fit the CPU number */
5633 int newncpus = ncpus;
5634 cpu_set_t *newmask;
5635 size_t newsetsize;
5636 while (newncpus <= cpu) {
5637 if (newncpus > INT_MAX / 2)
5638 newncpus = cpu + 1;
5639 else
5640 newncpus = newncpus * 2;
5641 }
5642 newmask = CPU_ALLOC(newncpus);
5643 if (newmask == NULL) {
5644 PyErr_NoMemory();
5645 goto error;
5646 }
5647 newsetsize = CPU_ALLOC_SIZE(newncpus);
5648 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005649 memcpy(newmask, cpu_set, setsize);
5650 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005651 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005652 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005653 ncpus = newncpus;
5654 }
Larry Hastings2f936352014-08-05 14:04:04 +10005655 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005656 }
5657 Py_CLEAR(iterator);
5658
Larry Hastings2f936352014-08-05 14:04:04 +10005659 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005660 posix_error();
5661 goto error;
5662 }
Larry Hastings2f936352014-08-05 14:04:04 +10005663 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005664 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005665
5666error:
Larry Hastings2f936352014-08-05 14:04:04 +10005667 if (cpu_set)
5668 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005669 Py_XDECREF(iterator);
5670 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005671}
5672
Larry Hastings2f936352014-08-05 14:04:04 +10005673
5674/*[clinic input]
5675os.sched_getaffinity
5676 pid: pid_t
5677 /
5678
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005679Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005680
5681The affinity is returned as a set of CPU identifiers.
5682[clinic start generated code]*/
5683
Larry Hastings2f936352014-08-05 14:04:04 +10005684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005685os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005686/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005687{
Antoine Pitrou84869872012-08-04 16:16:35 +02005688 int cpu, ncpus, count;
5689 size_t setsize;
5690 cpu_set_t *mask = NULL;
5691 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005692
Antoine Pitrou84869872012-08-04 16:16:35 +02005693 ncpus = NCPUS_START;
5694 while (1) {
5695 setsize = CPU_ALLOC_SIZE(ncpus);
5696 mask = CPU_ALLOC(ncpus);
5697 if (mask == NULL)
5698 return PyErr_NoMemory();
5699 if (sched_getaffinity(pid, setsize, mask) == 0)
5700 break;
5701 CPU_FREE(mask);
5702 if (errno != EINVAL)
5703 return posix_error();
5704 if (ncpus > INT_MAX / 2) {
5705 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5706 "a large enough CPU set");
5707 return NULL;
5708 }
5709 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005710 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005711
5712 res = PySet_New(NULL);
5713 if (res == NULL)
5714 goto error;
5715 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5716 if (CPU_ISSET_S(cpu, setsize, mask)) {
5717 PyObject *cpu_num = PyLong_FromLong(cpu);
5718 --count;
5719 if (cpu_num == NULL)
5720 goto error;
5721 if (PySet_Add(res, cpu_num)) {
5722 Py_DECREF(cpu_num);
5723 goto error;
5724 }
5725 Py_DECREF(cpu_num);
5726 }
5727 }
5728 CPU_FREE(mask);
5729 return res;
5730
5731error:
5732 if (mask)
5733 CPU_FREE(mask);
5734 Py_XDECREF(res);
5735 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005736}
5737
Benjamin Peterson2740af82011-08-02 17:41:34 -05005738#endif /* HAVE_SCHED_SETAFFINITY */
5739
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005740#endif /* HAVE_SCHED_H */
5741
Larry Hastings2f936352014-08-05 14:04:04 +10005742
Neal Norwitzb59798b2003-03-21 01:43:31 +00005743/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005744/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5745#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005746#define DEV_PTY_FILE "/dev/ptc"
5747#define HAVE_DEV_PTMX
5748#else
5749#define DEV_PTY_FILE "/dev/ptmx"
5750#endif
5751
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005752#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005753#ifdef HAVE_PTY_H
5754#include <pty.h>
5755#else
5756#ifdef HAVE_LIBUTIL_H
5757#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005758#else
5759#ifdef HAVE_UTIL_H
5760#include <util.h>
5761#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005762#endif /* HAVE_LIBUTIL_H */
5763#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005764#ifdef HAVE_STROPTS_H
5765#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005766#endif
5767#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005768
Larry Hastings2f936352014-08-05 14:04:04 +10005769
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005770#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005771/*[clinic input]
5772os.openpty
5773
5774Open a pseudo-terminal.
5775
5776Return a tuple of (master_fd, slave_fd) containing open file descriptors
5777for both the master and slave ends.
5778[clinic start generated code]*/
5779
Larry Hastings2f936352014-08-05 14:04:04 +10005780static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005781os_openpty_impl(PyObject *module)
5782/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005783{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005784 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005785#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005787#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005788#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005790#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005792#endif
5793#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005794
Thomas Wouters70c21a12000-07-14 14:28:33 +00005795#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005797 goto posix_error;
5798
5799 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5800 goto error;
5801 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5802 goto error;
5803
Neal Norwitzb59798b2003-03-21 01:43:31 +00005804#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5806 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005807 goto posix_error;
5808 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5809 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005810
Victor Stinnerdaf45552013-08-28 00:53:59 +02005811 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005812 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005813 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005814
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005815#else
Victor Stinner000de532013-11-25 23:19:58 +01005816 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005818 goto posix_error;
5819
Victor Stinner8c62be82010-05-06 00:08:46 +00005820 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005821
Victor Stinner8c62be82010-05-06 00:08:46 +00005822 /* change permission of slave */
5823 if (grantpt(master_fd) < 0) {
5824 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005825 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005826 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005827
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 /* unlock slave */
5829 if (unlockpt(master_fd) < 0) {
5830 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005831 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005833
Victor Stinner8c62be82010-05-06 00:08:46 +00005834 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005835
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 slave_name = ptsname(master_fd); /* get name of slave */
5837 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005838 goto posix_error;
5839
5840 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005841 if (slave_fd == -1)
5842 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005843
5844 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5845 goto posix_error;
5846
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005847#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5849 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005850#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005851 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005852#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005853#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005854#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005855
Victor Stinner8c62be82010-05-06 00:08:46 +00005856 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005857
Victor Stinnerdaf45552013-08-28 00:53:59 +02005858posix_error:
5859 posix_error();
5860error:
5861 if (master_fd != -1)
5862 close(master_fd);
5863 if (slave_fd != -1)
5864 close(slave_fd);
5865 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005866}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005867#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005868
Larry Hastings2f936352014-08-05 14:04:04 +10005869
Fred Drake8cef4cf2000-06-28 16:40:38 +00005870#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005871/*[clinic input]
5872os.forkpty
5873
5874Fork a new process with a new pseudo-terminal as controlling tty.
5875
5876Returns a tuple of (pid, master_fd).
5877Like fork(), return pid of 0 to the child process,
5878and pid of child to the parent process.
5879To both, return fd of newly opened pseudo-terminal.
5880[clinic start generated code]*/
5881
Larry Hastings2f936352014-08-05 14:04:04 +10005882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005883os_forkpty_impl(PyObject *module)
5884/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005885{
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 int master_fd = -1, result = 0;
5887 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005888
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 _PyImport_AcquireLock();
5890 pid = forkpty(&master_fd, NULL, NULL, NULL);
5891 if (pid == 0) {
5892 /* child: this clobbers and resets the import lock. */
5893 PyOS_AfterFork();
5894 } else {
5895 /* parent: release the import lock. */
5896 result = _PyImport_ReleaseLock();
5897 }
5898 if (pid == -1)
5899 return posix_error();
5900 if (result < 0) {
5901 /* Don't clobber the OSError if the fork failed. */
5902 PyErr_SetString(PyExc_RuntimeError,
5903 "not holding the import lock");
5904 return NULL;
5905 }
5906 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005907}
Larry Hastings2f936352014-08-05 14:04:04 +10005908#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005909
Ross Lagerwall7807c352011-03-17 20:20:30 +02005910
Guido van Rossumad0ee831995-03-01 10:34:45 +00005911#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005912/*[clinic input]
5913os.getegid
5914
5915Return the current process's effective group id.
5916[clinic start generated code]*/
5917
Larry Hastings2f936352014-08-05 14:04:04 +10005918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005919os_getegid_impl(PyObject *module)
5920/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005921{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005922 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005923}
Larry Hastings2f936352014-08-05 14:04:04 +10005924#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005925
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005926
Guido van Rossumad0ee831995-03-01 10:34:45 +00005927#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005928/*[clinic input]
5929os.geteuid
5930
5931Return the current process's effective user id.
5932[clinic start generated code]*/
5933
Larry Hastings2f936352014-08-05 14:04:04 +10005934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005935os_geteuid_impl(PyObject *module)
5936/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005937{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005938 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005939}
Larry Hastings2f936352014-08-05 14:04:04 +10005940#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005942
Guido van Rossumad0ee831995-03-01 10:34:45 +00005943#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005944/*[clinic input]
5945os.getgid
5946
5947Return the current process's group id.
5948[clinic start generated code]*/
5949
Larry Hastings2f936352014-08-05 14:04:04 +10005950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005951os_getgid_impl(PyObject *module)
5952/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005953{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005954 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005955}
Larry Hastings2f936352014-08-05 14:04:04 +10005956#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005958
Berker Peksag39404992016-09-15 20:45:16 +03005959#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10005960/*[clinic input]
5961os.getpid
5962
5963Return the current process id.
5964[clinic start generated code]*/
5965
Larry Hastings2f936352014-08-05 14:04:04 +10005966static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005967os_getpid_impl(PyObject *module)
5968/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005969{
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005971}
Berker Peksag39404992016-09-15 20:45:16 +03005972#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005973
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005974#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005975
5976/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005977PyDoc_STRVAR(posix_getgrouplist__doc__,
5978"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5979Returns a list of groups to which a user belongs.\n\n\
5980 user: username to lookup\n\
5981 group: base group id of the user");
5982
5983static PyObject *
5984posix_getgrouplist(PyObject *self, PyObject *args)
5985{
5986#ifdef NGROUPS_MAX
5987#define MAX_GROUPS NGROUPS_MAX
5988#else
5989 /* defined to be 16 on Solaris7, so this should be a small number */
5990#define MAX_GROUPS 64
5991#endif
5992
5993 const char *user;
5994 int i, ngroups;
5995 PyObject *list;
5996#ifdef __APPLE__
5997 int *groups, basegid;
5998#else
5999 gid_t *groups, basegid;
6000#endif
6001 ngroups = MAX_GROUPS;
6002
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006003#ifdef __APPLE__
6004 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006005 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006006#else
6007 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6008 _Py_Gid_Converter, &basegid))
6009 return NULL;
6010#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006011
6012#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006013 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006014#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006015 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006016#endif
6017 if (groups == NULL)
6018 return PyErr_NoMemory();
6019
6020 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6021 PyMem_Del(groups);
6022 return posix_error();
6023 }
6024
6025 list = PyList_New(ngroups);
6026 if (list == NULL) {
6027 PyMem_Del(groups);
6028 return NULL;
6029 }
6030
6031 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006032#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006033 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006034#else
6035 PyObject *o = _PyLong_FromGid(groups[i]);
6036#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006037 if (o == NULL) {
6038 Py_DECREF(list);
6039 PyMem_Del(groups);
6040 return NULL;
6041 }
6042 PyList_SET_ITEM(list, i, o);
6043 }
6044
6045 PyMem_Del(groups);
6046
6047 return list;
6048}
Larry Hastings2f936352014-08-05 14:04:04 +10006049#endif /* HAVE_GETGROUPLIST */
6050
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006051
Fred Drakec9680921999-12-13 16:37:25 +00006052#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006053/*[clinic input]
6054os.getgroups
6055
6056Return list of supplemental group IDs for the process.
6057[clinic start generated code]*/
6058
Larry Hastings2f936352014-08-05 14:04:04 +10006059static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006060os_getgroups_impl(PyObject *module)
6061/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006062{
6063 PyObject *result = NULL;
6064
Fred Drakec9680921999-12-13 16:37:25 +00006065#ifdef NGROUPS_MAX
6066#define MAX_GROUPS NGROUPS_MAX
6067#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006069#define MAX_GROUPS 64
6070#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006072
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006073 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006074 * This is a helper variable to store the intermediate result when
6075 * that happens.
6076 *
6077 * To keep the code readable the OSX behaviour is unconditional,
6078 * according to the POSIX spec this should be safe on all unix-y
6079 * systems.
6080 */
6081 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006083
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006084#ifdef __APPLE__
6085 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6086 * there are more groups than can fit in grouplist. Therefore, on OS X
6087 * always first call getgroups with length 0 to get the actual number
6088 * of groups.
6089 */
6090 n = getgroups(0, NULL);
6091 if (n < 0) {
6092 return posix_error();
6093 } else if (n <= MAX_GROUPS) {
6094 /* groups will fit in existing array */
6095 alt_grouplist = grouplist;
6096 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006097 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006098 if (alt_grouplist == NULL) {
6099 errno = EINVAL;
6100 return posix_error();
6101 }
6102 }
6103
6104 n = getgroups(n, alt_grouplist);
6105 if (n == -1) {
6106 if (alt_grouplist != grouplist) {
6107 PyMem_Free(alt_grouplist);
6108 }
6109 return posix_error();
6110 }
6111#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006113 if (n < 0) {
6114 if (errno == EINVAL) {
6115 n = getgroups(0, NULL);
6116 if (n == -1) {
6117 return posix_error();
6118 }
6119 if (n == 0) {
6120 /* Avoid malloc(0) */
6121 alt_grouplist = grouplist;
6122 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006123 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006124 if (alt_grouplist == NULL) {
6125 errno = EINVAL;
6126 return posix_error();
6127 }
6128 n = getgroups(n, alt_grouplist);
6129 if (n == -1) {
6130 PyMem_Free(alt_grouplist);
6131 return posix_error();
6132 }
6133 }
6134 } else {
6135 return posix_error();
6136 }
6137 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006138#endif
6139
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006140 result = PyList_New(n);
6141 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006142 int i;
6143 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006144 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006146 Py_DECREF(result);
6147 result = NULL;
6148 break;
Fred Drakec9680921999-12-13 16:37:25 +00006149 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006151 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006152 }
6153
6154 if (alt_grouplist != grouplist) {
6155 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006156 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006157
Fred Drakec9680921999-12-13 16:37:25 +00006158 return result;
6159}
Larry Hastings2f936352014-08-05 14:04:04 +10006160#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006161
Antoine Pitroub7572f02009-12-02 20:46:48 +00006162#ifdef HAVE_INITGROUPS
6163PyDoc_STRVAR(posix_initgroups__doc__,
6164"initgroups(username, gid) -> None\n\n\
6165Call the system initgroups() to initialize the group access list with all of\n\
6166the groups of which the specified username is a member, plus the specified\n\
6167group id.");
6168
Larry Hastings2f936352014-08-05 14:04:04 +10006169/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006170static PyObject *
6171posix_initgroups(PyObject *self, PyObject *args)
6172{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006173 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006174 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006175 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006176#ifdef __APPLE__
6177 int gid;
6178#else
6179 gid_t gid;
6180#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006181
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006182#ifdef __APPLE__
6183 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6184 PyUnicode_FSConverter, &oname,
6185 &gid))
6186#else
6187 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6188 PyUnicode_FSConverter, &oname,
6189 _Py_Gid_Converter, &gid))
6190#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006191 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006192 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006193
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006194 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006195 Py_DECREF(oname);
6196 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006198
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 Py_INCREF(Py_None);
6200 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006201}
Larry Hastings2f936352014-08-05 14:04:04 +10006202#endif /* HAVE_INITGROUPS */
6203
Antoine Pitroub7572f02009-12-02 20:46:48 +00006204
Martin v. Löwis606edc12002-06-13 21:09:11 +00006205#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006206/*[clinic input]
6207os.getpgid
6208
6209 pid: pid_t
6210
6211Call the system call getpgid(), and return the result.
6212[clinic start generated code]*/
6213
Larry Hastings2f936352014-08-05 14:04:04 +10006214static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006215os_getpgid_impl(PyObject *module, pid_t pid)
6216/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006217{
6218 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 if (pgid < 0)
6220 return posix_error();
6221 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006222}
6223#endif /* HAVE_GETPGID */
6224
6225
Guido van Rossumb6775db1994-08-01 11:34:53 +00006226#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006227/*[clinic input]
6228os.getpgrp
6229
6230Return the current process group id.
6231[clinic start generated code]*/
6232
Larry Hastings2f936352014-08-05 14:04:04 +10006233static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006234os_getpgrp_impl(PyObject *module)
6235/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006236{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006237#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006239#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006241#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006242}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006243#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006245
Guido van Rossumb6775db1994-08-01 11:34:53 +00006246#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006247/*[clinic input]
6248os.setpgrp
6249
6250Make the current process the leader of its process group.
6251[clinic start generated code]*/
6252
Larry Hastings2f936352014-08-05 14:04:04 +10006253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006254os_setpgrp_impl(PyObject *module)
6255/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006256{
Guido van Rossum64933891994-10-20 21:56:42 +00006257#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006259#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006261#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 return posix_error();
6263 Py_INCREF(Py_None);
6264 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006266#endif /* HAVE_SETPGRP */
6267
Guido van Rossumad0ee831995-03-01 10:34:45 +00006268#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006269
6270#ifdef MS_WINDOWS
6271#include <tlhelp32.h>
6272
6273static PyObject*
6274win32_getppid()
6275{
6276 HANDLE snapshot;
6277 pid_t mypid;
6278 PyObject* result = NULL;
6279 BOOL have_record;
6280 PROCESSENTRY32 pe;
6281
6282 mypid = getpid(); /* This function never fails */
6283
6284 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6285 if (snapshot == INVALID_HANDLE_VALUE)
6286 return PyErr_SetFromWindowsErr(GetLastError());
6287
6288 pe.dwSize = sizeof(pe);
6289 have_record = Process32First(snapshot, &pe);
6290 while (have_record) {
6291 if (mypid == (pid_t)pe.th32ProcessID) {
6292 /* We could cache the ulong value in a static variable. */
6293 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6294 break;
6295 }
6296
6297 have_record = Process32Next(snapshot, &pe);
6298 }
6299
6300 /* If our loop exits and our pid was not found (result will be NULL)
6301 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6302 * error anyway, so let's raise it. */
6303 if (!result)
6304 result = PyErr_SetFromWindowsErr(GetLastError());
6305
6306 CloseHandle(snapshot);
6307
6308 return result;
6309}
6310#endif /*MS_WINDOWS*/
6311
Larry Hastings2f936352014-08-05 14:04:04 +10006312
6313/*[clinic input]
6314os.getppid
6315
6316Return the parent's process id.
6317
6318If the parent process has already exited, Windows machines will still
6319return its id; others systems will return the id of the 'init' process (1).
6320[clinic start generated code]*/
6321
Larry Hastings2f936352014-08-05 14:04:04 +10006322static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006323os_getppid_impl(PyObject *module)
6324/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006325{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006326#ifdef MS_WINDOWS
6327 return win32_getppid();
6328#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006329 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006330#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006331}
6332#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006334
Fred Drake12c6e2d1999-12-14 21:25:03 +00006335#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006336/*[clinic input]
6337os.getlogin
6338
6339Return the actual login name.
6340[clinic start generated code]*/
6341
Larry Hastings2f936352014-08-05 14:04:04 +10006342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006343os_getlogin_impl(PyObject *module)
6344/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006345{
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006347#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006348 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006349 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006350
6351 if (GetUserNameW(user_name, &num_chars)) {
6352 /* num_chars is the number of unicode chars plus null terminator */
6353 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006354 }
6355 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006356 result = PyErr_SetFromWindowsErr(GetLastError());
6357#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 char *name;
6359 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006360
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 errno = 0;
6362 name = getlogin();
6363 if (name == NULL) {
6364 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006365 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006366 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006367 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 }
6369 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006370 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006372#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006373 return result;
6374}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006375#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006376
Larry Hastings2f936352014-08-05 14:04:04 +10006377
Guido van Rossumad0ee831995-03-01 10:34:45 +00006378#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006379/*[clinic input]
6380os.getuid
6381
6382Return the current process's user id.
6383[clinic start generated code]*/
6384
Larry Hastings2f936352014-08-05 14:04:04 +10006385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006386os_getuid_impl(PyObject *module)
6387/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006388{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006389 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006390}
Larry Hastings2f936352014-08-05 14:04:04 +10006391#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006393
Brian Curtineb24d742010-04-12 17:16:38 +00006394#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006395#define HAVE_KILL
6396#endif /* MS_WINDOWS */
6397
6398#ifdef HAVE_KILL
6399/*[clinic input]
6400os.kill
6401
6402 pid: pid_t
6403 signal: Py_ssize_t
6404 /
6405
6406Kill a process with a signal.
6407[clinic start generated code]*/
6408
Larry Hastings2f936352014-08-05 14:04:04 +10006409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006410os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6411/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006412#ifndef MS_WINDOWS
6413{
6414 if (kill(pid, (int)signal) == -1)
6415 return posix_error();
6416 Py_RETURN_NONE;
6417}
6418#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006419{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006420 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006421 DWORD sig = (DWORD)signal;
6422 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006424
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 /* Console processes which share a common console can be sent CTRL+C or
6426 CTRL+BREAK events, provided they handle said events. */
6427 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006428 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 err = GetLastError();
6430 PyErr_SetFromWindowsErr(err);
6431 }
6432 else
6433 Py_RETURN_NONE;
6434 }
Brian Curtineb24d742010-04-12 17:16:38 +00006435
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6437 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006438 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 if (handle == NULL) {
6440 err = GetLastError();
6441 return PyErr_SetFromWindowsErr(err);
6442 }
Brian Curtineb24d742010-04-12 17:16:38 +00006443
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 if (TerminateProcess(handle, sig) == 0) {
6445 err = GetLastError();
6446 result = PyErr_SetFromWindowsErr(err);
6447 } else {
6448 Py_INCREF(Py_None);
6449 result = Py_None;
6450 }
Brian Curtineb24d742010-04-12 17:16:38 +00006451
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 CloseHandle(handle);
6453 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006454}
Larry Hastings2f936352014-08-05 14:04:04 +10006455#endif /* !MS_WINDOWS */
6456#endif /* HAVE_KILL */
6457
6458
6459#ifdef HAVE_KILLPG
6460/*[clinic input]
6461os.killpg
6462
6463 pgid: pid_t
6464 signal: int
6465 /
6466
6467Kill a process group with a signal.
6468[clinic start generated code]*/
6469
Larry Hastings2f936352014-08-05 14:04:04 +10006470static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006471os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6472/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006473{
6474 /* XXX some man pages make the `pgid` parameter an int, others
6475 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6476 take the same type. Moreover, pid_t is always at least as wide as
6477 int (else compilation of this module fails), which is safe. */
6478 if (killpg(pgid, signal) == -1)
6479 return posix_error();
6480 Py_RETURN_NONE;
6481}
6482#endif /* HAVE_KILLPG */
6483
Brian Curtineb24d742010-04-12 17:16:38 +00006484
Guido van Rossumc0125471996-06-28 18:55:32 +00006485#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006486#ifdef HAVE_SYS_LOCK_H
6487#include <sys/lock.h>
6488#endif
6489
Larry Hastings2f936352014-08-05 14:04:04 +10006490/*[clinic input]
6491os.plock
6492 op: int
6493 /
6494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006495Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006496[clinic start generated code]*/
6497
Larry Hastings2f936352014-08-05 14:04:04 +10006498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006499os_plock_impl(PyObject *module, int op)
6500/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006501{
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 if (plock(op) == -1)
6503 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006504 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006505}
Larry Hastings2f936352014-08-05 14:04:04 +10006506#endif /* HAVE_PLOCK */
6507
Guido van Rossumc0125471996-06-28 18:55:32 +00006508
Guido van Rossumb6775db1994-08-01 11:34:53 +00006509#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006510/*[clinic input]
6511os.setuid
6512
6513 uid: uid_t
6514 /
6515
6516Set the current process's user id.
6517[clinic start generated code]*/
6518
Larry Hastings2f936352014-08-05 14:04:04 +10006519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006520os_setuid_impl(PyObject *module, uid_t uid)
6521/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006522{
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 if (setuid(uid) < 0)
6524 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006525 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006526}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006527#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006528
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006529
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006530#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006531/*[clinic input]
6532os.seteuid
6533
6534 euid: uid_t
6535 /
6536
6537Set the current process's effective user id.
6538[clinic start generated code]*/
6539
Larry Hastings2f936352014-08-05 14:04:04 +10006540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006541os_seteuid_impl(PyObject *module, uid_t euid)
6542/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006543{
6544 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006546 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006547}
6548#endif /* HAVE_SETEUID */
6549
Larry Hastings2f936352014-08-05 14:04:04 +10006550
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006551#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006552/*[clinic input]
6553os.setegid
6554
6555 egid: gid_t
6556 /
6557
6558Set the current process's effective group id.
6559[clinic start generated code]*/
6560
Larry Hastings2f936352014-08-05 14:04:04 +10006561static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006562os_setegid_impl(PyObject *module, gid_t egid)
6563/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006564{
6565 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006567 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006568}
6569#endif /* HAVE_SETEGID */
6570
Larry Hastings2f936352014-08-05 14:04:04 +10006571
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006572#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006573/*[clinic input]
6574os.setreuid
6575
6576 ruid: uid_t
6577 euid: uid_t
6578 /
6579
6580Set the current process's real and effective user ids.
6581[clinic start generated code]*/
6582
Larry Hastings2f936352014-08-05 14:04:04 +10006583static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006584os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6585/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006586{
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 if (setreuid(ruid, euid) < 0) {
6588 return posix_error();
6589 } else {
6590 Py_INCREF(Py_None);
6591 return Py_None;
6592 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006593}
6594#endif /* HAVE_SETREUID */
6595
Larry Hastings2f936352014-08-05 14:04:04 +10006596
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006597#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006598/*[clinic input]
6599os.setregid
6600
6601 rgid: gid_t
6602 egid: gid_t
6603 /
6604
6605Set the current process's real and effective group ids.
6606[clinic start generated code]*/
6607
Larry Hastings2f936352014-08-05 14:04:04 +10006608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006609os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6610/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006611{
6612 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006614 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006615}
6616#endif /* HAVE_SETREGID */
6617
Larry Hastings2f936352014-08-05 14:04:04 +10006618
Guido van Rossumb6775db1994-08-01 11:34:53 +00006619#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006620/*[clinic input]
6621os.setgid
6622 gid: gid_t
6623 /
6624
6625Set the current process's group id.
6626[clinic start generated code]*/
6627
Larry Hastings2f936352014-08-05 14:04:04 +10006628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006629os_setgid_impl(PyObject *module, gid_t gid)
6630/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006631{
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 if (setgid(gid) < 0)
6633 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006634 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006635}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006636#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006637
Larry Hastings2f936352014-08-05 14:04:04 +10006638
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006639#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006640/*[clinic input]
6641os.setgroups
6642
6643 groups: object
6644 /
6645
6646Set the groups of the current process to list.
6647[clinic start generated code]*/
6648
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006649static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006650os_setgroups(PyObject *module, PyObject *groups)
6651/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006652{
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 int i, len;
6654 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006655
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 if (!PySequence_Check(groups)) {
6657 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6658 return NULL;
6659 }
6660 len = PySequence_Size(groups);
6661 if (len > MAX_GROUPS) {
6662 PyErr_SetString(PyExc_ValueError, "too many groups");
6663 return NULL;
6664 }
6665 for(i = 0; i < len; i++) {
6666 PyObject *elem;
6667 elem = PySequence_GetItem(groups, i);
6668 if (!elem)
6669 return NULL;
6670 if (!PyLong_Check(elem)) {
6671 PyErr_SetString(PyExc_TypeError,
6672 "groups must be integers");
6673 Py_DECREF(elem);
6674 return NULL;
6675 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006676 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006677 Py_DECREF(elem);
6678 return NULL;
6679 }
6680 }
6681 Py_DECREF(elem);
6682 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006683
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 if (setgroups(len, grouplist) < 0)
6685 return posix_error();
6686 Py_INCREF(Py_None);
6687 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006688}
6689#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006690
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006691#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6692static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006693wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006694{
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 PyObject *result;
6696 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006697 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006698
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 if (pid == -1)
6700 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006701
Victor Stinner8c62be82010-05-06 00:08:46 +00006702 if (struct_rusage == NULL) {
6703 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6704 if (m == NULL)
6705 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006706 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 Py_DECREF(m);
6708 if (struct_rusage == NULL)
6709 return NULL;
6710 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006711
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6713 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6714 if (!result)
6715 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006716
6717#ifndef doubletime
6718#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6719#endif
6720
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006722 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006723 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006724 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006725#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006726 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6727 SET_INT(result, 2, ru->ru_maxrss);
6728 SET_INT(result, 3, ru->ru_ixrss);
6729 SET_INT(result, 4, ru->ru_idrss);
6730 SET_INT(result, 5, ru->ru_isrss);
6731 SET_INT(result, 6, ru->ru_minflt);
6732 SET_INT(result, 7, ru->ru_majflt);
6733 SET_INT(result, 8, ru->ru_nswap);
6734 SET_INT(result, 9, ru->ru_inblock);
6735 SET_INT(result, 10, ru->ru_oublock);
6736 SET_INT(result, 11, ru->ru_msgsnd);
6737 SET_INT(result, 12, ru->ru_msgrcv);
6738 SET_INT(result, 13, ru->ru_nsignals);
6739 SET_INT(result, 14, ru->ru_nvcsw);
6740 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006741#undef SET_INT
6742
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 if (PyErr_Occurred()) {
6744 Py_DECREF(result);
6745 return NULL;
6746 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006747
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006749}
6750#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6751
Larry Hastings2f936352014-08-05 14:04:04 +10006752
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006753#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006754/*[clinic input]
6755os.wait3
6756
6757 options: int
6758Wait for completion of a child process.
6759
6760Returns a tuple of information about the child process:
6761 (pid, status, rusage)
6762[clinic start generated code]*/
6763
Larry Hastings2f936352014-08-05 14:04:04 +10006764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006765os_wait3_impl(PyObject *module, int options)
6766/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006767{
Victor Stinner8c62be82010-05-06 00:08:46 +00006768 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006770 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006771 WAIT_TYPE status;
6772 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006773
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006774 do {
6775 Py_BEGIN_ALLOW_THREADS
6776 pid = wait3(&status, options, &ru);
6777 Py_END_ALLOW_THREADS
6778 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6779 if (pid < 0)
6780 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006781
Victor Stinner4195b5c2012-02-08 23:03:19 +01006782 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006783}
6784#endif /* HAVE_WAIT3 */
6785
Larry Hastings2f936352014-08-05 14:04:04 +10006786
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006787#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006788/*[clinic input]
6789
6790os.wait4
6791
6792 pid: pid_t
6793 options: int
6794
6795Wait for completion of a specific child process.
6796
6797Returns a tuple of information about the child process:
6798 (pid, status, rusage)
6799[clinic start generated code]*/
6800
Larry Hastings2f936352014-08-05 14:04:04 +10006801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006802os_wait4_impl(PyObject *module, pid_t pid, int options)
6803/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006804{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006805 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006807 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 WAIT_TYPE status;
6809 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006810
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006811 do {
6812 Py_BEGIN_ALLOW_THREADS
6813 res = wait4(pid, &status, options, &ru);
6814 Py_END_ALLOW_THREADS
6815 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6816 if (res < 0)
6817 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006819 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006820}
6821#endif /* HAVE_WAIT4 */
6822
Larry Hastings2f936352014-08-05 14:04:04 +10006823
Ross Lagerwall7807c352011-03-17 20:20:30 +02006824#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006825/*[clinic input]
6826os.waitid
6827
6828 idtype: idtype_t
6829 Must be one of be P_PID, P_PGID or P_ALL.
6830 id: id_t
6831 The id to wait on.
6832 options: int
6833 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6834 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6835 /
6836
6837Returns the result of waiting for a process or processes.
6838
6839Returns either waitid_result or None if WNOHANG is specified and there are
6840no children in a waitable state.
6841[clinic start generated code]*/
6842
Larry Hastings2f936352014-08-05 14:04:04 +10006843static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006844os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6845/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006846{
6847 PyObject *result;
6848 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006849 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006850 siginfo_t si;
6851 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006852
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006853 do {
6854 Py_BEGIN_ALLOW_THREADS
6855 res = waitid(idtype, id, &si, options);
6856 Py_END_ALLOW_THREADS
6857 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6858 if (res < 0)
6859 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006860
6861 if (si.si_pid == 0)
6862 Py_RETURN_NONE;
6863
6864 result = PyStructSequence_New(&WaitidResultType);
6865 if (!result)
6866 return NULL;
6867
6868 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006869 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006870 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6871 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6872 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6873 if (PyErr_Occurred()) {
6874 Py_DECREF(result);
6875 return NULL;
6876 }
6877
6878 return result;
6879}
Larry Hastings2f936352014-08-05 14:04:04 +10006880#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006881
Larry Hastings2f936352014-08-05 14:04:04 +10006882
6883#if defined(HAVE_WAITPID)
6884/*[clinic input]
6885os.waitpid
6886 pid: pid_t
6887 options: int
6888 /
6889
6890Wait for completion of a given child process.
6891
6892Returns a tuple of information regarding the child process:
6893 (pid, status)
6894
6895The options argument is ignored on Windows.
6896[clinic start generated code]*/
6897
Larry Hastings2f936352014-08-05 14:04:04 +10006898static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006899os_waitpid_impl(PyObject *module, pid_t pid, int options)
6900/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006901{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006902 pid_t res;
6903 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 WAIT_TYPE status;
6905 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006906
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006907 do {
6908 Py_BEGIN_ALLOW_THREADS
6909 res = waitpid(pid, &status, options);
6910 Py_END_ALLOW_THREADS
6911 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6912 if (res < 0)
6913 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006914
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006915 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006916}
Tim Petersab034fa2002-02-01 11:27:43 +00006917#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006918/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006919/*[clinic input]
6920os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006921 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006922 options: int
6923 /
6924
6925Wait for completion of a given process.
6926
6927Returns a tuple of information regarding the process:
6928 (pid, status << 8)
6929
6930The options argument is ignored on Windows.
6931[clinic start generated code]*/
6932
Larry Hastings2f936352014-08-05 14:04:04 +10006933static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006934os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006935/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006936{
6937 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006938 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006939 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006940
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006941 do {
6942 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006943 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006944 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006945 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 Py_END_ALLOW_THREADS
6947 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006948 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006949 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006952 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006953}
Larry Hastings2f936352014-08-05 14:04:04 +10006954#endif
6955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006956
Guido van Rossumad0ee831995-03-01 10:34:45 +00006957#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006958/*[clinic input]
6959os.wait
6960
6961Wait for completion of a child process.
6962
6963Returns a tuple of information about the child process:
6964 (pid, status)
6965[clinic start generated code]*/
6966
Larry Hastings2f936352014-08-05 14:04:04 +10006967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006968os_wait_impl(PyObject *module)
6969/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006970{
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006972 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 WAIT_TYPE status;
6974 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006975
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006976 do {
6977 Py_BEGIN_ALLOW_THREADS
6978 pid = wait(&status);
6979 Py_END_ALLOW_THREADS
6980 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6981 if (pid < 0)
6982 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006983
Victor Stinner8c62be82010-05-06 00:08:46 +00006984 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006985}
Larry Hastings2f936352014-08-05 14:04:04 +10006986#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006988
Larry Hastings9cf065c2012-06-22 16:30:09 -07006989#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6990PyDoc_STRVAR(readlink__doc__,
6991"readlink(path, *, dir_fd=None) -> path\n\n\
6992Return a string representing the path to which the symbolic link points.\n\
6993\n\
6994If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6995 and path should be relative; path will then be relative to that directory.\n\
6996dir_fd may not be implemented on your platform.\n\
6997 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006998#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006999
Guido van Rossumb6775db1994-08-01 11:34:53 +00007000#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007001
Larry Hastings2f936352014-08-05 14:04:04 +10007002/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007003static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007004posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007005{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007006 path_t path;
7007 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007008 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007009 ssize_t length;
7010 PyObject *return_value = NULL;
7011 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007012
Larry Hastings9cf065c2012-06-22 16:30:09 -07007013 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007014 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007015 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7016 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007017 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007019
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007021#ifdef HAVE_READLINKAT
7022 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007023 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007024 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007025#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007026 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007027 Py_END_ALLOW_THREADS
7028
7029 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007030 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007031 goto exit;
7032 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007033 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007034
7035 if (PyUnicode_Check(path.object))
7036 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7037 else
7038 return_value = PyBytes_FromStringAndSize(buffer, length);
7039exit:
7040 path_cleanup(&path);
7041 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007042}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007043
Guido van Rossumb6775db1994-08-01 11:34:53 +00007044#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007045
Larry Hastings2f936352014-08-05 14:04:04 +10007046#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7047
7048static PyObject *
7049win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7050{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007051 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007052 DWORD n_bytes_returned;
7053 DWORD io_result;
7054 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007055 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007056 HANDLE reparse_point_handle;
7057
Martin Panter70214ad2016-08-04 02:38:59 +00007058 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7059 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007060 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007061
7062 static char *keywords[] = {"path", "dir_fd", NULL};
7063
7064 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7065 &po,
7066 dir_fd_unavailable, &dir_fd
7067 ))
7068 return NULL;
7069
7070 path = PyUnicode_AsUnicode(po);
7071 if (path == NULL)
7072 return NULL;
7073
7074 /* First get a handle to the reparse point */
7075 Py_BEGIN_ALLOW_THREADS
7076 reparse_point_handle = CreateFileW(
7077 path,
7078 0,
7079 0,
7080 0,
7081 OPEN_EXISTING,
7082 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7083 0);
7084 Py_END_ALLOW_THREADS
7085
7086 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7087 return win32_error_object("readlink", po);
7088
7089 Py_BEGIN_ALLOW_THREADS
7090 /* New call DeviceIoControl to read the reparse point */
7091 io_result = DeviceIoControl(
7092 reparse_point_handle,
7093 FSCTL_GET_REPARSE_POINT,
7094 0, 0, /* in buffer */
7095 target_buffer, sizeof(target_buffer),
7096 &n_bytes_returned,
7097 0 /* we're not using OVERLAPPED_IO */
7098 );
7099 CloseHandle(reparse_point_handle);
7100 Py_END_ALLOW_THREADS
7101
7102 if (io_result==0)
7103 return win32_error_object("readlink", po);
7104
7105 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7106 {
7107 PyErr_SetString(PyExc_ValueError,
7108 "not a symbolic link");
7109 return NULL;
7110 }
7111 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7112 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7113
7114 result = PyUnicode_FromWideChar(print_name,
7115 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7116 return result;
7117}
7118
7119#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7120
7121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007122
Larry Hastings9cf065c2012-06-22 16:30:09 -07007123#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124
7125#if defined(MS_WINDOWS)
7126
7127/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007128static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007129
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007131check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007132{
7133 HINSTANCE hKernel32;
7134 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007135 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136 return 1;
7137 hKernel32 = GetModuleHandleW(L"KERNEL32");
7138 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7139 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007140 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007141}
7142
Victor Stinner31b3b922013-06-05 01:49:17 +02007143/* Remove the last portion of the path */
7144static void
7145_dirnameW(WCHAR *path)
7146{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007147 WCHAR *ptr;
7148
7149 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007150 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007151 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007152 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007153 }
7154 *ptr = 0;
7155}
7156
Victor Stinner31b3b922013-06-05 01:49:17 +02007157/* Is this path absolute? */
7158static int
7159_is_absW(const WCHAR *path)
7160{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007161 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7162
7163}
7164
Victor Stinner31b3b922013-06-05 01:49:17 +02007165/* join root and rest with a backslash */
7166static void
7167_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7168{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007169 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007170
Victor Stinner31b3b922013-06-05 01:49:17 +02007171 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007172 wcscpy(dest_path, rest);
7173 return;
7174 }
7175
7176 root_len = wcslen(root);
7177
7178 wcscpy(dest_path, root);
7179 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007180 dest_path[root_len] = L'\\';
7181 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007182 }
7183 wcscpy(dest_path+root_len, rest);
7184}
7185
Victor Stinner31b3b922013-06-05 01:49:17 +02007186/* Return True if the path at src relative to dest is a directory */
7187static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007188_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007189{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007190 WIN32_FILE_ATTRIBUTE_DATA src_info;
7191 WCHAR dest_parent[MAX_PATH];
7192 WCHAR src_resolved[MAX_PATH] = L"";
7193
7194 /* dest_parent = os.path.dirname(dest) */
7195 wcscpy(dest_parent, dest);
7196 _dirnameW(dest_parent);
7197 /* src_resolved = os.path.join(dest_parent, src) */
7198 _joinW(src_resolved, dest_parent, src);
7199 return (
7200 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7201 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7202 );
7203}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007204#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007205
Larry Hastings2f936352014-08-05 14:04:04 +10007206
7207/*[clinic input]
7208os.symlink
7209 src: path_t
7210 dst: path_t
7211 target_is_directory: bool = False
7212 *
7213 dir_fd: dir_fd(requires='symlinkat')=None
7214
7215# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7216
7217Create a symbolic link pointing to src named dst.
7218
7219target_is_directory is required on Windows if the target is to be
7220 interpreted as a directory. (On Windows, symlink requires
7221 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7222 target_is_directory is ignored on non-Windows platforms.
7223
7224If dir_fd is not None, it should be a file descriptor open to a directory,
7225 and path should be relative; path will then be relative to that directory.
7226dir_fd may not be implemented on your platform.
7227 If it is unavailable, using it will raise a NotImplementedError.
7228
7229[clinic start generated code]*/
7230
Larry Hastings2f936352014-08-05 14:04:04 +10007231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007232os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007233 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007234/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007235{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007236#ifdef MS_WINDOWS
7237 DWORD result;
7238#else
7239 int result;
7240#endif
7241
Larry Hastings9cf065c2012-06-22 16:30:09 -07007242#ifdef MS_WINDOWS
7243 if (!check_CreateSymbolicLink()) {
7244 PyErr_SetString(PyExc_NotImplementedError,
7245 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007246 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007247 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007248 if (!win32_can_symlink) {
7249 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007250 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007251 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007252#endif
7253
Larry Hastings2f936352014-08-05 14:04:04 +10007254 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007255 PyErr_SetString(PyExc_ValueError,
7256 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007257 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007258 }
7259
7260#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007261
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007263 /* if src is a directory, ensure target_is_directory==1 */
7264 target_is_directory |= _check_dirW(src->wide, dst->wide);
7265 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7266 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007267 Py_END_ALLOW_THREADS
7268
Larry Hastings2f936352014-08-05 14:04:04 +10007269 if (!result)
7270 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007271
7272#else
7273
7274 Py_BEGIN_ALLOW_THREADS
7275#if HAVE_SYMLINKAT
7276 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007277 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007278 else
7279#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007280 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007281 Py_END_ALLOW_THREADS
7282
Larry Hastings2f936352014-08-05 14:04:04 +10007283 if (result)
7284 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007285#endif
7286
Larry Hastings2f936352014-08-05 14:04:04 +10007287 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007288}
7289#endif /* HAVE_SYMLINK */
7290
Larry Hastings9cf065c2012-06-22 16:30:09 -07007291
Brian Curtind40e6f72010-07-08 21:39:08 +00007292
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007293
Larry Hastings605a62d2012-06-24 04:33:36 -07007294static PyStructSequence_Field times_result_fields[] = {
7295 {"user", "user time"},
7296 {"system", "system time"},
7297 {"children_user", "user time of children"},
7298 {"children_system", "system time of children"},
7299 {"elapsed", "elapsed time since an arbitrary point in the past"},
7300 {NULL}
7301};
7302
7303PyDoc_STRVAR(times_result__doc__,
7304"times_result: Result from os.times().\n\n\
7305This object may be accessed either as a tuple of\n\
7306 (user, system, children_user, children_system, elapsed),\n\
7307or via the attributes user, system, children_user, children_system,\n\
7308and elapsed.\n\
7309\n\
7310See os.times for more information.");
7311
7312static PyStructSequence_Desc times_result_desc = {
7313 "times_result", /* name */
7314 times_result__doc__, /* doc */
7315 times_result_fields,
7316 5
7317};
7318
7319static PyTypeObject TimesResultType;
7320
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007321#ifdef MS_WINDOWS
7322#define HAVE_TIMES /* mandatory, for the method table */
7323#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007324
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007325#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007326
7327static PyObject *
7328build_times_result(double user, double system,
7329 double children_user, double children_system,
7330 double elapsed)
7331{
7332 PyObject *value = PyStructSequence_New(&TimesResultType);
7333 if (value == NULL)
7334 return NULL;
7335
7336#define SET(i, field) \
7337 { \
7338 PyObject *o = PyFloat_FromDouble(field); \
7339 if (!o) { \
7340 Py_DECREF(value); \
7341 return NULL; \
7342 } \
7343 PyStructSequence_SET_ITEM(value, i, o); \
7344 } \
7345
7346 SET(0, user);
7347 SET(1, system);
7348 SET(2, children_user);
7349 SET(3, children_system);
7350 SET(4, elapsed);
7351
7352#undef SET
7353
7354 return value;
7355}
7356
Larry Hastings605a62d2012-06-24 04:33:36 -07007357
Larry Hastings2f936352014-08-05 14:04:04 +10007358#ifndef MS_WINDOWS
7359#define NEED_TICKS_PER_SECOND
7360static long ticks_per_second = -1;
7361#endif /* MS_WINDOWS */
7362
7363/*[clinic input]
7364os.times
7365
7366Return a collection containing process timing information.
7367
7368The object returned behaves like a named tuple with these fields:
7369 (utime, stime, cutime, cstime, elapsed_time)
7370All fields are floating point numbers.
7371[clinic start generated code]*/
7372
Larry Hastings2f936352014-08-05 14:04:04 +10007373static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007374os_times_impl(PyObject *module)
7375/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007376#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007377{
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 FILETIME create, exit, kernel, user;
7379 HANDLE hProc;
7380 hProc = GetCurrentProcess();
7381 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7382 /* The fields of a FILETIME structure are the hi and lo part
7383 of a 64-bit value expressed in 100 nanosecond units.
7384 1e7 is one second in such units; 1e-7 the inverse.
7385 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7386 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007387 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007388 (double)(user.dwHighDateTime*429.4967296 +
7389 user.dwLowDateTime*1e-7),
7390 (double)(kernel.dwHighDateTime*429.4967296 +
7391 kernel.dwLowDateTime*1e-7),
7392 (double)0,
7393 (double)0,
7394 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007395}
Larry Hastings2f936352014-08-05 14:04:04 +10007396#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007397{
Larry Hastings2f936352014-08-05 14:04:04 +10007398
7399
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007400 struct tms t;
7401 clock_t c;
7402 errno = 0;
7403 c = times(&t);
7404 if (c == (clock_t) -1)
7405 return posix_error();
7406 return build_times_result(
7407 (double)t.tms_utime / ticks_per_second,
7408 (double)t.tms_stime / ticks_per_second,
7409 (double)t.tms_cutime / ticks_per_second,
7410 (double)t.tms_cstime / ticks_per_second,
7411 (double)c / ticks_per_second);
7412}
Larry Hastings2f936352014-08-05 14:04:04 +10007413#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007414#endif /* HAVE_TIMES */
7415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007416
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007417#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007418/*[clinic input]
7419os.getsid
7420
7421 pid: pid_t
7422 /
7423
7424Call the system call getsid(pid) and return the result.
7425[clinic start generated code]*/
7426
Larry Hastings2f936352014-08-05 14:04:04 +10007427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007428os_getsid_impl(PyObject *module, pid_t pid)
7429/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007430{
Victor Stinner8c62be82010-05-06 00:08:46 +00007431 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007432 sid = getsid(pid);
7433 if (sid < 0)
7434 return posix_error();
7435 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007436}
7437#endif /* HAVE_GETSID */
7438
7439
Guido van Rossumb6775db1994-08-01 11:34:53 +00007440#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007441/*[clinic input]
7442os.setsid
7443
7444Call the system call setsid().
7445[clinic start generated code]*/
7446
Larry Hastings2f936352014-08-05 14:04:04 +10007447static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007448os_setsid_impl(PyObject *module)
7449/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007450{
Victor Stinner8c62be82010-05-06 00:08:46 +00007451 if (setsid() < 0)
7452 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007453 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007454}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007455#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007456
Larry Hastings2f936352014-08-05 14:04:04 +10007457
Guido van Rossumb6775db1994-08-01 11:34:53 +00007458#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007459/*[clinic input]
7460os.setpgid
7461
7462 pid: pid_t
7463 pgrp: pid_t
7464 /
7465
7466Call the system call setpgid(pid, pgrp).
7467[clinic start generated code]*/
7468
Larry Hastings2f936352014-08-05 14:04:04 +10007469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007470os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7471/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007472{
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 if (setpgid(pid, pgrp) < 0)
7474 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007475 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007476}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007477#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007479
Guido van Rossumb6775db1994-08-01 11:34:53 +00007480#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007481/*[clinic input]
7482os.tcgetpgrp
7483
7484 fd: int
7485 /
7486
7487Return the process group associated with the terminal specified by fd.
7488[clinic start generated code]*/
7489
Larry Hastings2f936352014-08-05 14:04:04 +10007490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007491os_tcgetpgrp_impl(PyObject *module, int fd)
7492/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007493{
7494 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 if (pgid < 0)
7496 return posix_error();
7497 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007498}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007499#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007501
Guido van Rossumb6775db1994-08-01 11:34:53 +00007502#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007503/*[clinic input]
7504os.tcsetpgrp
7505
7506 fd: int
7507 pgid: pid_t
7508 /
7509
7510Set the process group associated with the terminal specified by fd.
7511[clinic start generated code]*/
7512
Larry Hastings2f936352014-08-05 14:04:04 +10007513static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007514os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7515/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007516{
Victor Stinner8c62be82010-05-06 00:08:46 +00007517 if (tcsetpgrp(fd, pgid) < 0)
7518 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007519 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007520}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007521#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007522
Guido van Rossum687dd131993-05-17 08:34:16 +00007523/* Functions acting on file descriptors */
7524
Victor Stinnerdaf45552013-08-28 00:53:59 +02007525#ifdef O_CLOEXEC
7526extern int _Py_open_cloexec_works;
7527#endif
7528
Larry Hastings2f936352014-08-05 14:04:04 +10007529
7530/*[clinic input]
7531os.open -> int
7532 path: path_t
7533 flags: int
7534 mode: int = 0o777
7535 *
7536 dir_fd: dir_fd(requires='openat') = None
7537
7538# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7539
7540Open a file for low level IO. Returns a file descriptor (integer).
7541
7542If dir_fd is not None, it should be a file descriptor open to a directory,
7543 and path should be relative; path will then be relative to that directory.
7544dir_fd may not be implemented on your platform.
7545 If it is unavailable, using it will raise a NotImplementedError.
7546[clinic start generated code]*/
7547
Larry Hastings2f936352014-08-05 14:04:04 +10007548static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007549os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7550/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007551{
7552 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007553 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007554
Victor Stinnerdaf45552013-08-28 00:53:59 +02007555#ifdef O_CLOEXEC
7556 int *atomic_flag_works = &_Py_open_cloexec_works;
7557#elif !defined(MS_WINDOWS)
7558 int *atomic_flag_works = NULL;
7559#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007560
Victor Stinnerdaf45552013-08-28 00:53:59 +02007561#ifdef MS_WINDOWS
7562 flags |= O_NOINHERIT;
7563#elif defined(O_CLOEXEC)
7564 flags |= O_CLOEXEC;
7565#endif
7566
Steve Dower8fc89802015-04-12 00:26:27 -04007567 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007568 do {
7569 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007570#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007571 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007572#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007573#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007574 if (dir_fd != DEFAULT_DIR_FD)
7575 fd = openat(dir_fd, path->narrow, flags, mode);
7576 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007577#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007578 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007579#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007580 Py_END_ALLOW_THREADS
7581 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007582 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007583
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007584 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007585 if (!async_err)
7586 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007587 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007588 }
7589
Victor Stinnerdaf45552013-08-28 00:53:59 +02007590#ifndef MS_WINDOWS
7591 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7592 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007593 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007594 }
7595#endif
7596
Larry Hastings2f936352014-08-05 14:04:04 +10007597 return fd;
7598}
7599
7600
7601/*[clinic input]
7602os.close
7603
7604 fd: int
7605
7606Close a file descriptor.
7607[clinic start generated code]*/
7608
Barry Warsaw53699e91996-12-10 23:23:01 +00007609static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007610os_close_impl(PyObject *module, int fd)
7611/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007612{
Larry Hastings2f936352014-08-05 14:04:04 +10007613 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007614 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7615 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7616 * for more details.
7617 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007619 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007620 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007621 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 Py_END_ALLOW_THREADS
7623 if (res < 0)
7624 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007625 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007626}
7627
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007628
Larry Hastings2f936352014-08-05 14:04:04 +10007629/*[clinic input]
7630os.closerange
7631
7632 fd_low: int
7633 fd_high: int
7634 /
7635
7636Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7637[clinic start generated code]*/
7638
Larry Hastings2f936352014-08-05 14:04:04 +10007639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007640os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7641/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007642{
7643 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007645 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007646 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007647 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007648 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007649 Py_END_ALLOW_THREADS
7650 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007651}
7652
7653
Larry Hastings2f936352014-08-05 14:04:04 +10007654/*[clinic input]
7655os.dup -> int
7656
7657 fd: int
7658 /
7659
7660Return a duplicate of a file descriptor.
7661[clinic start generated code]*/
7662
Larry Hastings2f936352014-08-05 14:04:04 +10007663static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007664os_dup_impl(PyObject *module, int fd)
7665/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007666{
7667 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007668}
7669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007670
Larry Hastings2f936352014-08-05 14:04:04 +10007671/*[clinic input]
7672os.dup2
7673 fd: int
7674 fd2: int
7675 inheritable: bool=True
7676
7677Duplicate file descriptor.
7678[clinic start generated code]*/
7679
Larry Hastings2f936352014-08-05 14:04:04 +10007680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007681os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7682/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007683{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007684 int res;
7685#if defined(HAVE_DUP3) && \
7686 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7687 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7688 int dup3_works = -1;
7689#endif
7690
Steve Dower940f33a2016-09-08 11:21:54 -07007691 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007693
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007694 /* dup2() can fail with EINTR if the target FD is already open, because it
7695 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7696 * upon close(), and therefore below.
7697 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007698#ifdef MS_WINDOWS
7699 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007700 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007702 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007703 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 if (res < 0)
7705 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007706
7707 /* Character files like console cannot be make non-inheritable */
7708 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7709 close(fd2);
7710 return NULL;
7711 }
7712
7713#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7714 Py_BEGIN_ALLOW_THREADS
7715 if (!inheritable)
7716 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7717 else
7718 res = dup2(fd, fd2);
7719 Py_END_ALLOW_THREADS
7720 if (res < 0)
7721 return posix_error();
7722
7723#else
7724
7725#ifdef HAVE_DUP3
7726 if (!inheritable && dup3_works != 0) {
7727 Py_BEGIN_ALLOW_THREADS
7728 res = dup3(fd, fd2, O_CLOEXEC);
7729 Py_END_ALLOW_THREADS
7730 if (res < 0) {
7731 if (dup3_works == -1)
7732 dup3_works = (errno != ENOSYS);
7733 if (dup3_works)
7734 return posix_error();
7735 }
7736 }
7737
7738 if (inheritable || dup3_works == 0)
7739 {
7740#endif
7741 Py_BEGIN_ALLOW_THREADS
7742 res = dup2(fd, fd2);
7743 Py_END_ALLOW_THREADS
7744 if (res < 0)
7745 return posix_error();
7746
7747 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7748 close(fd2);
7749 return NULL;
7750 }
7751#ifdef HAVE_DUP3
7752 }
7753#endif
7754
7755#endif
7756
Larry Hastings2f936352014-08-05 14:04:04 +10007757 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007758}
7759
Larry Hastings2f936352014-08-05 14:04:04 +10007760
Ross Lagerwall7807c352011-03-17 20:20:30 +02007761#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007762/*[clinic input]
7763os.lockf
7764
7765 fd: int
7766 An open file descriptor.
7767 command: int
7768 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7769 length: Py_off_t
7770 The number of bytes to lock, starting at the current position.
7771 /
7772
7773Apply, test or remove a POSIX lock on an open file descriptor.
7774
7775[clinic start generated code]*/
7776
Larry Hastings2f936352014-08-05 14:04:04 +10007777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007778os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7779/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007780{
7781 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007782
7783 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007784 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007785 Py_END_ALLOW_THREADS
7786
7787 if (res < 0)
7788 return posix_error();
7789
7790 Py_RETURN_NONE;
7791}
Larry Hastings2f936352014-08-05 14:04:04 +10007792#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007793
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007794
Larry Hastings2f936352014-08-05 14:04:04 +10007795/*[clinic input]
7796os.lseek -> Py_off_t
7797
7798 fd: int
7799 position: Py_off_t
7800 how: int
7801 /
7802
7803Set the position of a file descriptor. Return the new position.
7804
7805Return the new cursor position in number of bytes
7806relative to the beginning of the file.
7807[clinic start generated code]*/
7808
Larry Hastings2f936352014-08-05 14:04:04 +10007809static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007810os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7811/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007812{
7813 Py_off_t result;
7814
Guido van Rossum687dd131993-05-17 08:34:16 +00007815#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7817 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007818 case 0: how = SEEK_SET; break;
7819 case 1: how = SEEK_CUR; break;
7820 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007822#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007823
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007825 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007826
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007828 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007829#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007830 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007831#else
Larry Hastings2f936352014-08-05 14:04:04 +10007832 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007833#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007834 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007836 if (result < 0)
7837 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007838
Larry Hastings2f936352014-08-05 14:04:04 +10007839 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007840}
7841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007842
Larry Hastings2f936352014-08-05 14:04:04 +10007843/*[clinic input]
7844os.read
7845 fd: int
7846 length: Py_ssize_t
7847 /
7848
7849Read from a file descriptor. Returns a bytes object.
7850[clinic start generated code]*/
7851
Larry Hastings2f936352014-08-05 14:04:04 +10007852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007853os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7854/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007855{
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 Py_ssize_t n;
7857 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007858
7859 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 errno = EINVAL;
7861 return posix_error();
7862 }
Larry Hastings2f936352014-08-05 14:04:04 +10007863
7864#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007865 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007866 if (length > INT_MAX)
7867 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007868#endif
7869
7870 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007871 if (buffer == NULL)
7872 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007873
Victor Stinner66aab0c2015-03-19 22:53:20 +01007874 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7875 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007877 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 }
Larry Hastings2f936352014-08-05 14:04:04 +10007879
7880 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007882
Victor Stinner8c62be82010-05-06 00:08:46 +00007883 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007884}
7885
Ross Lagerwall7807c352011-03-17 20:20:30 +02007886#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7887 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007888static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007889iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7890{
7891 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007892 Py_ssize_t blen, total = 0;
7893
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007894 *iov = PyMem_New(struct iovec, cnt);
7895 if (*iov == NULL) {
7896 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007897 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007898 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007899
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007900 *buf = PyMem_New(Py_buffer, cnt);
7901 if (*buf == NULL) {
7902 PyMem_Del(*iov);
7903 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007904 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007905 }
7906
7907 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007908 PyObject *item = PySequence_GetItem(seq, i);
7909 if (item == NULL)
7910 goto fail;
7911 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7912 Py_DECREF(item);
7913 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007914 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007915 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007916 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007917 blen = (*buf)[i].len;
7918 (*iov)[i].iov_len = blen;
7919 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007920 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007921 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007922
7923fail:
7924 PyMem_Del(*iov);
7925 for (j = 0; j < i; j++) {
7926 PyBuffer_Release(&(*buf)[j]);
7927 }
7928 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007929 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007930}
7931
7932static void
7933iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7934{
7935 int i;
7936 PyMem_Del(iov);
7937 for (i = 0; i < cnt; i++) {
7938 PyBuffer_Release(&buf[i]);
7939 }
7940 PyMem_Del(buf);
7941}
7942#endif
7943
Larry Hastings2f936352014-08-05 14:04:04 +10007944
Ross Lagerwall7807c352011-03-17 20:20:30 +02007945#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007946/*[clinic input]
7947os.readv -> Py_ssize_t
7948
7949 fd: int
7950 buffers: object
7951 /
7952
7953Read from a file descriptor fd into an iterable of buffers.
7954
7955The buffers should be mutable buffers accepting bytes.
7956readv will transfer data into each buffer until it is full
7957and then move on to the next buffer in the sequence to hold
7958the rest of the data.
7959
7960readv returns the total number of bytes read,
7961which may be less than the total capacity of all the buffers.
7962[clinic start generated code]*/
7963
Larry Hastings2f936352014-08-05 14:04:04 +10007964static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007965os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7966/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007967{
7968 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007969 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007970 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007971 struct iovec *iov;
7972 Py_buffer *buf;
7973
Larry Hastings2f936352014-08-05 14:04:04 +10007974 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007975 PyErr_SetString(PyExc_TypeError,
7976 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007977 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007978 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007979
Larry Hastings2f936352014-08-05 14:04:04 +10007980 cnt = PySequence_Size(buffers);
7981
7982 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7983 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007984
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007985 do {
7986 Py_BEGIN_ALLOW_THREADS
7987 n = readv(fd, iov, cnt);
7988 Py_END_ALLOW_THREADS
7989 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007990
7991 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007992 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007993 if (!async_err)
7994 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007995 return -1;
7996 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007997
Larry Hastings2f936352014-08-05 14:04:04 +10007998 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007999}
Larry Hastings2f936352014-08-05 14:04:04 +10008000#endif /* HAVE_READV */
8001
Ross Lagerwall7807c352011-03-17 20:20:30 +02008002
8003#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008004/*[clinic input]
8005# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8006os.pread
8007
8008 fd: int
8009 length: int
8010 offset: Py_off_t
8011 /
8012
8013Read a number of bytes from a file descriptor starting at a particular offset.
8014
8015Read length bytes from file descriptor fd, starting at offset bytes from
8016the beginning of the file. The file offset remains unchanged.
8017[clinic start generated code]*/
8018
Larry Hastings2f936352014-08-05 14:04:04 +10008019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008020os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8021/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008022{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008024 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008025 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008026
Larry Hastings2f936352014-08-05 14:04:04 +10008027 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008028 errno = EINVAL;
8029 return posix_error();
8030 }
Larry Hastings2f936352014-08-05 14:04:04 +10008031 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008032 if (buffer == NULL)
8033 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008034
8035 do {
8036 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008037 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008038 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008039 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008040 Py_END_ALLOW_THREADS
8041 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8042
Ross Lagerwall7807c352011-03-17 20:20:30 +02008043 if (n < 0) {
8044 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008045 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008046 }
Larry Hastings2f936352014-08-05 14:04:04 +10008047 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008048 _PyBytes_Resize(&buffer, n);
8049 return buffer;
8050}
Larry Hastings2f936352014-08-05 14:04:04 +10008051#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008052
Larry Hastings2f936352014-08-05 14:04:04 +10008053
8054/*[clinic input]
8055os.write -> Py_ssize_t
8056
8057 fd: int
8058 data: Py_buffer
8059 /
8060
8061Write a bytes object to a file descriptor.
8062[clinic start generated code]*/
8063
Larry Hastings2f936352014-08-05 14:04:04 +10008064static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008065os_write_impl(PyObject *module, int fd, Py_buffer *data)
8066/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008067{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008068 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008069}
8070
8071#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008073"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008074sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008076Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077
Larry Hastings2f936352014-08-05 14:04:04 +10008078/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079static PyObject *
8080posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8081{
8082 int in, out;
8083 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008084 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008085 off_t offset;
8086
8087#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8088#ifndef __APPLE__
8089 Py_ssize_t len;
8090#endif
8091 PyObject *headers = NULL, *trailers = NULL;
8092 Py_buffer *hbuf, *tbuf;
8093 off_t sbytes;
8094 struct sf_hdtr sf;
8095 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008096 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008097 static char *keywords[] = {"out", "in",
8098 "offset", "count",
8099 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008100
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008101 sf.headers = NULL;
8102 sf.trailers = NULL;
8103
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104#ifdef __APPLE__
8105 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008106 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008107#else
8108 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008109 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008110#endif
8111 &headers, &trailers, &flags))
8112 return NULL;
8113 if (headers != NULL) {
8114 if (!PySequence_Check(headers)) {
8115 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008116 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008117 return NULL;
8118 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008119 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008120 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008121 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008122 (i = iov_setup(&(sf.headers), &hbuf,
8123 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008124 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008125#ifdef __APPLE__
8126 sbytes += i;
8127#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008128 }
8129 }
8130 if (trailers != NULL) {
8131 if (!PySequence_Check(trailers)) {
8132 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008133 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008134 return NULL;
8135 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008136 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008137 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008138 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008139 (i = iov_setup(&(sf.trailers), &tbuf,
8140 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008141 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008142#ifdef __APPLE__
8143 sbytes += i;
8144#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008145 }
8146 }
8147
Steve Dower8fc89802015-04-12 00:26:27 -04008148 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 do {
8150 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008151#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008152 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008153#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008154 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008155#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008156 Py_END_ALLOW_THREADS
8157 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008158 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008159
8160 if (sf.headers != NULL)
8161 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8162 if (sf.trailers != NULL)
8163 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8164
8165 if (ret < 0) {
8166 if ((errno == EAGAIN) || (errno == EBUSY)) {
8167 if (sbytes != 0) {
8168 // some data has been sent
8169 goto done;
8170 }
8171 else {
8172 // no data has been sent; upper application is supposed
8173 // to retry on EAGAIN or EBUSY
8174 return posix_error();
8175 }
8176 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008177 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008178 }
8179 goto done;
8180
8181done:
8182 #if !defined(HAVE_LARGEFILE_SUPPORT)
8183 return Py_BuildValue("l", sbytes);
8184 #else
8185 return Py_BuildValue("L", sbytes);
8186 #endif
8187
8188#else
8189 Py_ssize_t count;
8190 PyObject *offobj;
8191 static char *keywords[] = {"out", "in",
8192 "offset", "count", NULL};
8193 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8194 keywords, &out, &in, &offobj, &count))
8195 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008196#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008197 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008198 do {
8199 Py_BEGIN_ALLOW_THREADS
8200 ret = sendfile(out, in, NULL, count);
8201 Py_END_ALLOW_THREADS
8202 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008203 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008204 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008205 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008206 }
8207#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008208 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008209 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008210
8211 do {
8212 Py_BEGIN_ALLOW_THREADS
8213 ret = sendfile(out, in, &offset, count);
8214 Py_END_ALLOW_THREADS
8215 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008216 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008217 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008218 return Py_BuildValue("n", ret);
8219#endif
8220}
Larry Hastings2f936352014-08-05 14:04:04 +10008221#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008222
Larry Hastings2f936352014-08-05 14:04:04 +10008223
8224/*[clinic input]
8225os.fstat
8226
8227 fd : int
8228
8229Perform a stat system call on the given file descriptor.
8230
8231Like stat(), but for an open file descriptor.
8232Equivalent to os.stat(fd).
8233[clinic start generated code]*/
8234
Larry Hastings2f936352014-08-05 14:04:04 +10008235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008236os_fstat_impl(PyObject *module, int fd)
8237/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008238{
Victor Stinner8c62be82010-05-06 00:08:46 +00008239 STRUCT_STAT st;
8240 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008241 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008242
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008243 do {
8244 Py_BEGIN_ALLOW_THREADS
8245 res = FSTAT(fd, &st);
8246 Py_END_ALLOW_THREADS
8247 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008249#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008250 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008251#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008252 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008253#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008254 }
Tim Peters5aa91602002-01-30 05:46:57 +00008255
Victor Stinner4195b5c2012-02-08 23:03:19 +01008256 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008257}
8258
Larry Hastings2f936352014-08-05 14:04:04 +10008259
8260/*[clinic input]
8261os.isatty -> bool
8262 fd: int
8263 /
8264
8265Return True if the fd is connected to a terminal.
8266
8267Return True if the file descriptor is an open file descriptor
8268connected to the slave end of a terminal.
8269[clinic start generated code]*/
8270
Larry Hastings2f936352014-08-05 14:04:04 +10008271static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008272os_isatty_impl(PyObject *module, int fd)
8273/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008274{
Steve Dower8fc89802015-04-12 00:26:27 -04008275 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008276 _Py_BEGIN_SUPPRESS_IPH
8277 return_value = isatty(fd);
8278 _Py_END_SUPPRESS_IPH
8279 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008280}
8281
8282
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008283#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008284/*[clinic input]
8285os.pipe
8286
8287Create a pipe.
8288
8289Returns a tuple of two file descriptors:
8290 (read_fd, write_fd)
8291[clinic start generated code]*/
8292
Larry Hastings2f936352014-08-05 14:04:04 +10008293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008294os_pipe_impl(PyObject *module)
8295/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008296{
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008298#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008300 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008302#else
8303 int res;
8304#endif
8305
8306#ifdef MS_WINDOWS
8307 attr.nLength = sizeof(attr);
8308 attr.lpSecurityDescriptor = NULL;
8309 attr.bInheritHandle = FALSE;
8310
8311 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008312 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008313 ok = CreatePipe(&read, &write, &attr, 0);
8314 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008315 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8316 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008317 if (fds[0] == -1 || fds[1] == -1) {
8318 CloseHandle(read);
8319 CloseHandle(write);
8320 ok = 0;
8321 }
8322 }
Steve Dowerc3630612016-11-19 18:41:16 -08008323 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008324 Py_END_ALLOW_THREADS
8325
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008327 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008328#else
8329
8330#ifdef HAVE_PIPE2
8331 Py_BEGIN_ALLOW_THREADS
8332 res = pipe2(fds, O_CLOEXEC);
8333 Py_END_ALLOW_THREADS
8334
8335 if (res != 0 && errno == ENOSYS)
8336 {
8337#endif
8338 Py_BEGIN_ALLOW_THREADS
8339 res = pipe(fds);
8340 Py_END_ALLOW_THREADS
8341
8342 if (res == 0) {
8343 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8344 close(fds[0]);
8345 close(fds[1]);
8346 return NULL;
8347 }
8348 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8349 close(fds[0]);
8350 close(fds[1]);
8351 return NULL;
8352 }
8353 }
8354#ifdef HAVE_PIPE2
8355 }
8356#endif
8357
8358 if (res != 0)
8359 return PyErr_SetFromErrno(PyExc_OSError);
8360#endif /* !MS_WINDOWS */
8361 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008362}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008363#endif /* HAVE_PIPE */
8364
Larry Hastings2f936352014-08-05 14:04:04 +10008365
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008366#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008367/*[clinic input]
8368os.pipe2
8369
8370 flags: int
8371 /
8372
8373Create a pipe with flags set atomically.
8374
8375Returns a tuple of two file descriptors:
8376 (read_fd, write_fd)
8377
8378flags can be constructed by ORing together one or more of these values:
8379O_NONBLOCK, O_CLOEXEC.
8380[clinic start generated code]*/
8381
Larry Hastings2f936352014-08-05 14:04:04 +10008382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008383os_pipe2_impl(PyObject *module, int flags)
8384/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008385{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008386 int fds[2];
8387 int res;
8388
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008389 res = pipe2(fds, flags);
8390 if (res != 0)
8391 return posix_error();
8392 return Py_BuildValue("(ii)", fds[0], fds[1]);
8393}
8394#endif /* HAVE_PIPE2 */
8395
Larry Hastings2f936352014-08-05 14:04:04 +10008396
Ross Lagerwall7807c352011-03-17 20:20:30 +02008397#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008398/*[clinic input]
8399os.writev -> Py_ssize_t
8400 fd: int
8401 buffers: object
8402 /
8403
8404Iterate over buffers, and write the contents of each to a file descriptor.
8405
8406Returns the total number of bytes written.
8407buffers must be a sequence of bytes-like objects.
8408[clinic start generated code]*/
8409
Larry Hastings2f936352014-08-05 14:04:04 +10008410static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008411os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8412/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008413{
8414 int cnt;
8415 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008416 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008417 struct iovec *iov;
8418 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008419
8420 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008421 PyErr_SetString(PyExc_TypeError,
8422 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008423 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008424 }
Larry Hastings2f936352014-08-05 14:04:04 +10008425 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008426
Larry Hastings2f936352014-08-05 14:04:04 +10008427 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8428 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008429 }
8430
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008431 do {
8432 Py_BEGIN_ALLOW_THREADS
8433 result = writev(fd, iov, cnt);
8434 Py_END_ALLOW_THREADS
8435 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008436
8437 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008438 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008439 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008440
Georg Brandl306336b2012-06-24 12:55:33 +02008441 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008442}
Larry Hastings2f936352014-08-05 14:04:04 +10008443#endif /* HAVE_WRITEV */
8444
8445
8446#ifdef HAVE_PWRITE
8447/*[clinic input]
8448os.pwrite -> Py_ssize_t
8449
8450 fd: int
8451 buffer: Py_buffer
8452 offset: Py_off_t
8453 /
8454
8455Write bytes to a file descriptor starting at a particular offset.
8456
8457Write buffer to fd, starting at offset bytes from the beginning of
8458the file. Returns the number of bytes writte. Does not change the
8459current file offset.
8460[clinic start generated code]*/
8461
Larry Hastings2f936352014-08-05 14:04:04 +10008462static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008463os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8464/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008465{
8466 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008467 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008468
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008469 do {
8470 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008471 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008472 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008473 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008474 Py_END_ALLOW_THREADS
8475 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008476
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008477 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008478 posix_error();
8479 return size;
8480}
8481#endif /* HAVE_PWRITE */
8482
8483
8484#ifdef HAVE_MKFIFO
8485/*[clinic input]
8486os.mkfifo
8487
8488 path: path_t
8489 mode: int=0o666
8490 *
8491 dir_fd: dir_fd(requires='mkfifoat')=None
8492
8493Create a "fifo" (a POSIX named pipe).
8494
8495If dir_fd is not None, it should be a file descriptor open to a directory,
8496 and path should be relative; path will then be relative to that directory.
8497dir_fd may not be implemented on your platform.
8498 If it is unavailable, using it will raise a NotImplementedError.
8499[clinic start generated code]*/
8500
Larry Hastings2f936352014-08-05 14:04:04 +10008501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008502os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8503/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008504{
8505 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008506 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008507
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008508 do {
8509 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008510#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008511 if (dir_fd != DEFAULT_DIR_FD)
8512 result = mkfifoat(dir_fd, path->narrow, mode);
8513 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008514#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008515 result = mkfifo(path->narrow, mode);
8516 Py_END_ALLOW_THREADS
8517 } while (result != 0 && errno == EINTR &&
8518 !(async_err = PyErr_CheckSignals()));
8519 if (result != 0)
8520 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008521
8522 Py_RETURN_NONE;
8523}
8524#endif /* HAVE_MKFIFO */
8525
8526
8527#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8528/*[clinic input]
8529os.mknod
8530
8531 path: path_t
8532 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008533 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008534 *
8535 dir_fd: dir_fd(requires='mknodat')=None
8536
8537Create a node in the file system.
8538
8539Create a node in the file system (file, device special file or named pipe)
8540at path. mode specifies both the permissions to use and the
8541type of node to be created, being combined (bitwise OR) with one of
8542S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8543device defines the newly created device special file (probably using
8544os.makedev()). Otherwise device is ignored.
8545
8546If dir_fd is not None, it should be a file descriptor open to a directory,
8547 and path should be relative; path will then be relative to that directory.
8548dir_fd may not be implemented on your platform.
8549 If it is unavailable, using it will raise a NotImplementedError.
8550[clinic start generated code]*/
8551
Larry Hastings2f936352014-08-05 14:04:04 +10008552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008553os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008554 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008555/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008556{
8557 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008558 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008559
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008560 do {
8561 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008562#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008563 if (dir_fd != DEFAULT_DIR_FD)
8564 result = mknodat(dir_fd, path->narrow, mode, device);
8565 else
Larry Hastings2f936352014-08-05 14:04:04 +10008566#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008567 result = mknod(path->narrow, mode, device);
8568 Py_END_ALLOW_THREADS
8569 } while (result != 0 && errno == EINTR &&
8570 !(async_err = PyErr_CheckSignals()));
8571 if (result != 0)
8572 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008573
8574 Py_RETURN_NONE;
8575}
8576#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8577
8578
8579#ifdef HAVE_DEVICE_MACROS
8580/*[clinic input]
8581os.major -> unsigned_int
8582
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008583 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008584 /
8585
8586Extracts a device major number from a raw device number.
8587[clinic start generated code]*/
8588
Larry Hastings2f936352014-08-05 14:04:04 +10008589static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008590os_major_impl(PyObject *module, dev_t device)
8591/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008592{
8593 return major(device);
8594}
8595
8596
8597/*[clinic input]
8598os.minor -> unsigned_int
8599
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008600 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008601 /
8602
8603Extracts a device minor number from a raw device number.
8604[clinic start generated code]*/
8605
Larry Hastings2f936352014-08-05 14:04:04 +10008606static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008607os_minor_impl(PyObject *module, dev_t device)
8608/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008609{
8610 return minor(device);
8611}
8612
8613
8614/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008615os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008616
8617 major: int
8618 minor: int
8619 /
8620
8621Composes a raw device number from the major and minor device numbers.
8622[clinic start generated code]*/
8623
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008624static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008625os_makedev_impl(PyObject *module, int major, int minor)
8626/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008627{
8628 return makedev(major, minor);
8629}
8630#endif /* HAVE_DEVICE_MACROS */
8631
8632
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008633#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008634/*[clinic input]
8635os.ftruncate
8636
8637 fd: int
8638 length: Py_off_t
8639 /
8640
8641Truncate a file, specified by file descriptor, to a specific length.
8642[clinic start generated code]*/
8643
Larry Hastings2f936352014-08-05 14:04:04 +10008644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008645os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8646/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008647{
8648 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008649 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008650
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008651 do {
8652 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008653 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008654#ifdef MS_WINDOWS
8655 result = _chsize_s(fd, length);
8656#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008657 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008658#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008659 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008660 Py_END_ALLOW_THREADS
8661 } while (result != 0 && errno == EINTR &&
8662 !(async_err = PyErr_CheckSignals()));
8663 if (result != 0)
8664 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008665 Py_RETURN_NONE;
8666}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008667#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008668
8669
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008670#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008671/*[clinic input]
8672os.truncate
8673 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8674 length: Py_off_t
8675
8676Truncate a file, specified by path, to a specific length.
8677
8678On some platforms, path may also be specified as an open file descriptor.
8679 If this functionality is unavailable, using it raises an exception.
8680[clinic start generated code]*/
8681
Larry Hastings2f936352014-08-05 14:04:04 +10008682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008683os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8684/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008685{
8686 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008687#ifdef MS_WINDOWS
8688 int fd;
8689#endif
8690
8691 if (path->fd != -1)
8692 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008693
8694 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008695 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008696#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008697 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008698 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008699 result = -1;
8700 else {
8701 result = _chsize_s(fd, length);
8702 close(fd);
8703 if (result < 0)
8704 errno = result;
8705 }
8706#else
8707 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008708#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008709 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008710 Py_END_ALLOW_THREADS
8711 if (result < 0)
8712 return path_error(path);
8713
8714 Py_RETURN_NONE;
8715}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008716#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008717
Ross Lagerwall7807c352011-03-17 20:20:30 +02008718
Victor Stinnerd6b17692014-09-30 12:20:05 +02008719/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8720 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8721 defined, which is the case in Python on AIX. AIX bug report:
8722 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8723#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8724# define POSIX_FADVISE_AIX_BUG
8725#endif
8726
Victor Stinnerec39e262014-09-30 12:35:58 +02008727
Victor Stinnerd6b17692014-09-30 12:20:05 +02008728#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008729/*[clinic input]
8730os.posix_fallocate
8731
8732 fd: int
8733 offset: Py_off_t
8734 length: Py_off_t
8735 /
8736
8737Ensure a file has allocated at least a particular number of bytes on disk.
8738
8739Ensure that the file specified by fd encompasses a range of bytes
8740starting at offset bytes from the beginning and continuing for length bytes.
8741[clinic start generated code]*/
8742
Larry Hastings2f936352014-08-05 14:04:04 +10008743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008744os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008745 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008746/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008747{
8748 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008749 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008750
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008751 do {
8752 Py_BEGIN_ALLOW_THREADS
8753 result = posix_fallocate(fd, offset, length);
8754 Py_END_ALLOW_THREADS
8755 } while (result != 0 && errno == EINTR &&
8756 !(async_err = PyErr_CheckSignals()));
8757 if (result != 0)
8758 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008759 Py_RETURN_NONE;
8760}
Victor Stinnerec39e262014-09-30 12:35:58 +02008761#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008762
Ross Lagerwall7807c352011-03-17 20:20:30 +02008763
Victor Stinnerd6b17692014-09-30 12:20:05 +02008764#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008765/*[clinic input]
8766os.posix_fadvise
8767
8768 fd: int
8769 offset: Py_off_t
8770 length: Py_off_t
8771 advice: int
8772 /
8773
8774Announce an intention to access data in a specific pattern.
8775
8776Announce an intention to access data in a specific pattern, thus allowing
8777the kernel to make optimizations.
8778The advice applies to the region of the file specified by fd starting at
8779offset and continuing for length bytes.
8780advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8781POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8782POSIX_FADV_DONTNEED.
8783[clinic start generated code]*/
8784
Larry Hastings2f936352014-08-05 14:04:04 +10008785static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008786os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008787 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008788/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008789{
8790 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008791 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008792
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008793 do {
8794 Py_BEGIN_ALLOW_THREADS
8795 result = posix_fadvise(fd, offset, length, advice);
8796 Py_END_ALLOW_THREADS
8797 } while (result != 0 && errno == EINTR &&
8798 !(async_err = PyErr_CheckSignals()));
8799 if (result != 0)
8800 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008801 Py_RETURN_NONE;
8802}
Victor Stinnerec39e262014-09-30 12:35:58 +02008803#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008804
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008805#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008806
Fred Drake762e2061999-08-26 17:23:54 +00008807/* Save putenv() parameters as values here, so we can collect them when they
8808 * get re-set with another call for the same key. */
8809static PyObject *posix_putenv_garbage;
8810
Larry Hastings2f936352014-08-05 14:04:04 +10008811static void
8812posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008813{
Larry Hastings2f936352014-08-05 14:04:04 +10008814 /* Install the first arg and newstr in posix_putenv_garbage;
8815 * this will cause previous value to be collected. This has to
8816 * happen after the real putenv() call because the old value
8817 * was still accessible until then. */
8818 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8819 /* really not much we can do; just leak */
8820 PyErr_Clear();
8821 else
8822 Py_DECREF(value);
8823}
8824
8825
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008826#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008827/*[clinic input]
8828os.putenv
8829
8830 name: unicode
8831 value: unicode
8832 /
8833
8834Change or add an environment variable.
8835[clinic start generated code]*/
8836
Larry Hastings2f936352014-08-05 14:04:04 +10008837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008838os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8839/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008840{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008841 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008842
8843 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8844 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008845 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008846 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008847 }
Larry Hastings2f936352014-08-05 14:04:04 +10008848 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008849 PyErr_Format(PyExc_ValueError,
8850 "the environment variable is longer than %u characters",
8851 _MAX_ENV);
8852 goto error;
8853 }
8854
Larry Hastings2f936352014-08-05 14:04:04 +10008855 env = PyUnicode_AsUnicode(unicode);
8856 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008857 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008858 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008860 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008862
Larry Hastings2f936352014-08-05 14:04:04 +10008863 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008864 Py_RETURN_NONE;
8865
8866error:
Larry Hastings2f936352014-08-05 14:04:04 +10008867 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008868 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008869}
Larry Hastings2f936352014-08-05 14:04:04 +10008870#else /* MS_WINDOWS */
8871/*[clinic input]
8872os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008873
Larry Hastings2f936352014-08-05 14:04:04 +10008874 name: FSConverter
8875 value: FSConverter
8876 /
8877
8878Change or add an environment variable.
8879[clinic start generated code]*/
8880
Larry Hastings2f936352014-08-05 14:04:04 +10008881static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008882os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8883/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008884{
8885 PyObject *bytes = NULL;
8886 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008887 const char *name_string = PyBytes_AsString(name);
8888 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008889
8890 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8891 if (bytes == NULL) {
8892 PyErr_NoMemory();
8893 return NULL;
8894 }
8895
8896 env = PyBytes_AS_STRING(bytes);
8897 if (putenv(env)) {
8898 Py_DECREF(bytes);
8899 return posix_error();
8900 }
8901
8902 posix_putenv_garbage_setitem(name, bytes);
8903 Py_RETURN_NONE;
8904}
8905#endif /* MS_WINDOWS */
8906#endif /* HAVE_PUTENV */
8907
8908
8909#ifdef HAVE_UNSETENV
8910/*[clinic input]
8911os.unsetenv
8912 name: FSConverter
8913 /
8914
8915Delete an environment variable.
8916[clinic start generated code]*/
8917
Larry Hastings2f936352014-08-05 14:04:04 +10008918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008919os_unsetenv_impl(PyObject *module, PyObject *name)
8920/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008921{
Victor Stinner984890f2011-11-24 13:53:38 +01008922#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008923 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008924#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008925
Victor Stinner984890f2011-11-24 13:53:38 +01008926#ifdef HAVE_BROKEN_UNSETENV
8927 unsetenv(PyBytes_AS_STRING(name));
8928#else
Victor Stinner65170952011-11-22 22:16:17 +01008929 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008930 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008931 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008932#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008933
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 /* Remove the key from posix_putenv_garbage;
8935 * this will cause it to be collected. This has to
8936 * happen after the real unsetenv() call because the
8937 * old value was still accessible until then.
8938 */
Victor Stinner65170952011-11-22 22:16:17 +01008939 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 /* really not much we can do; just leak */
8941 PyErr_Clear();
8942 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008943 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008944}
Larry Hastings2f936352014-08-05 14:04:04 +10008945#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008946
Larry Hastings2f936352014-08-05 14:04:04 +10008947
8948/*[clinic input]
8949os.strerror
8950
8951 code: int
8952 /
8953
8954Translate an error code to a message string.
8955[clinic start generated code]*/
8956
Larry Hastings2f936352014-08-05 14:04:04 +10008957static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008958os_strerror_impl(PyObject *module, int code)
8959/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008960{
8961 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 if (message == NULL) {
8963 PyErr_SetString(PyExc_ValueError,
8964 "strerror() argument out of range");
8965 return NULL;
8966 }
Victor Stinner1b579672011-12-17 05:47:23 +01008967 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008968}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008969
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008970
Guido van Rossumc9641791998-08-04 15:26:23 +00008971#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008972#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008973/*[clinic input]
8974os.WCOREDUMP -> bool
8975
8976 status: int
8977 /
8978
8979Return True if the process returning status was dumped to a core file.
8980[clinic start generated code]*/
8981
Larry Hastings2f936352014-08-05 14:04:04 +10008982static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008983os_WCOREDUMP_impl(PyObject *module, int status)
8984/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008985{
8986 WAIT_TYPE wait_status;
8987 WAIT_STATUS_INT(wait_status) = status;
8988 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008989}
8990#endif /* WCOREDUMP */
8991
Larry Hastings2f936352014-08-05 14:04:04 +10008992
Fred Drake106c1a02002-04-23 15:58:02 +00008993#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008994/*[clinic input]
8995os.WIFCONTINUED -> bool
8996
8997 status: int
8998
8999Return True if a particular process was continued from a job control stop.
9000
9001Return True if the process returning status was continued from a
9002job control stop.
9003[clinic start generated code]*/
9004
Larry Hastings2f936352014-08-05 14:04:04 +10009005static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009006os_WIFCONTINUED_impl(PyObject *module, int status)
9007/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009008{
9009 WAIT_TYPE wait_status;
9010 WAIT_STATUS_INT(wait_status) = status;
9011 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009012}
9013#endif /* WIFCONTINUED */
9014
Larry Hastings2f936352014-08-05 14:04:04 +10009015
Guido van Rossumc9641791998-08-04 15:26:23 +00009016#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009017/*[clinic input]
9018os.WIFSTOPPED -> bool
9019
9020 status: int
9021
9022Return True if the process returning status was stopped.
9023[clinic start generated code]*/
9024
Larry Hastings2f936352014-08-05 14:04:04 +10009025static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009026os_WIFSTOPPED_impl(PyObject *module, int status)
9027/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009028{
9029 WAIT_TYPE wait_status;
9030 WAIT_STATUS_INT(wait_status) = status;
9031 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009032}
9033#endif /* WIFSTOPPED */
9034
Larry Hastings2f936352014-08-05 14:04:04 +10009035
Guido van Rossumc9641791998-08-04 15:26:23 +00009036#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009037/*[clinic input]
9038os.WIFSIGNALED -> bool
9039
9040 status: int
9041
9042Return True if the process returning status was terminated by a signal.
9043[clinic start generated code]*/
9044
Larry Hastings2f936352014-08-05 14:04:04 +10009045static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009046os_WIFSIGNALED_impl(PyObject *module, int status)
9047/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009048{
9049 WAIT_TYPE wait_status;
9050 WAIT_STATUS_INT(wait_status) = status;
9051 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009052}
9053#endif /* WIFSIGNALED */
9054
Larry Hastings2f936352014-08-05 14:04:04 +10009055
Guido van Rossumc9641791998-08-04 15:26:23 +00009056#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009057/*[clinic input]
9058os.WIFEXITED -> bool
9059
9060 status: int
9061
9062Return True if the process returning status exited via the exit() system call.
9063[clinic start generated code]*/
9064
Larry Hastings2f936352014-08-05 14:04:04 +10009065static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009066os_WIFEXITED_impl(PyObject *module, int status)
9067/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009068{
9069 WAIT_TYPE wait_status;
9070 WAIT_STATUS_INT(wait_status) = status;
9071 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009072}
9073#endif /* WIFEXITED */
9074
Larry Hastings2f936352014-08-05 14:04:04 +10009075
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009076#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009077/*[clinic input]
9078os.WEXITSTATUS -> int
9079
9080 status: int
9081
9082Return the process return code from status.
9083[clinic start generated code]*/
9084
Larry Hastings2f936352014-08-05 14:04:04 +10009085static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009086os_WEXITSTATUS_impl(PyObject *module, int status)
9087/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009088{
9089 WAIT_TYPE wait_status;
9090 WAIT_STATUS_INT(wait_status) = status;
9091 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009092}
9093#endif /* WEXITSTATUS */
9094
Larry Hastings2f936352014-08-05 14:04:04 +10009095
Guido van Rossumc9641791998-08-04 15:26:23 +00009096#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009097/*[clinic input]
9098os.WTERMSIG -> int
9099
9100 status: int
9101
9102Return the signal that terminated the process that provided the status value.
9103[clinic start generated code]*/
9104
Larry Hastings2f936352014-08-05 14:04:04 +10009105static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009106os_WTERMSIG_impl(PyObject *module, int status)
9107/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009108{
9109 WAIT_TYPE wait_status;
9110 WAIT_STATUS_INT(wait_status) = status;
9111 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009112}
9113#endif /* WTERMSIG */
9114
Larry Hastings2f936352014-08-05 14:04:04 +10009115
Guido van Rossumc9641791998-08-04 15:26:23 +00009116#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009117/*[clinic input]
9118os.WSTOPSIG -> int
9119
9120 status: int
9121
9122Return the signal that stopped the process that provided the status value.
9123[clinic start generated code]*/
9124
Larry Hastings2f936352014-08-05 14:04:04 +10009125static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009126os_WSTOPSIG_impl(PyObject *module, int status)
9127/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009128{
9129 WAIT_TYPE wait_status;
9130 WAIT_STATUS_INT(wait_status) = status;
9131 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009132}
9133#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009134#endif /* HAVE_SYS_WAIT_H */
9135
9136
Thomas Wouters477c8d52006-05-27 19:21:47 +00009137#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009138#ifdef _SCO_DS
9139/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9140 needed definitions in sys/statvfs.h */
9141#define _SVID3
9142#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009143#include <sys/statvfs.h>
9144
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009145static PyObject*
9146_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9148 if (v == NULL)
9149 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009150
9151#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9153 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9154 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9155 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9156 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9157 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9158 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9159 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9160 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9161 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009162#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009163 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9164 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9165 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009166 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009168 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009169 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009170 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009172 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009173 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009174 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009175 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009176 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9178 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009179#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009180 if (PyErr_Occurred()) {
9181 Py_DECREF(v);
9182 return NULL;
9183 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009184
Victor Stinner8c62be82010-05-06 00:08:46 +00009185 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009186}
9187
Larry Hastings2f936352014-08-05 14:04:04 +10009188
9189/*[clinic input]
9190os.fstatvfs
9191 fd: int
9192 /
9193
9194Perform an fstatvfs system call on the given fd.
9195
9196Equivalent to statvfs(fd).
9197[clinic start generated code]*/
9198
Larry Hastings2f936352014-08-05 14:04:04 +10009199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009200os_fstatvfs_impl(PyObject *module, int fd)
9201/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009202{
9203 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009204 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009206
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009207 do {
9208 Py_BEGIN_ALLOW_THREADS
9209 result = fstatvfs(fd, &st);
9210 Py_END_ALLOW_THREADS
9211 } while (result != 0 && errno == EINTR &&
9212 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009213 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009214 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009215
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009217}
Larry Hastings2f936352014-08-05 14:04:04 +10009218#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009219
9220
Thomas Wouters477c8d52006-05-27 19:21:47 +00009221#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009222#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009223/*[clinic input]
9224os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009225
Larry Hastings2f936352014-08-05 14:04:04 +10009226 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9227
9228Perform a statvfs system call on the given path.
9229
9230path may always be specified as a string.
9231On some platforms, path may also be specified as an open file descriptor.
9232 If this functionality is unavailable, using it raises an exception.
9233[clinic start generated code]*/
9234
Larry Hastings2f936352014-08-05 14:04:04 +10009235static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009236os_statvfs_impl(PyObject *module, path_t *path)
9237/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009238{
9239 int result;
9240 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009241
9242 Py_BEGIN_ALLOW_THREADS
9243#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009244 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009245#ifdef __APPLE__
9246 /* handle weak-linking on Mac OS X 10.3 */
9247 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009248 fd_specified("statvfs", path->fd);
9249 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009250 }
9251#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009252 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009253 }
9254 else
9255#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009256 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009257 Py_END_ALLOW_THREADS
9258
9259 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009260 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009261 }
9262
Larry Hastings2f936352014-08-05 14:04:04 +10009263 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009264}
Larry Hastings2f936352014-08-05 14:04:04 +10009265#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9266
Guido van Rossum94f6f721999-01-06 18:42:14 +00009267
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009268#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009269/*[clinic input]
9270os._getdiskusage
9271
9272 path: Py_UNICODE
9273
9274Return disk usage statistics about the given path as a (total, free) tuple.
9275[clinic start generated code]*/
9276
Larry Hastings2f936352014-08-05 14:04:04 +10009277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009278os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9279/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009280{
9281 BOOL retval;
9282 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009283
9284 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009285 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009286 Py_END_ALLOW_THREADS
9287 if (retval == 0)
9288 return PyErr_SetFromWindowsErr(0);
9289
9290 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9291}
Larry Hastings2f936352014-08-05 14:04:04 +10009292#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009293
9294
Fred Drakec9680921999-12-13 16:37:25 +00009295/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9296 * It maps strings representing configuration variable names to
9297 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009298 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009299 * rarely-used constants. There are three separate tables that use
9300 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009301 *
9302 * This code is always included, even if none of the interfaces that
9303 * need it are included. The #if hackery needed to avoid it would be
9304 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009305 */
9306struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009307 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009308 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009309};
9310
Fred Drake12c6e2d1999-12-14 21:25:03 +00009311static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009312conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009313 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009314{
Christian Heimes217cfd12007-12-02 14:31:20 +00009315 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009316 int value = _PyLong_AsInt(arg);
9317 if (value == -1 && PyErr_Occurred())
9318 return 0;
9319 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009320 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009321 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009322 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009323 /* look up the value in the table using a binary search */
9324 size_t lo = 0;
9325 size_t mid;
9326 size_t hi = tablesize;
9327 int cmp;
9328 const char *confname;
9329 if (!PyUnicode_Check(arg)) {
9330 PyErr_SetString(PyExc_TypeError,
9331 "configuration names must be strings or integers");
9332 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009334 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009335 if (confname == NULL)
9336 return 0;
9337 while (lo < hi) {
9338 mid = (lo + hi) / 2;
9339 cmp = strcmp(confname, table[mid].name);
9340 if (cmp < 0)
9341 hi = mid;
9342 else if (cmp > 0)
9343 lo = mid + 1;
9344 else {
9345 *valuep = table[mid].value;
9346 return 1;
9347 }
9348 }
9349 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9350 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009352}
9353
9354
9355#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9356static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009357#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009359#endif
9360#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009362#endif
Fred Drakec9680921999-12-13 16:37:25 +00009363#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
9405#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009408#ifdef _PC_ACL_ENABLED
9409 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9410#endif
9411#ifdef _PC_MIN_HOLE_SIZE
9412 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9413#endif
9414#ifdef _PC_ALLOC_SIZE_MIN
9415 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9416#endif
9417#ifdef _PC_REC_INCR_XFER_SIZE
9418 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9419#endif
9420#ifdef _PC_REC_MAX_XFER_SIZE
9421 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9422#endif
9423#ifdef _PC_REC_MIN_XFER_SIZE
9424 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9425#endif
9426#ifdef _PC_REC_XFER_ALIGN
9427 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9428#endif
9429#ifdef _PC_SYMLINK_MAX
9430 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9431#endif
9432#ifdef _PC_XATTR_ENABLED
9433 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9434#endif
9435#ifdef _PC_XATTR_EXISTS
9436 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9437#endif
9438#ifdef _PC_TIMESTAMP_RESOLUTION
9439 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9440#endif
Fred Drakec9680921999-12-13 16:37:25 +00009441};
9442
Fred Drakec9680921999-12-13 16:37:25 +00009443static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009444conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009445{
9446 return conv_confname(arg, valuep, posix_constants_pathconf,
9447 sizeof(posix_constants_pathconf)
9448 / sizeof(struct constdef));
9449}
9450#endif
9451
Larry Hastings2f936352014-08-05 14:04:04 +10009452
Fred Drakec9680921999-12-13 16:37:25 +00009453#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009454/*[clinic input]
9455os.fpathconf -> long
9456
9457 fd: int
9458 name: path_confname
9459 /
9460
9461Return the configuration limit name for the file descriptor fd.
9462
9463If there is no limit, return -1.
9464[clinic start generated code]*/
9465
Larry Hastings2f936352014-08-05 14:04:04 +10009466static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009467os_fpathconf_impl(PyObject *module, int fd, int name)
9468/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009469{
9470 long limit;
9471
9472 errno = 0;
9473 limit = fpathconf(fd, name);
9474 if (limit == -1 && errno != 0)
9475 posix_error();
9476
9477 return limit;
9478}
9479#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009480
9481
9482#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009483/*[clinic input]
9484os.pathconf -> long
9485 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9486 name: path_confname
9487
9488Return the configuration limit name for the file or directory path.
9489
9490If there is no limit, return -1.
9491On some platforms, path may also be specified as an open file descriptor.
9492 If this functionality is unavailable, using it raises an exception.
9493[clinic start generated code]*/
9494
Larry Hastings2f936352014-08-05 14:04:04 +10009495static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009496os_pathconf_impl(PyObject *module, path_t *path, int name)
9497/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009498{
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009500
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009502#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009503 if (path->fd != -1)
9504 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009505 else
9506#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009507 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 if (limit == -1 && errno != 0) {
9509 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009510 /* could be a path or name problem */
9511 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009512 else
Larry Hastings2f936352014-08-05 14:04:04 +10009513 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 }
Larry Hastings2f936352014-08-05 14:04:04 +10009515
9516 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009517}
Larry Hastings2f936352014-08-05 14:04:04 +10009518#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009519
9520#ifdef HAVE_CONFSTR
9521static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009522#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009524#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009525#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009527#endif
9528#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009530#endif
Fred Draked86ed291999-12-15 15:34:33 +00009531#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009533#endif
9534#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
9537#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
9540#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009542#endif
Fred Drakec9680921999-12-13 16:37:25 +00009543#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
Fred Draked86ed291999-12-15 15:34:33 +00009567#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009569#endif
Fred Drakec9680921999-12-13 16:37:25 +00009570#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
Fred Draked86ed291999-12-15 15:34:33 +00009573#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009575#endif
9576#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009578#endif
9579#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009581#endif
9582#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009584#endif
Fred Drakec9680921999-12-13 16:37:25 +00009585#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
Fred Draked86ed291999-12-15 15:34:33 +00009633#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009635#endif
9636#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009638#endif
9639#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
9642#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009644#endif
9645#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
9648#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
9654#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
9657#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
9663#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009665#endif
9666#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009668#endif
9669#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
Fred Drakec9680921999-12-13 16:37:25 +00009672};
9673
9674static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009675conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009676{
9677 return conv_confname(arg, valuep, posix_constants_confstr,
9678 sizeof(posix_constants_confstr)
9679 / sizeof(struct constdef));
9680}
9681
Larry Hastings2f936352014-08-05 14:04:04 +10009682
9683/*[clinic input]
9684os.confstr
9685
9686 name: confstr_confname
9687 /
9688
9689Return a string-valued system configuration variable.
9690[clinic start generated code]*/
9691
Larry Hastings2f936352014-08-05 14:04:04 +10009692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009693os_confstr_impl(PyObject *module, int name)
9694/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009695{
9696 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009697 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009698 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009699
Victor Stinnercb043522010-09-10 23:49:04 +00009700 errno = 0;
9701 len = confstr(name, buffer, sizeof(buffer));
9702 if (len == 0) {
9703 if (errno) {
9704 posix_error();
9705 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009706 }
9707 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009708 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009709 }
9710 }
Victor Stinnercb043522010-09-10 23:49:04 +00009711
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009712 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009713 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009714 char *buf = PyMem_Malloc(len);
9715 if (buf == NULL)
9716 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009717 len2 = confstr(name, buf, len);
9718 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009719 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009720 PyMem_Free(buf);
9721 }
9722 else
9723 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009724 return result;
9725}
Larry Hastings2f936352014-08-05 14:04:04 +10009726#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009727
9728
9729#ifdef HAVE_SYSCONF
9730static struct constdef posix_constants_sysconf[] = {
9731#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
Fred Draked86ed291999-12-15 15:34:33 +00009761#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
9764#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009766#endif
Fred Drakec9680921999-12-13 16:37:25 +00009767#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
Fred Drakec9680921999-12-13 16:37:25 +00009770#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
Fred Draked86ed291999-12-15 15:34:33 +00009785#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009787#endif
Fred Drakec9680921999-12-13 16:37:25 +00009788#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
Fred Draked86ed291999-12-15 15:34:33 +00009803#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009805#endif
Fred Drakec9680921999-12-13 16:37:25 +00009806#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
Fred Draked86ed291999-12-15 15:34:33 +00009875#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009877#endif
Fred Drakec9680921999-12-13 16:37:25 +00009878#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
Fred Draked86ed291999-12-15 15:34:33 +00009887#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009889#endif
Fred Drakec9680921999-12-13 16:37:25 +00009890#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
Fred Draked86ed291999-12-15 15:34:33 +00009893#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009895#endif
9896#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009898#endif
Fred Drakec9680921999-12-13 16:37:25 +00009899#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
Fred Draked86ed291999-12-15 15:34:33 +00009911#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009913#endif
Fred Drakec9680921999-12-13 16:37:25 +00009914#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
Fred Draked86ed291999-12-15 15:34:33 +00009935#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009937#endif
Fred Drakec9680921999-12-13 16:37:25 +00009938#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
Fred Draked86ed291999-12-15 15:34:33 +00009944#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009946#endif
Fred Drakec9680921999-12-13 16:37:25 +00009947#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
Fred Draked86ed291999-12-15 15:34:33 +00009974#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009976#endif
9977#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009979#endif
Fred Drakec9680921999-12-13 16:37:25 +00009980#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
Fred Draked86ed291999-12-15 15:34:33 +000010085#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010087#endif
Fred Drakec9680921999-12-13 16:37:25 +000010088#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223};
10224
10225static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010226conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010227{
10228 return conv_confname(arg, valuep, posix_constants_sysconf,
10229 sizeof(posix_constants_sysconf)
10230 / sizeof(struct constdef));
10231}
10232
Larry Hastings2f936352014-08-05 14:04:04 +100010233
10234/*[clinic input]
10235os.sysconf -> long
10236 name: sysconf_confname
10237 /
10238
10239Return an integer-valued system configuration variable.
10240[clinic start generated code]*/
10241
Larry Hastings2f936352014-08-05 14:04:04 +100010242static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010243os_sysconf_impl(PyObject *module, int name)
10244/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010245{
10246 long value;
10247
10248 errno = 0;
10249 value = sysconf(name);
10250 if (value == -1 && errno != 0)
10251 posix_error();
10252 return value;
10253}
10254#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010255
10256
Fred Drakebec628d1999-12-15 18:31:10 +000010257/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010258 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010259 * the exported dictionaries that are used to publish information about the
10260 * names available on the host platform.
10261 *
10262 * Sorting the table at runtime ensures that the table is properly ordered
10263 * when used, even for platforms we're not able to test on. It also makes
10264 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010265 */
Fred Drakebec628d1999-12-15 18:31:10 +000010266
10267static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010268cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010269{
10270 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010272 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010274
10275 return strcmp(c1->name, c2->name);
10276}
10277
10278static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010279setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010280 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010281{
Fred Drakebec628d1999-12-15 18:31:10 +000010282 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010283 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010284
10285 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10286 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010287 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010289
Barry Warsaw3155db32000-04-13 15:20:40 +000010290 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 PyObject *o = PyLong_FromLong(table[i].value);
10292 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10293 Py_XDECREF(o);
10294 Py_DECREF(d);
10295 return -1;
10296 }
10297 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010298 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010299 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010300}
10301
Fred Drakebec628d1999-12-15 18:31:10 +000010302/* Return -1 on failure, 0 on success. */
10303static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010304setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010305{
10306#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010307 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010308 sizeof(posix_constants_pathconf)
10309 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010310 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010311 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010312#endif
10313#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010314 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010315 sizeof(posix_constants_confstr)
10316 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010317 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010318 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010319#endif
10320#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010321 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010322 sizeof(posix_constants_sysconf)
10323 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010324 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010325 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010326#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010327 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010328}
Fred Draked86ed291999-12-15 15:34:33 +000010329
10330
Larry Hastings2f936352014-08-05 14:04:04 +100010331/*[clinic input]
10332os.abort
10333
10334Abort the interpreter immediately.
10335
10336This function 'dumps core' or otherwise fails in the hardest way possible
10337on the hosting operating system. This function never returns.
10338[clinic start generated code]*/
10339
Larry Hastings2f936352014-08-05 14:04:04 +100010340static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010341os_abort_impl(PyObject *module)
10342/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010343{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010344 abort();
10345 /*NOTREACHED*/
10346 Py_FatalError("abort() called from Python code didn't abort!");
10347 return NULL;
10348}
Fred Drakebec628d1999-12-15 18:31:10 +000010349
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010350#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010351/* Grab ShellExecute dynamically from shell32 */
10352static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010353static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10354 LPCWSTR, INT);
10355static int
10356check_ShellExecute()
10357{
10358 HINSTANCE hShell32;
10359
10360 /* only recheck */
10361 if (-1 == has_ShellExecute) {
10362 Py_BEGIN_ALLOW_THREADS
10363 hShell32 = LoadLibraryW(L"SHELL32");
10364 Py_END_ALLOW_THREADS
10365 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010366 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10367 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010368 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010369 } else {
10370 has_ShellExecute = 0;
10371 }
10372 }
10373 return has_ShellExecute;
10374}
10375
10376
Steve Dowercc16be82016-09-08 10:35:16 -070010377/*[clinic input]
10378os.startfile
10379 filepath: path_t
10380 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010381
Steve Dowercc16be82016-09-08 10:35:16 -070010382startfile(filepath [, operation])
10383
10384Start a file with its associated application.
10385
10386When "operation" is not specified or "open", this acts like
10387double-clicking the file in Explorer, or giving the file name as an
10388argument to the DOS "start" command: the file is opened with whatever
10389application (if any) its extension is associated.
10390When another "operation" is given, it specifies what should be done with
10391the file. A typical operation is "print".
10392
10393startfile returns as soon as the associated application is launched.
10394There is no option to wait for the application to close, and no way
10395to retrieve the application's exit status.
10396
10397The filepath is relative to the current directory. If you want to use
10398an absolute path, make sure the first character is not a slash ("/");
10399the underlying Win32 ShellExecute function doesn't work if it is.
10400[clinic start generated code]*/
10401
10402static PyObject *
10403os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10404/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10405{
10406 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010407
10408 if(!check_ShellExecute()) {
10409 /* If the OS doesn't have ShellExecute, return a
10410 NotImplementedError. */
10411 return PyErr_Format(PyExc_NotImplementedError,
10412 "startfile not available on this platform");
10413 }
10414
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010416 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010417 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 Py_END_ALLOW_THREADS
10419
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010421 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010422 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 }
Steve Dowercc16be82016-09-08 10:35:16 -070010424 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010425}
Larry Hastings2f936352014-08-05 14:04:04 +100010426#endif /* MS_WINDOWS */
10427
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010428
Martin v. Löwis438b5342002-12-27 10:16:42 +000010429#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010430/*[clinic input]
10431os.getloadavg
10432
10433Return average recent system load information.
10434
10435Return the number of processes in the system run queue averaged over
10436the last 1, 5, and 15 minutes as a tuple of three floats.
10437Raises OSError if the load average was unobtainable.
10438[clinic start generated code]*/
10439
Larry Hastings2f936352014-08-05 14:04:04 +100010440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010441os_getloadavg_impl(PyObject *module)
10442/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010443{
10444 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010445 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010446 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10447 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010448 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010449 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010450}
Larry Hastings2f936352014-08-05 14:04:04 +100010451#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010452
Larry Hastings2f936352014-08-05 14:04:04 +100010453
10454/*[clinic input]
10455os.device_encoding
10456 fd: int
10457
10458Return a string describing the encoding of a terminal's file descriptor.
10459
10460The file descriptor must be attached to a terminal.
10461If the device is not a terminal, return None.
10462[clinic start generated code]*/
10463
Larry Hastings2f936352014-08-05 14:04:04 +100010464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010465os_device_encoding_impl(PyObject *module, int fd)
10466/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010467{
Brett Cannonefb00c02012-02-29 18:31:31 -050010468 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010469}
10470
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010471
Larry Hastings2f936352014-08-05 14:04:04 +100010472#ifdef HAVE_SETRESUID
10473/*[clinic input]
10474os.setresuid
10475
10476 ruid: uid_t
10477 euid: uid_t
10478 suid: uid_t
10479 /
10480
10481Set the current process's real, effective, and saved user ids.
10482[clinic start generated code]*/
10483
Larry Hastings2f936352014-08-05 14:04:04 +100010484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010485os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10486/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010487{
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 if (setresuid(ruid, euid, suid) < 0)
10489 return posix_error();
10490 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010491}
Larry Hastings2f936352014-08-05 14:04:04 +100010492#endif /* HAVE_SETRESUID */
10493
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010494
10495#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010496/*[clinic input]
10497os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010498
Larry Hastings2f936352014-08-05 14:04:04 +100010499 rgid: gid_t
10500 egid: gid_t
10501 sgid: gid_t
10502 /
10503
10504Set the current process's real, effective, and saved group ids.
10505[clinic start generated code]*/
10506
Larry Hastings2f936352014-08-05 14:04:04 +100010507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010508os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10509/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010510{
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 if (setresgid(rgid, egid, sgid) < 0)
10512 return posix_error();
10513 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010514}
Larry Hastings2f936352014-08-05 14:04:04 +100010515#endif /* HAVE_SETRESGID */
10516
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010517
10518#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010519/*[clinic input]
10520os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010521
Larry Hastings2f936352014-08-05 14:04:04 +100010522Return a tuple of the current process's real, effective, and saved user ids.
10523[clinic start generated code]*/
10524
Larry Hastings2f936352014-08-05 14:04:04 +100010525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010526os_getresuid_impl(PyObject *module)
10527/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010528{
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 if (getresuid(&ruid, &euid, &suid) < 0)
10531 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010532 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10533 _PyLong_FromUid(euid),
10534 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010535}
Larry Hastings2f936352014-08-05 14:04:04 +100010536#endif /* HAVE_GETRESUID */
10537
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010538
10539#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010540/*[clinic input]
10541os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010542
Larry Hastings2f936352014-08-05 14:04:04 +100010543Return a tuple of the current process's real, effective, and saved group ids.
10544[clinic start generated code]*/
10545
Larry Hastings2f936352014-08-05 14:04:04 +100010546static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010547os_getresgid_impl(PyObject *module)
10548/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010549{
10550 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 if (getresgid(&rgid, &egid, &sgid) < 0)
10552 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010553 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10554 _PyLong_FromGid(egid),
10555 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010556}
Larry Hastings2f936352014-08-05 14:04:04 +100010557#endif /* HAVE_GETRESGID */
10558
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010559
Benjamin Peterson9428d532011-09-14 11:45:52 -040010560#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010561/*[clinic input]
10562os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010563
Larry Hastings2f936352014-08-05 14:04:04 +100010564 path: path_t(allow_fd=True)
10565 attribute: path_t
10566 *
10567 follow_symlinks: bool = True
10568
10569Return the value of extended attribute attribute on path.
10570
10571path may be either a string or an open file descriptor.
10572If follow_symlinks is False, and the last element of the path is a symbolic
10573 link, getxattr will examine the symbolic link itself instead of the file
10574 the link points to.
10575
10576[clinic start generated code]*/
10577
Larry Hastings2f936352014-08-05 14:04:04 +100010578static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010579os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010580 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010581/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010582{
10583 Py_ssize_t i;
10584 PyObject *buffer = NULL;
10585
10586 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10587 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010588
Larry Hastings9cf065c2012-06-22 16:30:09 -070010589 for (i = 0; ; i++) {
10590 void *ptr;
10591 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010592 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010593 Py_ssize_t buffer_size = buffer_sizes[i];
10594 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010595 path_error(path);
10596 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010597 }
10598 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10599 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010600 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010601 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010602
Larry Hastings9cf065c2012-06-22 16:30:09 -070010603 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010604 if (path->fd >= 0)
10605 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010607 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 else
Larry Hastings2f936352014-08-05 14:04:04 +100010609 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010611
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 if (result < 0) {
10613 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 if (errno == ERANGE)
10615 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010616 path_error(path);
10617 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010618 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010619
Larry Hastings9cf065c2012-06-22 16:30:09 -070010620 if (result != buffer_size) {
10621 /* Can only shrink. */
10622 _PyBytes_Resize(&buffer, result);
10623 }
10624 break;
10625 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626
Larry Hastings9cf065c2012-06-22 16:30:09 -070010627 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010628}
10629
Larry Hastings2f936352014-08-05 14:04:04 +100010630
10631/*[clinic input]
10632os.setxattr
10633
10634 path: path_t(allow_fd=True)
10635 attribute: path_t
10636 value: Py_buffer
10637 flags: int = 0
10638 *
10639 follow_symlinks: bool = True
10640
10641Set extended attribute attribute on path to value.
10642
10643path may be either a string or an open file descriptor.
10644If follow_symlinks is False, and the last element of the path is a symbolic
10645 link, setxattr will modify the symbolic link itself instead of the file
10646 the link points to.
10647
10648[clinic start generated code]*/
10649
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010651os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010652 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010653/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010654{
Larry Hastings2f936352014-08-05 14:04:04 +100010655 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656
Larry Hastings2f936352014-08-05 14:04:04 +100010657 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010658 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010659
Benjamin Peterson799bd802011-08-31 22:15:17 -040010660 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010661 if (path->fd > -1)
10662 result = fsetxattr(path->fd, attribute->narrow,
10663 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010664 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010665 result = setxattr(path->narrow, attribute->narrow,
10666 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010667 else
Larry Hastings2f936352014-08-05 14:04:04 +100010668 result = lsetxattr(path->narrow, attribute->narrow,
10669 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010671
Larry Hastings9cf065c2012-06-22 16:30:09 -070010672 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010673 path_error(path);
10674 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010675 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010676
Larry Hastings2f936352014-08-05 14:04:04 +100010677 Py_RETURN_NONE;
10678}
10679
10680
10681/*[clinic input]
10682os.removexattr
10683
10684 path: path_t(allow_fd=True)
10685 attribute: path_t
10686 *
10687 follow_symlinks: bool = True
10688
10689Remove extended attribute attribute on path.
10690
10691path may be either a string or an open file descriptor.
10692If follow_symlinks is False, and the last element of the path is a symbolic
10693 link, removexattr will modify the symbolic link itself instead of the file
10694 the link points to.
10695
10696[clinic start generated code]*/
10697
Larry Hastings2f936352014-08-05 14:04:04 +100010698static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010699os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010700 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010701/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010702{
10703 ssize_t result;
10704
10705 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10706 return NULL;
10707
10708 Py_BEGIN_ALLOW_THREADS;
10709 if (path->fd > -1)
10710 result = fremovexattr(path->fd, attribute->narrow);
10711 else if (follow_symlinks)
10712 result = removexattr(path->narrow, attribute->narrow);
10713 else
10714 result = lremovexattr(path->narrow, attribute->narrow);
10715 Py_END_ALLOW_THREADS;
10716
10717 if (result) {
10718 return path_error(path);
10719 }
10720
10721 Py_RETURN_NONE;
10722}
10723
10724
10725/*[clinic input]
10726os.listxattr
10727
10728 path: path_t(allow_fd=True, nullable=True) = None
10729 *
10730 follow_symlinks: bool = True
10731
10732Return a list of extended attributes on path.
10733
10734path may be either None, a string, or an open file descriptor.
10735if path is None, listxattr will examine the current directory.
10736If follow_symlinks is False, and the last element of the path is a symbolic
10737 link, listxattr will examine the symbolic link itself instead of the file
10738 the link points to.
10739[clinic start generated code]*/
10740
Larry Hastings2f936352014-08-05 14:04:04 +100010741static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010742os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10743/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010744{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745 Py_ssize_t i;
10746 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010747 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010748 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010749
Larry Hastings2f936352014-08-05 14:04:04 +100010750 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010752
Larry Hastings2f936352014-08-05 14:04:04 +100010753 name = path->narrow ? path->narrow : ".";
10754
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010756 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010758 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010759 Py_ssize_t buffer_size = buffer_sizes[i];
10760 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010761 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010762 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763 break;
10764 }
10765 buffer = PyMem_MALLOC(buffer_size);
10766 if (!buffer) {
10767 PyErr_NoMemory();
10768 break;
10769 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010770
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010772 if (path->fd > -1)
10773 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 else if (follow_symlinks)
10775 length = listxattr(name, buffer, buffer_size);
10776 else
10777 length = llistxattr(name, buffer, buffer_size);
10778 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010779
Larry Hastings9cf065c2012-06-22 16:30:09 -070010780 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010781 if (errno == ERANGE) {
10782 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010783 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010784 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010785 }
Larry Hastings2f936352014-08-05 14:04:04 +100010786 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010787 break;
10788 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010789
Larry Hastings9cf065c2012-06-22 16:30:09 -070010790 result = PyList_New(0);
10791 if (!result) {
10792 goto exit;
10793 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010794
Larry Hastings9cf065c2012-06-22 16:30:09 -070010795 end = buffer + length;
10796 for (trace = start = buffer; trace != end; trace++) {
10797 if (!*trace) {
10798 int error;
10799 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10800 trace - start);
10801 if (!attribute) {
10802 Py_DECREF(result);
10803 result = NULL;
10804 goto exit;
10805 }
10806 error = PyList_Append(result, attribute);
10807 Py_DECREF(attribute);
10808 if (error) {
10809 Py_DECREF(result);
10810 result = NULL;
10811 goto exit;
10812 }
10813 start = trace + 1;
10814 }
10815 }
10816 break;
10817 }
10818exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010819 if (buffer)
10820 PyMem_FREE(buffer);
10821 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010822}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010823#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010824
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010825
Larry Hastings2f936352014-08-05 14:04:04 +100010826/*[clinic input]
10827os.urandom
10828
10829 size: Py_ssize_t
10830 /
10831
10832Return a bytes object containing random bytes suitable for cryptographic use.
10833[clinic start generated code]*/
10834
Larry Hastings2f936352014-08-05 14:04:04 +100010835static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010836os_urandom_impl(PyObject *module, Py_ssize_t size)
10837/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010838{
10839 PyObject *bytes;
10840 int result;
10841
Georg Brandl2fb477c2012-02-21 00:33:36 +010010842 if (size < 0)
10843 return PyErr_Format(PyExc_ValueError,
10844 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010845 bytes = PyBytes_FromStringAndSize(NULL, size);
10846 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010847 return NULL;
10848
Victor Stinnere66987e2016-09-06 16:33:52 -070010849 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010850 if (result == -1) {
10851 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010852 return NULL;
10853 }
Larry Hastings2f936352014-08-05 14:04:04 +100010854 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010855}
10856
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010857/* Terminal size querying */
10858
10859static PyTypeObject TerminalSizeType;
10860
10861PyDoc_STRVAR(TerminalSize_docstring,
10862 "A tuple of (columns, lines) for holding terminal window size");
10863
10864static PyStructSequence_Field TerminalSize_fields[] = {
10865 {"columns", "width of the terminal window in characters"},
10866 {"lines", "height of the terminal window in characters"},
10867 {NULL, NULL}
10868};
10869
10870static PyStructSequence_Desc TerminalSize_desc = {
10871 "os.terminal_size",
10872 TerminalSize_docstring,
10873 TerminalSize_fields,
10874 2,
10875};
10876
10877#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010878/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010879PyDoc_STRVAR(termsize__doc__,
10880 "Return the size of the terminal window as (columns, lines).\n" \
10881 "\n" \
10882 "The optional argument fd (default standard output) specifies\n" \
10883 "which file descriptor should be queried.\n" \
10884 "\n" \
10885 "If the file descriptor is not connected to a terminal, an OSError\n" \
10886 "is thrown.\n" \
10887 "\n" \
10888 "This function will only be defined if an implementation is\n" \
10889 "available for this system.\n" \
10890 "\n" \
10891 "shutil.get_terminal_size is the high-level function which should \n" \
10892 "normally be used, os.get_terminal_size is the low-level implementation.");
10893
10894static PyObject*
10895get_terminal_size(PyObject *self, PyObject *args)
10896{
10897 int columns, lines;
10898 PyObject *termsize;
10899
10900 int fd = fileno(stdout);
10901 /* Under some conditions stdout may not be connected and
10902 * fileno(stdout) may point to an invalid file descriptor. For example
10903 * GUI apps don't have valid standard streams by default.
10904 *
10905 * If this happens, and the optional fd argument is not present,
10906 * the ioctl below will fail returning EBADF. This is what we want.
10907 */
10908
10909 if (!PyArg_ParseTuple(args, "|i", &fd))
10910 return NULL;
10911
10912#ifdef TERMSIZE_USE_IOCTL
10913 {
10914 struct winsize w;
10915 if (ioctl(fd, TIOCGWINSZ, &w))
10916 return PyErr_SetFromErrno(PyExc_OSError);
10917 columns = w.ws_col;
10918 lines = w.ws_row;
10919 }
10920#endif /* TERMSIZE_USE_IOCTL */
10921
10922#ifdef TERMSIZE_USE_CONIO
10923 {
10924 DWORD nhandle;
10925 HANDLE handle;
10926 CONSOLE_SCREEN_BUFFER_INFO csbi;
10927 switch (fd) {
10928 case 0: nhandle = STD_INPUT_HANDLE;
10929 break;
10930 case 1: nhandle = STD_OUTPUT_HANDLE;
10931 break;
10932 case 2: nhandle = STD_ERROR_HANDLE;
10933 break;
10934 default:
10935 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10936 }
10937 handle = GetStdHandle(nhandle);
10938 if (handle == NULL)
10939 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10940 if (handle == INVALID_HANDLE_VALUE)
10941 return PyErr_SetFromWindowsErr(0);
10942
10943 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10944 return PyErr_SetFromWindowsErr(0);
10945
10946 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10947 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10948 }
10949#endif /* TERMSIZE_USE_CONIO */
10950
10951 termsize = PyStructSequence_New(&TerminalSizeType);
10952 if (termsize == NULL)
10953 return NULL;
10954 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10955 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10956 if (PyErr_Occurred()) {
10957 Py_DECREF(termsize);
10958 return NULL;
10959 }
10960 return termsize;
10961}
10962#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10963
Larry Hastings2f936352014-08-05 14:04:04 +100010964
10965/*[clinic input]
10966os.cpu_count
10967
Charles-François Natali80d62e62015-08-13 20:37:08 +010010968Return the number of CPUs in the system; return None if indeterminable.
10969
10970This number is not equivalent to the number of CPUs the current process can
10971use. The number of usable CPUs can be obtained with
10972``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010973[clinic start generated code]*/
10974
Larry Hastings2f936352014-08-05 14:04:04 +100010975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010976os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010977/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010978{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010979 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010980#ifdef MS_WINDOWS
10981 SYSTEM_INFO sysinfo;
10982 GetSystemInfo(&sysinfo);
10983 ncpu = sysinfo.dwNumberOfProcessors;
10984#elif defined(__hpux)
10985 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10986#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10987 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010988#elif defined(__DragonFly__) || \
10989 defined(__OpenBSD__) || \
10990 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010991 defined(__NetBSD__) || \
10992 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010993 int mib[2];
10994 size_t len = sizeof(ncpu);
10995 mib[0] = CTL_HW;
10996 mib[1] = HW_NCPU;
10997 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10998 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010999#endif
11000 if (ncpu >= 1)
11001 return PyLong_FromLong(ncpu);
11002 else
11003 Py_RETURN_NONE;
11004}
11005
Victor Stinnerdaf45552013-08-28 00:53:59 +020011006
Larry Hastings2f936352014-08-05 14:04:04 +100011007/*[clinic input]
11008os.get_inheritable -> bool
11009
11010 fd: int
11011 /
11012
11013Get the close-on-exe flag of the specified file descriptor.
11014[clinic start generated code]*/
11015
Larry Hastings2f936352014-08-05 14:04:04 +100011016static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011017os_get_inheritable_impl(PyObject *module, int fd)
11018/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011019{
Steve Dower8fc89802015-04-12 00:26:27 -040011020 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011021 _Py_BEGIN_SUPPRESS_IPH
11022 return_value = _Py_get_inheritable(fd);
11023 _Py_END_SUPPRESS_IPH
11024 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011025}
11026
11027
11028/*[clinic input]
11029os.set_inheritable
11030 fd: int
11031 inheritable: int
11032 /
11033
11034Set the inheritable flag of the specified file descriptor.
11035[clinic start generated code]*/
11036
Larry Hastings2f936352014-08-05 14:04:04 +100011037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011038os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11039/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011040{
Steve Dower8fc89802015-04-12 00:26:27 -040011041 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011042
Steve Dower8fc89802015-04-12 00:26:27 -040011043 _Py_BEGIN_SUPPRESS_IPH
11044 result = _Py_set_inheritable(fd, inheritable, NULL);
11045 _Py_END_SUPPRESS_IPH
11046 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011047 return NULL;
11048 Py_RETURN_NONE;
11049}
11050
11051
11052#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011053/*[clinic input]
11054os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011055 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011056 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011057
Larry Hastings2f936352014-08-05 14:04:04 +100011058Get the close-on-exe flag of the specified file descriptor.
11059[clinic start generated code]*/
11060
Larry Hastings2f936352014-08-05 14:04:04 +100011061static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011062os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011063/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011064{
11065 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011066
11067 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11068 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011069 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011070 }
11071
Larry Hastings2f936352014-08-05 14:04:04 +100011072 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011073}
11074
Victor Stinnerdaf45552013-08-28 00:53:59 +020011075
Larry Hastings2f936352014-08-05 14:04:04 +100011076/*[clinic input]
11077os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011078 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011079 inheritable: bool
11080 /
11081
11082Set the inheritable flag of the specified handle.
11083[clinic start generated code]*/
11084
Larry Hastings2f936352014-08-05 14:04:04 +100011085static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011086os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011087 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011088/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011089{
11090 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011091 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11092 PyErr_SetFromWindowsErr(0);
11093 return NULL;
11094 }
11095 Py_RETURN_NONE;
11096}
Larry Hastings2f936352014-08-05 14:04:04 +100011097#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011098
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011099#ifndef MS_WINDOWS
11100PyDoc_STRVAR(get_blocking__doc__,
11101 "get_blocking(fd) -> bool\n" \
11102 "\n" \
11103 "Get the blocking mode of the file descriptor:\n" \
11104 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11105
11106static PyObject*
11107posix_get_blocking(PyObject *self, PyObject *args)
11108{
11109 int fd;
11110 int blocking;
11111
11112 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11113 return NULL;
11114
Steve Dower8fc89802015-04-12 00:26:27 -040011115 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011116 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011117 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011118 if (blocking < 0)
11119 return NULL;
11120 return PyBool_FromLong(blocking);
11121}
11122
11123PyDoc_STRVAR(set_blocking__doc__,
11124 "set_blocking(fd, blocking)\n" \
11125 "\n" \
11126 "Set the blocking mode of the specified file descriptor.\n" \
11127 "Set the O_NONBLOCK flag if blocking is False,\n" \
11128 "clear the O_NONBLOCK flag otherwise.");
11129
11130static PyObject*
11131posix_set_blocking(PyObject *self, PyObject *args)
11132{
Steve Dower8fc89802015-04-12 00:26:27 -040011133 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011134
11135 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11136 return NULL;
11137
Steve Dower8fc89802015-04-12 00:26:27 -040011138 _Py_BEGIN_SUPPRESS_IPH
11139 result = _Py_set_blocking(fd, blocking);
11140 _Py_END_SUPPRESS_IPH
11141 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011142 return NULL;
11143 Py_RETURN_NONE;
11144}
11145#endif /* !MS_WINDOWS */
11146
11147
Victor Stinner6036e442015-03-08 01:58:04 +010011148PyDoc_STRVAR(posix_scandir__doc__,
11149"scandir(path='.') -> iterator of DirEntry objects for given path");
11150
11151static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11152
11153typedef struct {
11154 PyObject_HEAD
11155 PyObject *name;
11156 PyObject *path;
11157 PyObject *stat;
11158 PyObject *lstat;
11159#ifdef MS_WINDOWS
11160 struct _Py_stat_struct win32_lstat;
Victor Stinner68d29802017-03-09 18:43:39 +010011161 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011162 int got_file_index;
11163#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011164#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011165 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011166#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011167 ino_t d_ino;
11168#endif
11169} DirEntry;
11170
11171static void
11172DirEntry_dealloc(DirEntry *entry)
11173{
11174 Py_XDECREF(entry->name);
11175 Py_XDECREF(entry->path);
11176 Py_XDECREF(entry->stat);
11177 Py_XDECREF(entry->lstat);
11178 Py_TYPE(entry)->tp_free((PyObject *)entry);
11179}
11180
11181/* Forward reference */
11182static int
11183DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11184
11185/* Set exception and return -1 on error, 0 for False, 1 for True */
11186static int
11187DirEntry_is_symlink(DirEntry *self)
11188{
11189#ifdef MS_WINDOWS
11190 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011191#elif defined(HAVE_DIRENT_D_TYPE)
11192 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011193 if (self->d_type != DT_UNKNOWN)
11194 return self->d_type == DT_LNK;
11195 else
11196 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011197#else
11198 /* POSIX without d_type */
11199 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011200#endif
11201}
11202
11203static PyObject *
11204DirEntry_py_is_symlink(DirEntry *self)
11205{
11206 int result;
11207
11208 result = DirEntry_is_symlink(self);
11209 if (result == -1)
11210 return NULL;
11211 return PyBool_FromLong(result);
11212}
11213
11214static PyObject *
11215DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11216{
11217 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011218 STRUCT_STAT st;
11219 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011220
11221#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011222 if (PyUnicode_FSDecoder(self->path, &ub)) {
11223 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011224#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011225 if (PyUnicode_FSConverter(self->path, &ub)) {
11226 const char *path = PyBytes_AS_STRING(ub);
11227#endif
11228 if (follow_symlinks)
11229 result = STAT(path, &st);
11230 else
11231 result = LSTAT(path, &st);
11232 Py_DECREF(ub);
11233 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011234 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011235
11236 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011237 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011238
11239 return _pystat_fromstructstat(&st);
11240}
11241
11242static PyObject *
11243DirEntry_get_lstat(DirEntry *self)
11244{
11245 if (!self->lstat) {
11246#ifdef MS_WINDOWS
11247 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11248#else /* POSIX */
11249 self->lstat = DirEntry_fetch_stat(self, 0);
11250#endif
11251 }
11252 Py_XINCREF(self->lstat);
11253 return self->lstat;
11254}
11255
11256static PyObject *
11257DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11258{
11259 if (!follow_symlinks)
11260 return DirEntry_get_lstat(self);
11261
11262 if (!self->stat) {
11263 int result = DirEntry_is_symlink(self);
11264 if (result == -1)
11265 return NULL;
11266 else if (result)
11267 self->stat = DirEntry_fetch_stat(self, 1);
11268 else
11269 self->stat = DirEntry_get_lstat(self);
11270 }
11271
11272 Py_XINCREF(self->stat);
11273 return self->stat;
11274}
11275
11276static PyObject *
11277DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11278{
11279 int follow_symlinks = 1;
11280
11281 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11282 follow_symlinks_keywords, &follow_symlinks))
11283 return NULL;
11284
11285 return DirEntry_get_stat(self, follow_symlinks);
11286}
11287
11288/* Set exception and return -1 on error, 0 for False, 1 for True */
11289static int
11290DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11291{
11292 PyObject *stat = NULL;
11293 PyObject *st_mode = NULL;
11294 long mode;
11295 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011296#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011297 int is_symlink;
11298 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011299#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011300#ifdef MS_WINDOWS
11301 unsigned long dir_bits;
11302#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011303 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011304
11305#ifdef MS_WINDOWS
11306 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11307 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011308#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011309 is_symlink = self->d_type == DT_LNK;
11310 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11311#endif
11312
Victor Stinner35a97c02015-03-08 02:59:09 +010011313#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011314 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011315#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011316 stat = DirEntry_get_stat(self, follow_symlinks);
11317 if (!stat) {
11318 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11319 /* If file doesn't exist (anymore), then return False
11320 (i.e., say it's not a file/directory) */
11321 PyErr_Clear();
11322 return 0;
11323 }
11324 goto error;
11325 }
11326 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11327 if (!st_mode)
11328 goto error;
11329
11330 mode = PyLong_AsLong(st_mode);
11331 if (mode == -1 && PyErr_Occurred())
11332 goto error;
11333 Py_CLEAR(st_mode);
11334 Py_CLEAR(stat);
11335 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011336#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011337 }
11338 else if (is_symlink) {
11339 assert(mode_bits != S_IFLNK);
11340 result = 0;
11341 }
11342 else {
11343 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11344#ifdef MS_WINDOWS
11345 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11346 if (mode_bits == S_IFDIR)
11347 result = dir_bits != 0;
11348 else
11349 result = dir_bits == 0;
11350#else /* POSIX */
11351 if (mode_bits == S_IFDIR)
11352 result = self->d_type == DT_DIR;
11353 else
11354 result = self->d_type == DT_REG;
11355#endif
11356 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011357#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011358
11359 return result;
11360
11361error:
11362 Py_XDECREF(st_mode);
11363 Py_XDECREF(stat);
11364 return -1;
11365}
11366
11367static PyObject *
11368DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11369{
11370 int result;
11371
11372 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11373 if (result == -1)
11374 return NULL;
11375 return PyBool_FromLong(result);
11376}
11377
11378static PyObject *
11379DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11380{
11381 int follow_symlinks = 1;
11382
11383 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11384 follow_symlinks_keywords, &follow_symlinks))
11385 return NULL;
11386
11387 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11388}
11389
11390static PyObject *
11391DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11392{
11393 int follow_symlinks = 1;
11394
11395 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11396 follow_symlinks_keywords, &follow_symlinks))
11397 return NULL;
11398
11399 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11400}
11401
11402static PyObject *
11403DirEntry_inode(DirEntry *self)
11404{
11405#ifdef MS_WINDOWS
11406 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011407 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011408 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011409 STRUCT_STAT stat;
11410 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011411
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011412 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011413 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011414 path = PyUnicode_AsUnicode(unicode);
11415 result = LSTAT(path, &stat);
11416 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011417
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011418 if (result != 0)
11419 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011420
11421 self->win32_file_index = stat.st_ino;
11422 self->got_file_index = 1;
11423 }
Victor Stinner68d29802017-03-09 18:43:39 +010011424 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11425 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011426#else /* POSIX */
11427#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011428 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011429#else
11430 return PyLong_FromLong((long)self->d_ino);
11431#endif
11432#endif
11433}
11434
11435static PyObject *
11436DirEntry_repr(DirEntry *self)
11437{
11438 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11439}
11440
Brett Cannon96881cd2016-06-10 14:37:21 -070011441static PyObject *
11442DirEntry_fspath(DirEntry *self)
11443{
11444 Py_INCREF(self->path);
11445 return self->path;
11446}
11447
Victor Stinner6036e442015-03-08 01:58:04 +010011448static PyMemberDef DirEntry_members[] = {
11449 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11450 "the entry's base filename, relative to scandir() \"path\" argument"},
11451 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11452 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11453 {NULL}
11454};
11455
11456static PyMethodDef DirEntry_methods[] = {
11457 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11458 "return True if the entry is a directory; cached per entry"
11459 },
11460 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11461 "return True if the entry is a file; cached per entry"
11462 },
11463 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11464 "return True if the entry is a symbolic link; cached per entry"
11465 },
11466 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11467 "return stat_result object for the entry; cached per entry"
11468 },
11469 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11470 "return inode of the entry; cached per entry",
11471 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011472 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11473 "returns the path for the entry",
11474 },
Victor Stinner6036e442015-03-08 01:58:04 +010011475 {NULL}
11476};
11477
Benjamin Peterson5646de42015-04-12 17:56:34 -040011478static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011479 PyVarObject_HEAD_INIT(NULL, 0)
11480 MODNAME ".DirEntry", /* tp_name */
11481 sizeof(DirEntry), /* tp_basicsize */
11482 0, /* tp_itemsize */
11483 /* methods */
11484 (destructor)DirEntry_dealloc, /* tp_dealloc */
11485 0, /* tp_print */
11486 0, /* tp_getattr */
11487 0, /* tp_setattr */
11488 0, /* tp_compare */
11489 (reprfunc)DirEntry_repr, /* tp_repr */
11490 0, /* tp_as_number */
11491 0, /* tp_as_sequence */
11492 0, /* tp_as_mapping */
11493 0, /* tp_hash */
11494 0, /* tp_call */
11495 0, /* tp_str */
11496 0, /* tp_getattro */
11497 0, /* tp_setattro */
11498 0, /* tp_as_buffer */
11499 Py_TPFLAGS_DEFAULT, /* tp_flags */
11500 0, /* tp_doc */
11501 0, /* tp_traverse */
11502 0, /* tp_clear */
11503 0, /* tp_richcompare */
11504 0, /* tp_weaklistoffset */
11505 0, /* tp_iter */
11506 0, /* tp_iternext */
11507 DirEntry_methods, /* tp_methods */
11508 DirEntry_members, /* tp_members */
11509};
11510
11511#ifdef MS_WINDOWS
11512
11513static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011514join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011515{
11516 Py_ssize_t path_len;
11517 Py_ssize_t size;
11518 wchar_t *result;
11519 wchar_t ch;
11520
11521 if (!path_wide) { /* Default arg: "." */
11522 path_wide = L".";
11523 path_len = 1;
11524 }
11525 else {
11526 path_len = wcslen(path_wide);
11527 }
11528
11529 /* The +1's are for the path separator and the NUL */
11530 size = path_len + 1 + wcslen(filename) + 1;
11531 result = PyMem_New(wchar_t, size);
11532 if (!result) {
11533 PyErr_NoMemory();
11534 return NULL;
11535 }
11536 wcscpy(result, path_wide);
11537 if (path_len > 0) {
11538 ch = result[path_len - 1];
11539 if (ch != SEP && ch != ALTSEP && ch != L':')
11540 result[path_len++] = SEP;
11541 wcscpy(result + path_len, filename);
11542 }
11543 return result;
11544}
11545
11546static PyObject *
11547DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11548{
11549 DirEntry *entry;
11550 BY_HANDLE_FILE_INFORMATION file_info;
11551 ULONG reparse_tag;
11552 wchar_t *joined_path;
11553
11554 entry = PyObject_New(DirEntry, &DirEntryType);
11555 if (!entry)
11556 return NULL;
11557 entry->name = NULL;
11558 entry->path = NULL;
11559 entry->stat = NULL;
11560 entry->lstat = NULL;
11561 entry->got_file_index = 0;
11562
11563 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11564 if (!entry->name)
11565 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011566 if (path->narrow) {
11567 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11568 if (!entry->name)
11569 goto error;
11570 }
Victor Stinner6036e442015-03-08 01:58:04 +010011571
11572 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11573 if (!joined_path)
11574 goto error;
11575
11576 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11577 PyMem_Free(joined_path);
11578 if (!entry->path)
11579 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011580 if (path->narrow) {
11581 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11582 if (!entry->path)
11583 goto error;
11584 }
Victor Stinner6036e442015-03-08 01:58:04 +010011585
Steve Dowercc16be82016-09-08 10:35:16 -070011586 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011587 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11588
11589 return (PyObject *)entry;
11590
11591error:
11592 Py_DECREF(entry);
11593 return NULL;
11594}
11595
11596#else /* POSIX */
11597
11598static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011599join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011600{
11601 Py_ssize_t path_len;
11602 Py_ssize_t size;
11603 char *result;
11604
11605 if (!path_narrow) { /* Default arg: "." */
11606 path_narrow = ".";
11607 path_len = 1;
11608 }
11609 else {
11610 path_len = strlen(path_narrow);
11611 }
11612
11613 if (filename_len == -1)
11614 filename_len = strlen(filename);
11615
11616 /* The +1's are for the path separator and the NUL */
11617 size = path_len + 1 + filename_len + 1;
11618 result = PyMem_New(char, size);
11619 if (!result) {
11620 PyErr_NoMemory();
11621 return NULL;
11622 }
11623 strcpy(result, path_narrow);
11624 if (path_len > 0 && result[path_len - 1] != '/')
11625 result[path_len++] = '/';
11626 strcpy(result + path_len, filename);
11627 return result;
11628}
11629
11630static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011631DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011632 ino_t d_ino
11633#ifdef HAVE_DIRENT_D_TYPE
11634 , unsigned char d_type
11635#endif
11636 )
Victor Stinner6036e442015-03-08 01:58:04 +010011637{
11638 DirEntry *entry;
11639 char *joined_path;
11640
11641 entry = PyObject_New(DirEntry, &DirEntryType);
11642 if (!entry)
11643 return NULL;
11644 entry->name = NULL;
11645 entry->path = NULL;
11646 entry->stat = NULL;
11647 entry->lstat = NULL;
11648
11649 joined_path = join_path_filename(path->narrow, name, name_len);
11650 if (!joined_path)
11651 goto error;
11652
11653 if (!path->narrow || !PyBytes_Check(path->object)) {
11654 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11655 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11656 }
11657 else {
11658 entry->name = PyBytes_FromStringAndSize(name, name_len);
11659 entry->path = PyBytes_FromString(joined_path);
11660 }
11661 PyMem_Free(joined_path);
11662 if (!entry->name || !entry->path)
11663 goto error;
11664
Victor Stinner35a97c02015-03-08 02:59:09 +010011665#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011666 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011667#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011668 entry->d_ino = d_ino;
11669
11670 return (PyObject *)entry;
11671
11672error:
11673 Py_XDECREF(entry);
11674 return NULL;
11675}
11676
11677#endif
11678
11679
11680typedef struct {
11681 PyObject_HEAD
11682 path_t path;
11683#ifdef MS_WINDOWS
11684 HANDLE handle;
11685 WIN32_FIND_DATAW file_data;
11686 int first_time;
11687#else /* POSIX */
11688 DIR *dirp;
11689#endif
11690} ScandirIterator;
11691
11692#ifdef MS_WINDOWS
11693
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011694static int
11695ScandirIterator_is_closed(ScandirIterator *iterator)
11696{
11697 return iterator->handle == INVALID_HANDLE_VALUE;
11698}
11699
Victor Stinner6036e442015-03-08 01:58:04 +010011700static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011701ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011702{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011703 HANDLE handle = iterator->handle;
11704
11705 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011706 return;
11707
Victor Stinner6036e442015-03-08 01:58:04 +010011708 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011709 Py_BEGIN_ALLOW_THREADS
11710 FindClose(handle);
11711 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011712}
11713
11714static PyObject *
11715ScandirIterator_iternext(ScandirIterator *iterator)
11716{
11717 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11718 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011719 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011720
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011721 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011722 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011723 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011724
11725 while (1) {
11726 if (!iterator->first_time) {
11727 Py_BEGIN_ALLOW_THREADS
11728 success = FindNextFileW(iterator->handle, file_data);
11729 Py_END_ALLOW_THREADS
11730 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011731 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011732 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011733 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011734 break;
11735 }
11736 }
11737 iterator->first_time = 0;
11738
11739 /* Skip over . and .. */
11740 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011741 wcscmp(file_data->cFileName, L"..") != 0) {
11742 entry = DirEntry_from_find_data(&iterator->path, file_data);
11743 if (!entry)
11744 break;
11745 return entry;
11746 }
Victor Stinner6036e442015-03-08 01:58:04 +010011747
11748 /* Loop till we get a non-dot directory or finish iterating */
11749 }
11750
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011751 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011752 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011753 return NULL;
11754}
11755
11756#else /* POSIX */
11757
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011758static int
11759ScandirIterator_is_closed(ScandirIterator *iterator)
11760{
11761 return !iterator->dirp;
11762}
11763
Victor Stinner6036e442015-03-08 01:58:04 +010011764static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011765ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011766{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011767 DIR *dirp = iterator->dirp;
11768
11769 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011770 return;
11771
Victor Stinner6036e442015-03-08 01:58:04 +010011772 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011773 Py_BEGIN_ALLOW_THREADS
11774 closedir(dirp);
11775 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011776 return;
11777}
11778
11779static PyObject *
11780ScandirIterator_iternext(ScandirIterator *iterator)
11781{
11782 struct dirent *direntp;
11783 Py_ssize_t name_len;
11784 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011785 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011786
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011787 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011788 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011789 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011790
11791 while (1) {
11792 errno = 0;
11793 Py_BEGIN_ALLOW_THREADS
11794 direntp = readdir(iterator->dirp);
11795 Py_END_ALLOW_THREADS
11796
11797 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011798 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011799 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011800 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011801 break;
11802 }
11803
11804 /* Skip over . and .. */
11805 name_len = NAMLEN(direntp);
11806 is_dot = direntp->d_name[0] == '.' &&
11807 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11808 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011809 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011810 name_len, direntp->d_ino
11811#ifdef HAVE_DIRENT_D_TYPE
11812 , direntp->d_type
11813#endif
11814 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011815 if (!entry)
11816 break;
11817 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011818 }
11819
11820 /* Loop till we get a non-dot directory or finish iterating */
11821 }
11822
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011823 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011824 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011825 return NULL;
11826}
11827
11828#endif
11829
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011830static PyObject *
11831ScandirIterator_close(ScandirIterator *self, PyObject *args)
11832{
11833 ScandirIterator_closedir(self);
11834 Py_RETURN_NONE;
11835}
11836
11837static PyObject *
11838ScandirIterator_enter(PyObject *self, PyObject *args)
11839{
11840 Py_INCREF(self);
11841 return self;
11842}
11843
11844static PyObject *
11845ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11846{
11847 ScandirIterator_closedir(self);
11848 Py_RETURN_NONE;
11849}
11850
Victor Stinner6036e442015-03-08 01:58:04 +010011851static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011852ScandirIterator_finalize(ScandirIterator *iterator)
11853{
11854 PyObject *error_type, *error_value, *error_traceback;
11855
11856 /* Save the current exception, if any. */
11857 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11858
11859 if (!ScandirIterator_is_closed(iterator)) {
11860 ScandirIterator_closedir(iterator);
11861
11862 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11863 "unclosed scandir iterator %R", iterator)) {
11864 /* Spurious errors can appear at shutdown */
11865 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11866 PyErr_WriteUnraisable((PyObject *) iterator);
11867 }
11868 }
11869 }
11870
Victor Stinner7bfa4092016-03-23 00:43:54 +010011871 path_cleanup(&iterator->path);
11872
11873 /* Restore the saved exception. */
11874 PyErr_Restore(error_type, error_value, error_traceback);
11875}
11876
11877static void
Victor Stinner6036e442015-03-08 01:58:04 +010011878ScandirIterator_dealloc(ScandirIterator *iterator)
11879{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011880 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11881 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011882
Victor Stinner6036e442015-03-08 01:58:04 +010011883 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11884}
11885
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011886static PyMethodDef ScandirIterator_methods[] = {
11887 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11888 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11889 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11890 {NULL}
11891};
11892
Benjamin Peterson5646de42015-04-12 17:56:34 -040011893static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011894 PyVarObject_HEAD_INIT(NULL, 0)
11895 MODNAME ".ScandirIterator", /* tp_name */
11896 sizeof(ScandirIterator), /* tp_basicsize */
11897 0, /* tp_itemsize */
11898 /* methods */
11899 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11900 0, /* tp_print */
11901 0, /* tp_getattr */
11902 0, /* tp_setattr */
11903 0, /* tp_compare */
11904 0, /* tp_repr */
11905 0, /* tp_as_number */
11906 0, /* tp_as_sequence */
11907 0, /* tp_as_mapping */
11908 0, /* tp_hash */
11909 0, /* tp_call */
11910 0, /* tp_str */
11911 0, /* tp_getattro */
11912 0, /* tp_setattro */
11913 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011914 Py_TPFLAGS_DEFAULT
11915 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011916 0, /* tp_doc */
11917 0, /* tp_traverse */
11918 0, /* tp_clear */
11919 0, /* tp_richcompare */
11920 0, /* tp_weaklistoffset */
11921 PyObject_SelfIter, /* tp_iter */
11922 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011923 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011924 0, /* tp_members */
11925 0, /* tp_getset */
11926 0, /* tp_base */
11927 0, /* tp_dict */
11928 0, /* tp_descr_get */
11929 0, /* tp_descr_set */
11930 0, /* tp_dictoffset */
11931 0, /* tp_init */
11932 0, /* tp_alloc */
11933 0, /* tp_new */
11934 0, /* tp_free */
11935 0, /* tp_is_gc */
11936 0, /* tp_bases */
11937 0, /* tp_mro */
11938 0, /* tp_cache */
11939 0, /* tp_subclasses */
11940 0, /* tp_weaklist */
11941 0, /* tp_del */
11942 0, /* tp_version_tag */
11943 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011944};
11945
11946static PyObject *
11947posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11948{
11949 ScandirIterator *iterator;
11950 static char *keywords[] = {"path", NULL};
11951#ifdef MS_WINDOWS
11952 wchar_t *path_strW;
11953#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011954 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011955#endif
11956
11957 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11958 if (!iterator)
11959 return NULL;
11960 memset(&iterator->path, 0, sizeof(path_t));
11961 iterator->path.function_name = "scandir";
11962 iterator->path.nullable = 1;
11963
11964#ifdef MS_WINDOWS
11965 iterator->handle = INVALID_HANDLE_VALUE;
11966#else
11967 iterator->dirp = NULL;
11968#endif
11969
11970 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11971 path_converter, &iterator->path))
11972 goto error;
11973
Victor Stinner6036e442015-03-08 01:58:04 +010011974#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011975 iterator->first_time = 1;
11976
11977 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11978 if (!path_strW)
11979 goto error;
11980
11981 Py_BEGIN_ALLOW_THREADS
11982 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11983 Py_END_ALLOW_THREADS
11984
11985 PyMem_Free(path_strW);
11986
11987 if (iterator->handle == INVALID_HANDLE_VALUE) {
11988 path_error(&iterator->path);
11989 goto error;
11990 }
11991#else /* POSIX */
11992 if (iterator->path.narrow)
11993 path = iterator->path.narrow;
11994 else
11995 path = ".";
11996
11997 errno = 0;
11998 Py_BEGIN_ALLOW_THREADS
11999 iterator->dirp = opendir(path);
12000 Py_END_ALLOW_THREADS
12001
12002 if (!iterator->dirp) {
12003 path_error(&iterator->path);
12004 goto error;
12005 }
12006#endif
12007
12008 return (PyObject *)iterator;
12009
12010error:
12011 Py_DECREF(iterator);
12012 return NULL;
12013}
12014
Ethan Furman410ef8e2016-06-04 12:06:26 -070012015/*
12016 Return the file system path representation of the object.
12017
12018 If the object is str or bytes, then allow it to pass through with
12019 an incremented refcount. If the object defines __fspath__(), then
12020 return the result of that method. All other types raise a TypeError.
12021*/
12022PyObject *
12023PyOS_FSPath(PyObject *path)
12024{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012025 /* For error message reasons, this function is manually inlined in
12026 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012027 _Py_IDENTIFIER(__fspath__);
12028 PyObject *func = NULL;
12029 PyObject *path_repr = NULL;
12030
12031 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12032 Py_INCREF(path);
12033 return path;
12034 }
12035
12036 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12037 if (NULL == func) {
12038 return PyErr_Format(PyExc_TypeError,
12039 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012040 "not %.200s",
12041 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012042 }
12043
12044 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12045 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012046 if (NULL == path_repr) {
12047 return NULL;
12048 }
12049
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012050 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12051 PyErr_Format(PyExc_TypeError,
12052 "expected %.200s.__fspath__() to return str or bytes, "
12053 "not %.200s", Py_TYPE(path)->tp_name,
12054 Py_TYPE(path_repr)->tp_name);
12055 Py_DECREF(path_repr);
12056 return NULL;
12057 }
12058
Ethan Furman410ef8e2016-06-04 12:06:26 -070012059 return path_repr;
12060}
12061
12062/*[clinic input]
12063os.fspath
12064
12065 path: object
12066
12067Return the file system path representation of the object.
12068
Brett Cannonb4f43e92016-06-09 14:32:08 -070012069If the object is str or bytes, then allow it to pass through as-is. If the
12070object defines __fspath__(), then return the result of that method. All other
12071types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012072[clinic start generated code]*/
12073
12074static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012075os_fspath_impl(PyObject *module, PyObject *path)
12076/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012077{
12078 return PyOS_FSPath(path);
12079}
Victor Stinner6036e442015-03-08 01:58:04 +010012080
Victor Stinner9b1f4742016-09-06 16:18:52 -070012081#ifdef HAVE_GETRANDOM_SYSCALL
12082/*[clinic input]
12083os.getrandom
12084
12085 size: Py_ssize_t
12086 flags: int=0
12087
12088Obtain a series of random bytes.
12089[clinic start generated code]*/
12090
12091static PyObject *
12092os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12093/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12094{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012095 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012096 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012097
12098 if (size < 0) {
12099 errno = EINVAL;
12100 return posix_error();
12101 }
12102
Victor Stinnerec2319c2016-09-20 23:00:59 +020012103 bytes = PyBytes_FromStringAndSize(NULL, size);
12104 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012105 PyErr_NoMemory();
12106 return NULL;
12107 }
12108
12109 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012110 n = syscall(SYS_getrandom,
12111 PyBytes_AS_STRING(bytes),
12112 PyBytes_GET_SIZE(bytes),
12113 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012114 if (n < 0 && errno == EINTR) {
12115 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012116 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012117 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012118
12119 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012120 continue;
12121 }
12122 break;
12123 }
12124
12125 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012126 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012127 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012128 }
12129
Victor Stinnerec2319c2016-09-20 23:00:59 +020012130 if (n != size) {
12131 _PyBytes_Resize(&bytes, n);
12132 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012133
12134 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012135
12136error:
12137 Py_DECREF(bytes);
12138 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012139}
12140#endif /* HAVE_GETRANDOM_SYSCALL */
12141
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012142#include "clinic/posixmodule.c.h"
12143
Larry Hastings7726ac92014-01-31 22:03:12 -080012144/*[clinic input]
12145dump buffer
12146[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012147/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012148
Larry Hastings31826802013-10-19 00:09:25 -070012149
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012150static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012151
12152 OS_STAT_METHODDEF
12153 OS_ACCESS_METHODDEF
12154 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012155 OS_CHDIR_METHODDEF
12156 OS_CHFLAGS_METHODDEF
12157 OS_CHMOD_METHODDEF
12158 OS_FCHMOD_METHODDEF
12159 OS_LCHMOD_METHODDEF
12160 OS_CHOWN_METHODDEF
12161 OS_FCHOWN_METHODDEF
12162 OS_LCHOWN_METHODDEF
12163 OS_LCHFLAGS_METHODDEF
12164 OS_CHROOT_METHODDEF
12165 OS_CTERMID_METHODDEF
12166 OS_GETCWD_METHODDEF
12167 OS_GETCWDB_METHODDEF
12168 OS_LINK_METHODDEF
12169 OS_LISTDIR_METHODDEF
12170 OS_LSTAT_METHODDEF
12171 OS_MKDIR_METHODDEF
12172 OS_NICE_METHODDEF
12173 OS_GETPRIORITY_METHODDEF
12174 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012175#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012176 {"readlink", (PyCFunction)posix_readlink,
12177 METH_VARARGS | METH_KEYWORDS,
12178 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012179#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012180#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012181 {"readlink", (PyCFunction)win_readlink,
12182 METH_VARARGS | METH_KEYWORDS,
12183 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012184#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012185 OS_RENAME_METHODDEF
12186 OS_REPLACE_METHODDEF
12187 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012188 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012189 OS_SYMLINK_METHODDEF
12190 OS_SYSTEM_METHODDEF
12191 OS_UMASK_METHODDEF
12192 OS_UNAME_METHODDEF
12193 OS_UNLINK_METHODDEF
12194 OS_REMOVE_METHODDEF
12195 OS_UTIME_METHODDEF
12196 OS_TIMES_METHODDEF
12197 OS__EXIT_METHODDEF
12198 OS_EXECV_METHODDEF
12199 OS_EXECVE_METHODDEF
12200 OS_SPAWNV_METHODDEF
12201 OS_SPAWNVE_METHODDEF
12202 OS_FORK1_METHODDEF
12203 OS_FORK_METHODDEF
12204 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12205 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12206 OS_SCHED_GETPARAM_METHODDEF
12207 OS_SCHED_GETSCHEDULER_METHODDEF
12208 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12209 OS_SCHED_SETPARAM_METHODDEF
12210 OS_SCHED_SETSCHEDULER_METHODDEF
12211 OS_SCHED_YIELD_METHODDEF
12212 OS_SCHED_SETAFFINITY_METHODDEF
12213 OS_SCHED_GETAFFINITY_METHODDEF
12214 OS_OPENPTY_METHODDEF
12215 OS_FORKPTY_METHODDEF
12216 OS_GETEGID_METHODDEF
12217 OS_GETEUID_METHODDEF
12218 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012219#ifdef HAVE_GETGROUPLIST
12220 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12221#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012222 OS_GETGROUPS_METHODDEF
12223 OS_GETPID_METHODDEF
12224 OS_GETPGRP_METHODDEF
12225 OS_GETPPID_METHODDEF
12226 OS_GETUID_METHODDEF
12227 OS_GETLOGIN_METHODDEF
12228 OS_KILL_METHODDEF
12229 OS_KILLPG_METHODDEF
12230 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012231#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012232 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012233#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012234 OS_SETUID_METHODDEF
12235 OS_SETEUID_METHODDEF
12236 OS_SETREUID_METHODDEF
12237 OS_SETGID_METHODDEF
12238 OS_SETEGID_METHODDEF
12239 OS_SETREGID_METHODDEF
12240 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012241#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012242 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012243#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012244 OS_GETPGID_METHODDEF
12245 OS_SETPGRP_METHODDEF
12246 OS_WAIT_METHODDEF
12247 OS_WAIT3_METHODDEF
12248 OS_WAIT4_METHODDEF
12249 OS_WAITID_METHODDEF
12250 OS_WAITPID_METHODDEF
12251 OS_GETSID_METHODDEF
12252 OS_SETSID_METHODDEF
12253 OS_SETPGID_METHODDEF
12254 OS_TCGETPGRP_METHODDEF
12255 OS_TCSETPGRP_METHODDEF
12256 OS_OPEN_METHODDEF
12257 OS_CLOSE_METHODDEF
12258 OS_CLOSERANGE_METHODDEF
12259 OS_DEVICE_ENCODING_METHODDEF
12260 OS_DUP_METHODDEF
12261 OS_DUP2_METHODDEF
12262 OS_LOCKF_METHODDEF
12263 OS_LSEEK_METHODDEF
12264 OS_READ_METHODDEF
12265 OS_READV_METHODDEF
12266 OS_PREAD_METHODDEF
12267 OS_WRITE_METHODDEF
12268 OS_WRITEV_METHODDEF
12269 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012270#ifdef HAVE_SENDFILE
12271 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12272 posix_sendfile__doc__},
12273#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012274 OS_FSTAT_METHODDEF
12275 OS_ISATTY_METHODDEF
12276 OS_PIPE_METHODDEF
12277 OS_PIPE2_METHODDEF
12278 OS_MKFIFO_METHODDEF
12279 OS_MKNOD_METHODDEF
12280 OS_MAJOR_METHODDEF
12281 OS_MINOR_METHODDEF
12282 OS_MAKEDEV_METHODDEF
12283 OS_FTRUNCATE_METHODDEF
12284 OS_TRUNCATE_METHODDEF
12285 OS_POSIX_FALLOCATE_METHODDEF
12286 OS_POSIX_FADVISE_METHODDEF
12287 OS_PUTENV_METHODDEF
12288 OS_UNSETENV_METHODDEF
12289 OS_STRERROR_METHODDEF
12290 OS_FCHDIR_METHODDEF
12291 OS_FSYNC_METHODDEF
12292 OS_SYNC_METHODDEF
12293 OS_FDATASYNC_METHODDEF
12294 OS_WCOREDUMP_METHODDEF
12295 OS_WIFCONTINUED_METHODDEF
12296 OS_WIFSTOPPED_METHODDEF
12297 OS_WIFSIGNALED_METHODDEF
12298 OS_WIFEXITED_METHODDEF
12299 OS_WEXITSTATUS_METHODDEF
12300 OS_WTERMSIG_METHODDEF
12301 OS_WSTOPSIG_METHODDEF
12302 OS_FSTATVFS_METHODDEF
12303 OS_STATVFS_METHODDEF
12304 OS_CONFSTR_METHODDEF
12305 OS_SYSCONF_METHODDEF
12306 OS_FPATHCONF_METHODDEF
12307 OS_PATHCONF_METHODDEF
12308 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012309 OS__GETFULLPATHNAME_METHODDEF
12310 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012311 OS__GETDISKUSAGE_METHODDEF
12312 OS__GETFINALPATHNAME_METHODDEF
12313 OS__GETVOLUMEPATHNAME_METHODDEF
12314 OS_GETLOADAVG_METHODDEF
12315 OS_URANDOM_METHODDEF
12316 OS_SETRESUID_METHODDEF
12317 OS_SETRESGID_METHODDEF
12318 OS_GETRESUID_METHODDEF
12319 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012320
Larry Hastings2f936352014-08-05 14:04:04 +100012321 OS_GETXATTR_METHODDEF
12322 OS_SETXATTR_METHODDEF
12323 OS_REMOVEXATTR_METHODDEF
12324 OS_LISTXATTR_METHODDEF
12325
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012326#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12327 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12328#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012329 OS_CPU_COUNT_METHODDEF
12330 OS_GET_INHERITABLE_METHODDEF
12331 OS_SET_INHERITABLE_METHODDEF
12332 OS_GET_HANDLE_INHERITABLE_METHODDEF
12333 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012334#ifndef MS_WINDOWS
12335 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12336 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12337#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012338 {"scandir", (PyCFunction)posix_scandir,
12339 METH_VARARGS | METH_KEYWORDS,
12340 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012341 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012342 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012343 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012344};
12345
12346
Brian Curtin52173d42010-12-02 18:29:18 +000012347#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012348static int
Brian Curtin52173d42010-12-02 18:29:18 +000012349enable_symlink()
12350{
12351 HANDLE tok;
12352 TOKEN_PRIVILEGES tok_priv;
12353 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012354
12355 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012356 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012357
12358 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012359 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012360
12361 tok_priv.PrivilegeCount = 1;
12362 tok_priv.Privileges[0].Luid = luid;
12363 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12364
12365 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12366 sizeof(TOKEN_PRIVILEGES),
12367 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012368 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012369
Brian Curtin3b4499c2010-12-28 14:31:47 +000012370 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12371 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012372}
12373#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12374
Barry Warsaw4a342091996-12-19 23:50:02 +000012375static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012376all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012377{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012378#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012379 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012380#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012381#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012383#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012384#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012385 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012386#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012387#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012388 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012389#endif
Fred Drakec9680921999-12-13 16:37:25 +000012390#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012391 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012392#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012393#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012394 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012395#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012396#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012397 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012398#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012399#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012401#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012402#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012404#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012405#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012407#endif
12408#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012410#endif
12411#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012413#endif
12414#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012416#endif
12417#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012419#endif
12420#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012422#endif
12423#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012424 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012425#endif
12426#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012428#endif
12429#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012430 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#endif
12432#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012433 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012434#endif
12435#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012437#endif
12438#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012439 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012440#endif
12441#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012442 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012443#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012444#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012445 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012446#endif
12447#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012449#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012450#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012452#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012453#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012454 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012455#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012456#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012457#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012459#endif
12460#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012462#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012463#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012464#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012466#endif
12467#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012468 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012469#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012470#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012472#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012473#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012474 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012475#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012476#ifdef O_TMPFILE
12477 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12478#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012479#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012480 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012481#endif
12482#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012484#endif
12485#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012486 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012487#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012488#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012489 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012490#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012491#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012492 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012493#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012494
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012495
Jesus Cea94363612012-06-22 18:32:07 +020012496#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012498#endif
12499#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012501#endif
12502
Tim Peters5aa91602002-01-30 05:46:57 +000012503/* MS Windows */
12504#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012505 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012507#endif
12508#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012509 /* Optimize for short life (keep in memory). */
12510 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012511 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012512#endif
12513#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012514 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012516#endif
12517#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012518 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012519 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012520#endif
12521#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012522 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012523 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012524#endif
12525
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012526/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012527#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012528 /* Send a SIGIO signal whenever input or output
12529 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012531#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012532#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012533 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012534 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012535#endif
12536#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012537 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012538 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012539#endif
12540#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012541 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012542 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012543#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012544#ifdef O_NOLINKS
12545 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012546 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012547#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012548#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012549 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012550 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012551#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012552
Victor Stinner8c62be82010-05-06 00:08:46 +000012553 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012554#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012556#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012557#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012559#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012560#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012561 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012562#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012563#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012564 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012565#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012566#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012568#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012569#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012571#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012572#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012573 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012574#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012575#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012576 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012577#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012598#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012599#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012601#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012602#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012604#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012605
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012606 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012607#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012609#endif /* ST_RDONLY */
12610#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012612#endif /* ST_NOSUID */
12613
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012614 /* GNU extensions */
12615#ifdef ST_NODEV
12616 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12617#endif /* ST_NODEV */
12618#ifdef ST_NOEXEC
12619 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12620#endif /* ST_NOEXEC */
12621#ifdef ST_SYNCHRONOUS
12622 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12623#endif /* ST_SYNCHRONOUS */
12624#ifdef ST_MANDLOCK
12625 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12626#endif /* ST_MANDLOCK */
12627#ifdef ST_WRITE
12628 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12629#endif /* ST_WRITE */
12630#ifdef ST_APPEND
12631 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12632#endif /* ST_APPEND */
12633#ifdef ST_NOATIME
12634 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12635#endif /* ST_NOATIME */
12636#ifdef ST_NODIRATIME
12637 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12638#endif /* ST_NODIRATIME */
12639#ifdef ST_RELATIME
12640 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12641#endif /* ST_RELATIME */
12642
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012643 /* FreeBSD sendfile() constants */
12644#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012645 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012646#endif
12647#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012648 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012649#endif
12650#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012651 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012652#endif
12653
Ross Lagerwall7807c352011-03-17 20:20:30 +020012654 /* constants for posix_fadvise */
12655#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012657#endif
12658#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012660#endif
12661#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012663#endif
12664#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012666#endif
12667#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012669#endif
12670#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012672#endif
12673
12674 /* constants for waitid */
12675#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012676 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12677 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12678 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012679#endif
12680#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012682#endif
12683#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012685#endif
12686#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012687 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012688#endif
12689#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012691#endif
12692#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012694#endif
12695#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012697#endif
12698#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012699 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012700#endif
12701
12702 /* constants for lockf */
12703#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012705#endif
12706#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012708#endif
12709#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012710 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012711#endif
12712#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012714#endif
12715
Guido van Rossum246bc171999-02-01 23:54:31 +000012716#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12718 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12719 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12720 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12721 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012722#endif
12723
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012724#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012725#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012727#endif
12728#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012730#endif
12731#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012733#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012734#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012736#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012737#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012739#endif
12740#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012742#endif
12743#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012745#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012746#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012748#endif
12749#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012751#endif
12752#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012754#endif
12755#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012757#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012758#endif
12759
Benjamin Peterson9428d532011-09-14 11:45:52 -040012760#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12762 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12763 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012764#endif
12765
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012766#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012768#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012769#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012771#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012772#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012774#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012775#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012777#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012778#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012780#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012781#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012783#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012784#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012786#endif
12787
Victor Stinner9b1f4742016-09-06 16:18:52 -070012788#ifdef HAVE_GETRANDOM_SYSCALL
12789 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12790 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12791#endif
12792
Victor Stinner8c62be82010-05-06 00:08:46 +000012793 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012794}
12795
12796
Martin v. Löwis1a214512008-06-11 05:26:20 +000012797static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012798 PyModuleDef_HEAD_INIT,
12799 MODNAME,
12800 posix__doc__,
12801 -1,
12802 posix_methods,
12803 NULL,
12804 NULL,
12805 NULL,
12806 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012807};
12808
12809
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012810static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012811
12812#ifdef HAVE_FACCESSAT
12813 "HAVE_FACCESSAT",
12814#endif
12815
12816#ifdef HAVE_FCHDIR
12817 "HAVE_FCHDIR",
12818#endif
12819
12820#ifdef HAVE_FCHMOD
12821 "HAVE_FCHMOD",
12822#endif
12823
12824#ifdef HAVE_FCHMODAT
12825 "HAVE_FCHMODAT",
12826#endif
12827
12828#ifdef HAVE_FCHOWN
12829 "HAVE_FCHOWN",
12830#endif
12831
Larry Hastings00964ed2013-08-12 13:49:30 -040012832#ifdef HAVE_FCHOWNAT
12833 "HAVE_FCHOWNAT",
12834#endif
12835
Larry Hastings9cf065c2012-06-22 16:30:09 -070012836#ifdef HAVE_FEXECVE
12837 "HAVE_FEXECVE",
12838#endif
12839
12840#ifdef HAVE_FDOPENDIR
12841 "HAVE_FDOPENDIR",
12842#endif
12843
Georg Brandl306336b2012-06-24 12:55:33 +020012844#ifdef HAVE_FPATHCONF
12845 "HAVE_FPATHCONF",
12846#endif
12847
Larry Hastings9cf065c2012-06-22 16:30:09 -070012848#ifdef HAVE_FSTATAT
12849 "HAVE_FSTATAT",
12850#endif
12851
12852#ifdef HAVE_FSTATVFS
12853 "HAVE_FSTATVFS",
12854#endif
12855
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012856#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012857 "HAVE_FTRUNCATE",
12858#endif
12859
Larry Hastings9cf065c2012-06-22 16:30:09 -070012860#ifdef HAVE_FUTIMENS
12861 "HAVE_FUTIMENS",
12862#endif
12863
12864#ifdef HAVE_FUTIMES
12865 "HAVE_FUTIMES",
12866#endif
12867
12868#ifdef HAVE_FUTIMESAT
12869 "HAVE_FUTIMESAT",
12870#endif
12871
12872#ifdef HAVE_LINKAT
12873 "HAVE_LINKAT",
12874#endif
12875
12876#ifdef HAVE_LCHFLAGS
12877 "HAVE_LCHFLAGS",
12878#endif
12879
12880#ifdef HAVE_LCHMOD
12881 "HAVE_LCHMOD",
12882#endif
12883
12884#ifdef HAVE_LCHOWN
12885 "HAVE_LCHOWN",
12886#endif
12887
12888#ifdef HAVE_LSTAT
12889 "HAVE_LSTAT",
12890#endif
12891
12892#ifdef HAVE_LUTIMES
12893 "HAVE_LUTIMES",
12894#endif
12895
12896#ifdef HAVE_MKDIRAT
12897 "HAVE_MKDIRAT",
12898#endif
12899
12900#ifdef HAVE_MKFIFOAT
12901 "HAVE_MKFIFOAT",
12902#endif
12903
12904#ifdef HAVE_MKNODAT
12905 "HAVE_MKNODAT",
12906#endif
12907
12908#ifdef HAVE_OPENAT
12909 "HAVE_OPENAT",
12910#endif
12911
12912#ifdef HAVE_READLINKAT
12913 "HAVE_READLINKAT",
12914#endif
12915
12916#ifdef HAVE_RENAMEAT
12917 "HAVE_RENAMEAT",
12918#endif
12919
12920#ifdef HAVE_SYMLINKAT
12921 "HAVE_SYMLINKAT",
12922#endif
12923
12924#ifdef HAVE_UNLINKAT
12925 "HAVE_UNLINKAT",
12926#endif
12927
12928#ifdef HAVE_UTIMENSAT
12929 "HAVE_UTIMENSAT",
12930#endif
12931
12932#ifdef MS_WINDOWS
12933 "MS_WINDOWS",
12934#endif
12935
12936 NULL
12937};
12938
12939
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012940PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012941INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012942{
Victor Stinner8c62be82010-05-06 00:08:46 +000012943 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012944 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012945 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012946
Brian Curtin52173d42010-12-02 18:29:18 +000012947#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012948 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012949#endif
12950
Victor Stinner8c62be82010-05-06 00:08:46 +000012951 m = PyModule_Create(&posixmodule);
12952 if (m == NULL)
12953 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012954
Victor Stinner8c62be82010-05-06 00:08:46 +000012955 /* Initialize environ dictionary */
12956 v = convertenviron();
12957 Py_XINCREF(v);
12958 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12959 return NULL;
12960 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012961
Victor Stinner8c62be82010-05-06 00:08:46 +000012962 if (all_ins(m))
12963 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012964
Victor Stinner8c62be82010-05-06 00:08:46 +000012965 if (setup_confname_tables(m))
12966 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012967
Victor Stinner8c62be82010-05-06 00:08:46 +000012968 Py_INCREF(PyExc_OSError);
12969 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012970
Guido van Rossumb3d39562000-01-31 18:41:26 +000012971#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012972 if (posix_putenv_garbage == NULL)
12973 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012974#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012975
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012977#if defined(HAVE_WAITID) && !defined(__APPLE__)
12978 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012979 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12980 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012981#endif
12982
Christian Heimes25827622013-10-12 01:27:08 +020012983 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012984 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12985 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12986 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012987 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12988 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 structseq_new = StatResultType.tp_new;
12990 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012991
Christian Heimes25827622013-10-12 01:27:08 +020012992 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012993 if (PyStructSequence_InitType2(&StatVFSResultType,
12994 &statvfs_result_desc) < 0)
12995 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012996#ifdef NEED_TICKS_PER_SECOND
12997# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012998 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012999# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013000 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013001# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013002 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013003# endif
13004#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013005
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013006#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013007 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013008 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13009 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013010 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013011#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013012
13013 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013014 if (PyStructSequence_InitType2(&TerminalSizeType,
13015 &TerminalSize_desc) < 0)
13016 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013017
13018 /* initialize scandir types */
13019 if (PyType_Ready(&ScandirIteratorType) < 0)
13020 return NULL;
13021 if (PyType_Ready(&DirEntryType) < 0)
13022 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013023 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013024#if defined(HAVE_WAITID) && !defined(__APPLE__)
13025 Py_INCREF((PyObject*) &WaitidResultType);
13026 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13027#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013028 Py_INCREF((PyObject*) &StatResultType);
13029 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13030 Py_INCREF((PyObject*) &StatVFSResultType);
13031 PyModule_AddObject(m, "statvfs_result",
13032 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013033
13034#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013035 Py_INCREF(&SchedParamType);
13036 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013037#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013038
Larry Hastings605a62d2012-06-24 04:33:36 -070013039 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013040 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13041 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013042 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13043
13044 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013045 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13046 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013047 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13048
Thomas Wouters477c8d52006-05-27 19:21:47 +000013049#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013050 /*
13051 * Step 2 of weak-linking support on Mac OS X.
13052 *
13053 * The code below removes functions that are not available on the
13054 * currently active platform.
13055 *
13056 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013057 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013058 * OSX 10.4.
13059 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013060#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013061 if (fstatvfs == NULL) {
13062 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13063 return NULL;
13064 }
13065 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013066#endif /* HAVE_FSTATVFS */
13067
13068#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013069 if (statvfs == NULL) {
13070 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13071 return NULL;
13072 }
13073 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013074#endif /* HAVE_STATVFS */
13075
13076# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013077 if (lchown == NULL) {
13078 if (PyObject_DelAttrString(m, "lchown") == -1) {
13079 return NULL;
13080 }
13081 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013082#endif /* HAVE_LCHOWN */
13083
13084
13085#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013086
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013087 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013088 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13089
Larry Hastings6fe20b32012-04-19 15:07:49 -070013090 billion = PyLong_FromLong(1000000000);
13091 if (!billion)
13092 return NULL;
13093
Larry Hastings9cf065c2012-06-22 16:30:09 -070013094 /* suppress "function not used" warnings */
13095 {
13096 int ignored;
13097 fd_specified("", -1);
13098 follow_symlinks_specified("", 1);
13099 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13100 dir_fd_converter(Py_None, &ignored);
13101 dir_fd_unavailable(Py_None, &ignored);
13102 }
13103
13104 /*
13105 * provide list of locally available functions
13106 * so os.py can populate support_* lists
13107 */
13108 list = PyList_New(0);
13109 if (!list)
13110 return NULL;
13111 for (trace = have_functions; *trace; trace++) {
13112 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13113 if (!unicode)
13114 return NULL;
13115 if (PyList_Append(list, unicode))
13116 return NULL;
13117 Py_DECREF(unicode);
13118 }
13119 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013120
13121 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013122 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013123
13124 initialized = 1;
13125
Victor Stinner8c62be82010-05-06 00:08:46 +000013126 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013127}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013128
13129#ifdef __cplusplus
13130}
13131#endif