blob: 0a9123b61bdc06a531e1b13024c70da27680069a [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{
Serhiy Storchaka680fea42017-04-19 21:22:49 +03006653 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 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);
Serhiy Storchaka680fea42017-04-19 21:22:49 +03006661 if (len < 0) {
6662 return NULL;
6663 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 if (len > MAX_GROUPS) {
6665 PyErr_SetString(PyExc_ValueError, "too many groups");
6666 return NULL;
6667 }
6668 for(i = 0; i < len; i++) {
6669 PyObject *elem;
6670 elem = PySequence_GetItem(groups, i);
6671 if (!elem)
6672 return NULL;
6673 if (!PyLong_Check(elem)) {
6674 PyErr_SetString(PyExc_TypeError,
6675 "groups must be integers");
6676 Py_DECREF(elem);
6677 return NULL;
6678 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006679 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 Py_DECREF(elem);
6681 return NULL;
6682 }
6683 }
6684 Py_DECREF(elem);
6685 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006686
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 if (setgroups(len, grouplist) < 0)
6688 return posix_error();
6689 Py_INCREF(Py_None);
6690 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006691}
6692#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006693
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006694#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6695static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006696wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006697{
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 PyObject *result;
6699 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006700 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006701
Victor Stinner8c62be82010-05-06 00:08:46 +00006702 if (pid == -1)
6703 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006704
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 if (struct_rusage == NULL) {
6706 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6707 if (m == NULL)
6708 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006709 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 Py_DECREF(m);
6711 if (struct_rusage == NULL)
6712 return NULL;
6713 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006714
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6716 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6717 if (!result)
6718 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006719
6720#ifndef doubletime
6721#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6722#endif
6723
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006725 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006726 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006727 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006728#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6730 SET_INT(result, 2, ru->ru_maxrss);
6731 SET_INT(result, 3, ru->ru_ixrss);
6732 SET_INT(result, 4, ru->ru_idrss);
6733 SET_INT(result, 5, ru->ru_isrss);
6734 SET_INT(result, 6, ru->ru_minflt);
6735 SET_INT(result, 7, ru->ru_majflt);
6736 SET_INT(result, 8, ru->ru_nswap);
6737 SET_INT(result, 9, ru->ru_inblock);
6738 SET_INT(result, 10, ru->ru_oublock);
6739 SET_INT(result, 11, ru->ru_msgsnd);
6740 SET_INT(result, 12, ru->ru_msgrcv);
6741 SET_INT(result, 13, ru->ru_nsignals);
6742 SET_INT(result, 14, ru->ru_nvcsw);
6743 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006744#undef SET_INT
6745
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 if (PyErr_Occurred()) {
6747 Py_DECREF(result);
6748 return NULL;
6749 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006750
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006752}
6753#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6754
Larry Hastings2f936352014-08-05 14:04:04 +10006755
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006756#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006757/*[clinic input]
6758os.wait3
6759
6760 options: int
6761Wait for completion of a child process.
6762
6763Returns a tuple of information about the child process:
6764 (pid, status, rusage)
6765[clinic start generated code]*/
6766
Larry Hastings2f936352014-08-05 14:04:04 +10006767static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006768os_wait3_impl(PyObject *module, int options)
6769/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006770{
Victor Stinner8c62be82010-05-06 00:08:46 +00006771 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006773 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 WAIT_TYPE status;
6775 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006777 do {
6778 Py_BEGIN_ALLOW_THREADS
6779 pid = wait3(&status, options, &ru);
6780 Py_END_ALLOW_THREADS
6781 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6782 if (pid < 0)
6783 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006784
Victor Stinner4195b5c2012-02-08 23:03:19 +01006785 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006786}
6787#endif /* HAVE_WAIT3 */
6788
Larry Hastings2f936352014-08-05 14:04:04 +10006789
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006790#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006791/*[clinic input]
6792
6793os.wait4
6794
6795 pid: pid_t
6796 options: int
6797
6798Wait for completion of a specific child process.
6799
6800Returns a tuple of information about the child process:
6801 (pid, status, rusage)
6802[clinic start generated code]*/
6803
Larry Hastings2f936352014-08-05 14:04:04 +10006804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006805os_wait4_impl(PyObject *module, pid_t pid, int options)
6806/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006807{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006808 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006810 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 WAIT_TYPE status;
6812 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006813
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006814 do {
6815 Py_BEGIN_ALLOW_THREADS
6816 res = wait4(pid, &status, options, &ru);
6817 Py_END_ALLOW_THREADS
6818 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6819 if (res < 0)
6820 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006821
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006822 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006823}
6824#endif /* HAVE_WAIT4 */
6825
Larry Hastings2f936352014-08-05 14:04:04 +10006826
Ross Lagerwall7807c352011-03-17 20:20:30 +02006827#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006828/*[clinic input]
6829os.waitid
6830
6831 idtype: idtype_t
6832 Must be one of be P_PID, P_PGID or P_ALL.
6833 id: id_t
6834 The id to wait on.
6835 options: int
6836 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6837 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6838 /
6839
6840Returns the result of waiting for a process or processes.
6841
6842Returns either waitid_result or None if WNOHANG is specified and there are
6843no children in a waitable state.
6844[clinic start generated code]*/
6845
Larry Hastings2f936352014-08-05 14:04:04 +10006846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006847os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6848/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006849{
6850 PyObject *result;
6851 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006852 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006853 siginfo_t si;
6854 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006855
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006856 do {
6857 Py_BEGIN_ALLOW_THREADS
6858 res = waitid(idtype, id, &si, options);
6859 Py_END_ALLOW_THREADS
6860 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6861 if (res < 0)
6862 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006863
6864 if (si.si_pid == 0)
6865 Py_RETURN_NONE;
6866
6867 result = PyStructSequence_New(&WaitidResultType);
6868 if (!result)
6869 return NULL;
6870
6871 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006872 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006873 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6874 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6875 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6876 if (PyErr_Occurred()) {
6877 Py_DECREF(result);
6878 return NULL;
6879 }
6880
6881 return result;
6882}
Larry Hastings2f936352014-08-05 14:04:04 +10006883#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006884
Larry Hastings2f936352014-08-05 14:04:04 +10006885
6886#if defined(HAVE_WAITPID)
6887/*[clinic input]
6888os.waitpid
6889 pid: pid_t
6890 options: int
6891 /
6892
6893Wait for completion of a given child process.
6894
6895Returns a tuple of information regarding the child process:
6896 (pid, status)
6897
6898The options argument is ignored on Windows.
6899[clinic start generated code]*/
6900
Larry Hastings2f936352014-08-05 14:04:04 +10006901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006902os_waitpid_impl(PyObject *module, pid_t pid, int options)
6903/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006904{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006905 pid_t res;
6906 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 WAIT_TYPE status;
6908 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006909
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006910 do {
6911 Py_BEGIN_ALLOW_THREADS
6912 res = waitpid(pid, &status, options);
6913 Py_END_ALLOW_THREADS
6914 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6915 if (res < 0)
6916 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006918 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006919}
Tim Petersab034fa2002-02-01 11:27:43 +00006920#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006921/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006922/*[clinic input]
6923os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006924 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006925 options: int
6926 /
6927
6928Wait for completion of a given process.
6929
6930Returns a tuple of information regarding the process:
6931 (pid, status << 8)
6932
6933The options argument is ignored on Windows.
6934[clinic start generated code]*/
6935
Larry Hastings2f936352014-08-05 14:04:04 +10006936static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006937os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006938/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006939{
6940 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006941 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006942 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006943
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006944 do {
6945 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006946 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006947 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006948 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006949 Py_END_ALLOW_THREADS
6950 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006951 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006952 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006953
Victor Stinner8c62be82010-05-06 00:08:46 +00006954 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006955 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006956}
Larry Hastings2f936352014-08-05 14:04:04 +10006957#endif
6958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006959
Guido van Rossumad0ee831995-03-01 10:34:45 +00006960#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006961/*[clinic input]
6962os.wait
6963
6964Wait for completion of a child process.
6965
6966Returns a tuple of information about the child process:
6967 (pid, status)
6968[clinic start generated code]*/
6969
Larry Hastings2f936352014-08-05 14:04:04 +10006970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006971os_wait_impl(PyObject *module)
6972/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006973{
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006975 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 WAIT_TYPE status;
6977 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006978
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006979 do {
6980 Py_BEGIN_ALLOW_THREADS
6981 pid = wait(&status);
6982 Py_END_ALLOW_THREADS
6983 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6984 if (pid < 0)
6985 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006986
Victor Stinner8c62be82010-05-06 00:08:46 +00006987 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006988}
Larry Hastings2f936352014-08-05 14:04:04 +10006989#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006991
Larry Hastings9cf065c2012-06-22 16:30:09 -07006992#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6993PyDoc_STRVAR(readlink__doc__,
6994"readlink(path, *, dir_fd=None) -> path\n\n\
6995Return a string representing the path to which the symbolic link points.\n\
6996\n\
6997If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6998 and path should be relative; path will then be relative to that directory.\n\
6999dir_fd may not be implemented on your platform.\n\
7000 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007001#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007002
Guido van Rossumb6775db1994-08-01 11:34:53 +00007003#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007004
Larry Hastings2f936352014-08-05 14:04:04 +10007005/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007006static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007007posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007008{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007009 path_t path;
7010 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007011 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007012 ssize_t length;
7013 PyObject *return_value = NULL;
7014 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007015
Larry Hastings9cf065c2012-06-22 16:30:09 -07007016 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007017 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007018 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7019 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007020 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007022
Victor Stinner8c62be82010-05-06 00:08:46 +00007023 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007024#ifdef HAVE_READLINKAT
7025 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007026 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007027 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007028#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007029 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007030 Py_END_ALLOW_THREADS
7031
7032 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007033 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007034 goto exit;
7035 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007036 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007037
7038 if (PyUnicode_Check(path.object))
7039 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7040 else
7041 return_value = PyBytes_FromStringAndSize(buffer, length);
7042exit:
7043 path_cleanup(&path);
7044 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007045}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007046
Guido van Rossumb6775db1994-08-01 11:34:53 +00007047#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007048
Larry Hastings2f936352014-08-05 14:04:04 +10007049#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7050
7051static PyObject *
7052win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7053{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007054 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007055 DWORD n_bytes_returned;
7056 DWORD io_result;
7057 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007058 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007059 HANDLE reparse_point_handle;
7060
Martin Panter70214ad2016-08-04 02:38:59 +00007061 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7062 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007063 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007064
7065 static char *keywords[] = {"path", "dir_fd", NULL};
7066
7067 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7068 &po,
7069 dir_fd_unavailable, &dir_fd
7070 ))
7071 return NULL;
7072
7073 path = PyUnicode_AsUnicode(po);
7074 if (path == NULL)
7075 return NULL;
7076
7077 /* First get a handle to the reparse point */
7078 Py_BEGIN_ALLOW_THREADS
7079 reparse_point_handle = CreateFileW(
7080 path,
7081 0,
7082 0,
7083 0,
7084 OPEN_EXISTING,
7085 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7086 0);
7087 Py_END_ALLOW_THREADS
7088
7089 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7090 return win32_error_object("readlink", po);
7091
7092 Py_BEGIN_ALLOW_THREADS
7093 /* New call DeviceIoControl to read the reparse point */
7094 io_result = DeviceIoControl(
7095 reparse_point_handle,
7096 FSCTL_GET_REPARSE_POINT,
7097 0, 0, /* in buffer */
7098 target_buffer, sizeof(target_buffer),
7099 &n_bytes_returned,
7100 0 /* we're not using OVERLAPPED_IO */
7101 );
7102 CloseHandle(reparse_point_handle);
7103 Py_END_ALLOW_THREADS
7104
7105 if (io_result==0)
7106 return win32_error_object("readlink", po);
7107
7108 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7109 {
7110 PyErr_SetString(PyExc_ValueError,
7111 "not a symbolic link");
7112 return NULL;
7113 }
7114 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7115 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7116
7117 result = PyUnicode_FromWideChar(print_name,
7118 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7119 return result;
7120}
7121
7122#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7123
7124
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007125
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007127
7128#if defined(MS_WINDOWS)
7129
7130/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007131static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007132
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007134check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135{
7136 HINSTANCE hKernel32;
7137 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007138 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007139 return 1;
7140 hKernel32 = GetModuleHandleW(L"KERNEL32");
7141 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7142 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007143 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007144}
7145
Victor Stinner31b3b922013-06-05 01:49:17 +02007146/* Remove the last portion of the path */
7147static void
7148_dirnameW(WCHAR *path)
7149{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007150 WCHAR *ptr;
7151
7152 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007153 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007154 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007155 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007156 }
7157 *ptr = 0;
7158}
7159
Victor Stinner31b3b922013-06-05 01:49:17 +02007160/* Is this path absolute? */
7161static int
7162_is_absW(const WCHAR *path)
7163{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007164 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7165
7166}
7167
Victor Stinner31b3b922013-06-05 01:49:17 +02007168/* join root and rest with a backslash */
7169static void
7170_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7171{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007172 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007173
Victor Stinner31b3b922013-06-05 01:49:17 +02007174 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007175 wcscpy(dest_path, rest);
7176 return;
7177 }
7178
7179 root_len = wcslen(root);
7180
7181 wcscpy(dest_path, root);
7182 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007183 dest_path[root_len] = L'\\';
7184 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007185 }
7186 wcscpy(dest_path+root_len, rest);
7187}
7188
Victor Stinner31b3b922013-06-05 01:49:17 +02007189/* Return True if the path at src relative to dest is a directory */
7190static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007191_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007192{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007193 WIN32_FILE_ATTRIBUTE_DATA src_info;
7194 WCHAR dest_parent[MAX_PATH];
7195 WCHAR src_resolved[MAX_PATH] = L"";
7196
7197 /* dest_parent = os.path.dirname(dest) */
7198 wcscpy(dest_parent, dest);
7199 _dirnameW(dest_parent);
7200 /* src_resolved = os.path.join(dest_parent, src) */
7201 _joinW(src_resolved, dest_parent, src);
7202 return (
7203 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7204 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7205 );
7206}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007207#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007208
Larry Hastings2f936352014-08-05 14:04:04 +10007209
7210/*[clinic input]
7211os.symlink
7212 src: path_t
7213 dst: path_t
7214 target_is_directory: bool = False
7215 *
7216 dir_fd: dir_fd(requires='symlinkat')=None
7217
7218# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7219
7220Create a symbolic link pointing to src named dst.
7221
7222target_is_directory is required on Windows if the target is to be
7223 interpreted as a directory. (On Windows, symlink requires
7224 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7225 target_is_directory is ignored on non-Windows platforms.
7226
7227If dir_fd is not None, it should be a file descriptor open to a directory,
7228 and path should be relative; path will then be relative to that directory.
7229dir_fd may not be implemented on your platform.
7230 If it is unavailable, using it will raise a NotImplementedError.
7231
7232[clinic start generated code]*/
7233
Larry Hastings2f936352014-08-05 14:04:04 +10007234static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007235os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007236 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007237/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007238{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007239#ifdef MS_WINDOWS
7240 DWORD result;
7241#else
7242 int result;
7243#endif
7244
Larry Hastings9cf065c2012-06-22 16:30:09 -07007245#ifdef MS_WINDOWS
7246 if (!check_CreateSymbolicLink()) {
7247 PyErr_SetString(PyExc_NotImplementedError,
7248 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007249 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007250 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007251 if (!win32_can_symlink) {
7252 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007253 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007254 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007255#endif
7256
Larry Hastings2f936352014-08-05 14:04:04 +10007257 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007258 PyErr_SetString(PyExc_ValueError,
7259 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007260 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007261 }
7262
7263#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007264
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007266 /* if src is a directory, ensure target_is_directory==1 */
7267 target_is_directory |= _check_dirW(src->wide, dst->wide);
7268 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7269 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007270 Py_END_ALLOW_THREADS
7271
Larry Hastings2f936352014-08-05 14:04:04 +10007272 if (!result)
7273 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007274
7275#else
7276
7277 Py_BEGIN_ALLOW_THREADS
7278#if HAVE_SYMLINKAT
7279 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007280 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007281 else
7282#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007283 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007284 Py_END_ALLOW_THREADS
7285
Larry Hastings2f936352014-08-05 14:04:04 +10007286 if (result)
7287 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007288#endif
7289
Larry Hastings2f936352014-08-05 14:04:04 +10007290 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007291}
7292#endif /* HAVE_SYMLINK */
7293
Larry Hastings9cf065c2012-06-22 16:30:09 -07007294
Brian Curtind40e6f72010-07-08 21:39:08 +00007295
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007296
Larry Hastings605a62d2012-06-24 04:33:36 -07007297static PyStructSequence_Field times_result_fields[] = {
7298 {"user", "user time"},
7299 {"system", "system time"},
7300 {"children_user", "user time of children"},
7301 {"children_system", "system time of children"},
7302 {"elapsed", "elapsed time since an arbitrary point in the past"},
7303 {NULL}
7304};
7305
7306PyDoc_STRVAR(times_result__doc__,
7307"times_result: Result from os.times().\n\n\
7308This object may be accessed either as a tuple of\n\
7309 (user, system, children_user, children_system, elapsed),\n\
7310or via the attributes user, system, children_user, children_system,\n\
7311and elapsed.\n\
7312\n\
7313See os.times for more information.");
7314
7315static PyStructSequence_Desc times_result_desc = {
7316 "times_result", /* name */
7317 times_result__doc__, /* doc */
7318 times_result_fields,
7319 5
7320};
7321
7322static PyTypeObject TimesResultType;
7323
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007324#ifdef MS_WINDOWS
7325#define HAVE_TIMES /* mandatory, for the method table */
7326#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007327
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007328#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007329
7330static PyObject *
7331build_times_result(double user, double system,
7332 double children_user, double children_system,
7333 double elapsed)
7334{
7335 PyObject *value = PyStructSequence_New(&TimesResultType);
7336 if (value == NULL)
7337 return NULL;
7338
7339#define SET(i, field) \
7340 { \
7341 PyObject *o = PyFloat_FromDouble(field); \
7342 if (!o) { \
7343 Py_DECREF(value); \
7344 return NULL; \
7345 } \
7346 PyStructSequence_SET_ITEM(value, i, o); \
7347 } \
7348
7349 SET(0, user);
7350 SET(1, system);
7351 SET(2, children_user);
7352 SET(3, children_system);
7353 SET(4, elapsed);
7354
7355#undef SET
7356
7357 return value;
7358}
7359
Larry Hastings605a62d2012-06-24 04:33:36 -07007360
Larry Hastings2f936352014-08-05 14:04:04 +10007361#ifndef MS_WINDOWS
7362#define NEED_TICKS_PER_SECOND
7363static long ticks_per_second = -1;
7364#endif /* MS_WINDOWS */
7365
7366/*[clinic input]
7367os.times
7368
7369Return a collection containing process timing information.
7370
7371The object returned behaves like a named tuple with these fields:
7372 (utime, stime, cutime, cstime, elapsed_time)
7373All fields are floating point numbers.
7374[clinic start generated code]*/
7375
Larry Hastings2f936352014-08-05 14:04:04 +10007376static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007377os_times_impl(PyObject *module)
7378/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007379#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007380{
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 FILETIME create, exit, kernel, user;
7382 HANDLE hProc;
7383 hProc = GetCurrentProcess();
7384 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7385 /* The fields of a FILETIME structure are the hi and lo part
7386 of a 64-bit value expressed in 100 nanosecond units.
7387 1e7 is one second in such units; 1e-7 the inverse.
7388 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7389 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007390 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007391 (double)(user.dwHighDateTime*429.4967296 +
7392 user.dwLowDateTime*1e-7),
7393 (double)(kernel.dwHighDateTime*429.4967296 +
7394 kernel.dwLowDateTime*1e-7),
7395 (double)0,
7396 (double)0,
7397 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007398}
Larry Hastings2f936352014-08-05 14:04:04 +10007399#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007400{
Larry Hastings2f936352014-08-05 14:04:04 +10007401
7402
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007403 struct tms t;
7404 clock_t c;
7405 errno = 0;
7406 c = times(&t);
7407 if (c == (clock_t) -1)
7408 return posix_error();
7409 return build_times_result(
7410 (double)t.tms_utime / ticks_per_second,
7411 (double)t.tms_stime / ticks_per_second,
7412 (double)t.tms_cutime / ticks_per_second,
7413 (double)t.tms_cstime / ticks_per_second,
7414 (double)c / ticks_per_second);
7415}
Larry Hastings2f936352014-08-05 14:04:04 +10007416#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007417#endif /* HAVE_TIMES */
7418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007419
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007420#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007421/*[clinic input]
7422os.getsid
7423
7424 pid: pid_t
7425 /
7426
7427Call the system call getsid(pid) and return the result.
7428[clinic start generated code]*/
7429
Larry Hastings2f936352014-08-05 14:04:04 +10007430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007431os_getsid_impl(PyObject *module, pid_t pid)
7432/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007433{
Victor Stinner8c62be82010-05-06 00:08:46 +00007434 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 sid = getsid(pid);
7436 if (sid < 0)
7437 return posix_error();
7438 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007439}
7440#endif /* HAVE_GETSID */
7441
7442
Guido van Rossumb6775db1994-08-01 11:34:53 +00007443#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007444/*[clinic input]
7445os.setsid
7446
7447Call the system call setsid().
7448[clinic start generated code]*/
7449
Larry Hastings2f936352014-08-05 14:04:04 +10007450static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007451os_setsid_impl(PyObject *module)
7452/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007453{
Victor Stinner8c62be82010-05-06 00:08:46 +00007454 if (setsid() < 0)
7455 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007456 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007457}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007458#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007459
Larry Hastings2f936352014-08-05 14:04:04 +10007460
Guido van Rossumb6775db1994-08-01 11:34:53 +00007461#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007462/*[clinic input]
7463os.setpgid
7464
7465 pid: pid_t
7466 pgrp: pid_t
7467 /
7468
7469Call the system call setpgid(pid, pgrp).
7470[clinic start generated code]*/
7471
Larry Hastings2f936352014-08-05 14:04:04 +10007472static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007473os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7474/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007475{
Victor Stinner8c62be82010-05-06 00:08:46 +00007476 if (setpgid(pid, pgrp) < 0)
7477 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007478 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007479}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007480#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007482
Guido van Rossumb6775db1994-08-01 11:34:53 +00007483#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007484/*[clinic input]
7485os.tcgetpgrp
7486
7487 fd: int
7488 /
7489
7490Return the process group associated with the terminal specified by fd.
7491[clinic start generated code]*/
7492
Larry Hastings2f936352014-08-05 14:04:04 +10007493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007494os_tcgetpgrp_impl(PyObject *module, int fd)
7495/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007496{
7497 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007498 if (pgid < 0)
7499 return posix_error();
7500 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007501}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007502#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007504
Guido van Rossumb6775db1994-08-01 11:34:53 +00007505#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007506/*[clinic input]
7507os.tcsetpgrp
7508
7509 fd: int
7510 pgid: pid_t
7511 /
7512
7513Set the process group associated with the terminal specified by fd.
7514[clinic start generated code]*/
7515
Larry Hastings2f936352014-08-05 14:04:04 +10007516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007517os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7518/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007519{
Victor Stinner8c62be82010-05-06 00:08:46 +00007520 if (tcsetpgrp(fd, pgid) < 0)
7521 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007522 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007523}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007524#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007525
Guido van Rossum687dd131993-05-17 08:34:16 +00007526/* Functions acting on file descriptors */
7527
Victor Stinnerdaf45552013-08-28 00:53:59 +02007528#ifdef O_CLOEXEC
7529extern int _Py_open_cloexec_works;
7530#endif
7531
Larry Hastings2f936352014-08-05 14:04:04 +10007532
7533/*[clinic input]
7534os.open -> int
7535 path: path_t
7536 flags: int
7537 mode: int = 0o777
7538 *
7539 dir_fd: dir_fd(requires='openat') = None
7540
7541# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7542
7543Open a file for low level IO. Returns a file descriptor (integer).
7544
7545If dir_fd is not None, it should be a file descriptor open to a directory,
7546 and path should be relative; path will then be relative to that directory.
7547dir_fd may not be implemented on your platform.
7548 If it is unavailable, using it will raise a NotImplementedError.
7549[clinic start generated code]*/
7550
Larry Hastings2f936352014-08-05 14:04:04 +10007551static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007552os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7553/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007554{
7555 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007556 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007557
Victor Stinnerdaf45552013-08-28 00:53:59 +02007558#ifdef O_CLOEXEC
7559 int *atomic_flag_works = &_Py_open_cloexec_works;
7560#elif !defined(MS_WINDOWS)
7561 int *atomic_flag_works = NULL;
7562#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007563
Victor Stinnerdaf45552013-08-28 00:53:59 +02007564#ifdef MS_WINDOWS
7565 flags |= O_NOINHERIT;
7566#elif defined(O_CLOEXEC)
7567 flags |= O_CLOEXEC;
7568#endif
7569
Steve Dower8fc89802015-04-12 00:26:27 -04007570 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007571 do {
7572 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007573#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007574 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007575#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007576#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007577 if (dir_fd != DEFAULT_DIR_FD)
7578 fd = openat(dir_fd, path->narrow, flags, mode);
7579 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007580#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007581 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007582#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007583 Py_END_ALLOW_THREADS
7584 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007585 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007586
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007587 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007588 if (!async_err)
7589 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007590 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007591 }
7592
Victor Stinnerdaf45552013-08-28 00:53:59 +02007593#ifndef MS_WINDOWS
7594 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7595 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007596 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007597 }
7598#endif
7599
Larry Hastings2f936352014-08-05 14:04:04 +10007600 return fd;
7601}
7602
7603
7604/*[clinic input]
7605os.close
7606
7607 fd: int
7608
7609Close a file descriptor.
7610[clinic start generated code]*/
7611
Barry Warsaw53699e91996-12-10 23:23:01 +00007612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007613os_close_impl(PyObject *module, int fd)
7614/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007615{
Larry Hastings2f936352014-08-05 14:04:04 +10007616 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007617 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7618 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7619 * for more details.
7620 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007622 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007623 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007624 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 Py_END_ALLOW_THREADS
7626 if (res < 0)
7627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007628 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007629}
7630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007631
Larry Hastings2f936352014-08-05 14:04:04 +10007632/*[clinic input]
7633os.closerange
7634
7635 fd_low: int
7636 fd_high: int
7637 /
7638
7639Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7640[clinic start generated code]*/
7641
Larry Hastings2f936352014-08-05 14:04:04 +10007642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007643os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7644/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007645{
7646 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007647 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007648 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007649 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007650 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007651 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007652 Py_END_ALLOW_THREADS
7653 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007654}
7655
7656
Larry Hastings2f936352014-08-05 14:04:04 +10007657/*[clinic input]
7658os.dup -> int
7659
7660 fd: int
7661 /
7662
7663Return a duplicate of a file descriptor.
7664[clinic start generated code]*/
7665
Larry Hastings2f936352014-08-05 14:04:04 +10007666static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007667os_dup_impl(PyObject *module, int fd)
7668/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007669{
7670 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007671}
7672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007673
Larry Hastings2f936352014-08-05 14:04:04 +10007674/*[clinic input]
7675os.dup2
7676 fd: int
7677 fd2: int
7678 inheritable: bool=True
7679
7680Duplicate file descriptor.
7681[clinic start generated code]*/
7682
Larry Hastings2f936352014-08-05 14:04:04 +10007683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007684os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7685/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007686{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007687 int res;
7688#if defined(HAVE_DUP3) && \
7689 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7690 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7691 int dup3_works = -1;
7692#endif
7693
Steve Dower940f33a2016-09-08 11:21:54 -07007694 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007696
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007697 /* dup2() can fail with EINTR if the target FD is already open, because it
7698 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7699 * upon close(), and therefore below.
7700 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007701#ifdef MS_WINDOWS
7702 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007703 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007705 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007706 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007707 if (res < 0)
7708 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007709
7710 /* Character files like console cannot be make non-inheritable */
7711 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7712 close(fd2);
7713 return NULL;
7714 }
7715
7716#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7717 Py_BEGIN_ALLOW_THREADS
7718 if (!inheritable)
7719 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7720 else
7721 res = dup2(fd, fd2);
7722 Py_END_ALLOW_THREADS
7723 if (res < 0)
7724 return posix_error();
7725
7726#else
7727
7728#ifdef HAVE_DUP3
7729 if (!inheritable && dup3_works != 0) {
7730 Py_BEGIN_ALLOW_THREADS
7731 res = dup3(fd, fd2, O_CLOEXEC);
7732 Py_END_ALLOW_THREADS
7733 if (res < 0) {
7734 if (dup3_works == -1)
7735 dup3_works = (errno != ENOSYS);
7736 if (dup3_works)
7737 return posix_error();
7738 }
7739 }
7740
7741 if (inheritable || dup3_works == 0)
7742 {
7743#endif
7744 Py_BEGIN_ALLOW_THREADS
7745 res = dup2(fd, fd2);
7746 Py_END_ALLOW_THREADS
7747 if (res < 0)
7748 return posix_error();
7749
7750 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7751 close(fd2);
7752 return NULL;
7753 }
7754#ifdef HAVE_DUP3
7755 }
7756#endif
7757
7758#endif
7759
Larry Hastings2f936352014-08-05 14:04:04 +10007760 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007761}
7762
Larry Hastings2f936352014-08-05 14:04:04 +10007763
Ross Lagerwall7807c352011-03-17 20:20:30 +02007764#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007765/*[clinic input]
7766os.lockf
7767
7768 fd: int
7769 An open file descriptor.
7770 command: int
7771 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7772 length: Py_off_t
7773 The number of bytes to lock, starting at the current position.
7774 /
7775
7776Apply, test or remove a POSIX lock on an open file descriptor.
7777
7778[clinic start generated code]*/
7779
Larry Hastings2f936352014-08-05 14:04:04 +10007780static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007781os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7782/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007783{
7784 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007785
7786 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007787 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007788 Py_END_ALLOW_THREADS
7789
7790 if (res < 0)
7791 return posix_error();
7792
7793 Py_RETURN_NONE;
7794}
Larry Hastings2f936352014-08-05 14:04:04 +10007795#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007796
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007797
Larry Hastings2f936352014-08-05 14:04:04 +10007798/*[clinic input]
7799os.lseek -> Py_off_t
7800
7801 fd: int
7802 position: Py_off_t
7803 how: int
7804 /
7805
7806Set the position of a file descriptor. Return the new position.
7807
7808Return the new cursor position in number of bytes
7809relative to the beginning of the file.
7810[clinic start generated code]*/
7811
Larry Hastings2f936352014-08-05 14:04:04 +10007812static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007813os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7814/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007815{
7816 Py_off_t result;
7817
Guido van Rossum687dd131993-05-17 08:34:16 +00007818#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7820 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007821 case 0: how = SEEK_SET; break;
7822 case 1: how = SEEK_CUR; break;
7823 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007825#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007826
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007828 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007829
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007831 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007832#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007833 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007834#else
Larry Hastings2f936352014-08-05 14:04:04 +10007835 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007836#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007837 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007839 if (result < 0)
7840 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007841
Larry Hastings2f936352014-08-05 14:04:04 +10007842 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007843}
7844
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007845
Larry Hastings2f936352014-08-05 14:04:04 +10007846/*[clinic input]
7847os.read
7848 fd: int
7849 length: Py_ssize_t
7850 /
7851
7852Read from a file descriptor. Returns a bytes object.
7853[clinic start generated code]*/
7854
Larry Hastings2f936352014-08-05 14:04:04 +10007855static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007856os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7857/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007858{
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 Py_ssize_t n;
7860 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007861
7862 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 errno = EINVAL;
7864 return posix_error();
7865 }
Larry Hastings2f936352014-08-05 14:04:04 +10007866
7867#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007868 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007869 if (length > INT_MAX)
7870 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007871#endif
7872
7873 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 if (buffer == NULL)
7875 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007876
Victor Stinner66aab0c2015-03-19 22:53:20 +01007877 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7878 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007880 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 }
Larry Hastings2f936352014-08-05 14:04:04 +10007882
7883 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007885
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007887}
7888
Ross Lagerwall7807c352011-03-17 20:20:30 +02007889#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7890 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007891static Py_ssize_t
Serhiy Storchaka680fea42017-04-19 21:22:49 +03007892iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007893{
Serhiy Storchaka680fea42017-04-19 21:22:49 +03007894 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007895 Py_ssize_t blen, total = 0;
7896
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007897 *iov = PyMem_New(struct iovec, cnt);
7898 if (*iov == NULL) {
7899 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007900 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007901 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007902
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007903 *buf = PyMem_New(Py_buffer, cnt);
7904 if (*buf == NULL) {
7905 PyMem_Del(*iov);
7906 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007907 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007908 }
7909
7910 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007911 PyObject *item = PySequence_GetItem(seq, i);
7912 if (item == NULL)
7913 goto fail;
7914 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7915 Py_DECREF(item);
7916 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007917 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007918 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007919 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007920 blen = (*buf)[i].len;
7921 (*iov)[i].iov_len = blen;
7922 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007923 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007924 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007925
7926fail:
7927 PyMem_Del(*iov);
7928 for (j = 0; j < i; j++) {
7929 PyBuffer_Release(&(*buf)[j]);
7930 }
7931 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007932 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007933}
7934
7935static void
7936iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7937{
7938 int i;
7939 PyMem_Del(iov);
7940 for (i = 0; i < cnt; i++) {
7941 PyBuffer_Release(&buf[i]);
7942 }
7943 PyMem_Del(buf);
7944}
7945#endif
7946
Larry Hastings2f936352014-08-05 14:04:04 +10007947
Ross Lagerwall7807c352011-03-17 20:20:30 +02007948#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007949/*[clinic input]
7950os.readv -> Py_ssize_t
7951
7952 fd: int
7953 buffers: object
7954 /
7955
7956Read from a file descriptor fd into an iterable of buffers.
7957
7958The buffers should be mutable buffers accepting bytes.
7959readv will transfer data into each buffer until it is full
7960and then move on to the next buffer in the sequence to hold
7961the rest of the data.
7962
7963readv returns the total number of bytes read,
7964which may be less than the total capacity of all the buffers.
7965[clinic start generated code]*/
7966
Larry Hastings2f936352014-08-05 14:04:04 +10007967static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007968os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7969/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007970{
Serhiy Storchaka680fea42017-04-19 21:22:49 +03007971 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007972 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007973 struct iovec *iov;
7974 Py_buffer *buf;
7975
Larry Hastings2f936352014-08-05 14:04:04 +10007976 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007977 PyErr_SetString(PyExc_TypeError,
7978 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007979 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007980 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007981
Larry Hastings2f936352014-08-05 14:04:04 +10007982 cnt = PySequence_Size(buffers);
Serhiy Storchaka680fea42017-04-19 21:22:49 +03007983 if (cnt < 0)
7984 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10007985
7986 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7987 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007988
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007989 do {
7990 Py_BEGIN_ALLOW_THREADS
7991 n = readv(fd, iov, cnt);
7992 Py_END_ALLOW_THREADS
7993 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007994
7995 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007996 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007997 if (!async_err)
7998 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007999 return -1;
8000 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008001
Larry Hastings2f936352014-08-05 14:04:04 +10008002 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008003}
Larry Hastings2f936352014-08-05 14:04:04 +10008004#endif /* HAVE_READV */
8005
Ross Lagerwall7807c352011-03-17 20:20:30 +02008006
8007#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008008/*[clinic input]
8009# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8010os.pread
8011
8012 fd: int
8013 length: int
8014 offset: Py_off_t
8015 /
8016
8017Read a number of bytes from a file descriptor starting at a particular offset.
8018
8019Read length bytes from file descriptor fd, starting at offset bytes from
8020the beginning of the file. The file offset remains unchanged.
8021[clinic start generated code]*/
8022
Larry Hastings2f936352014-08-05 14:04:04 +10008023static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008024os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8025/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008026{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008027 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008028 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008029 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008030
Larry Hastings2f936352014-08-05 14:04:04 +10008031 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008032 errno = EINVAL;
8033 return posix_error();
8034 }
Larry Hastings2f936352014-08-05 14:04:04 +10008035 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008036 if (buffer == NULL)
8037 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008038
8039 do {
8040 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008041 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008042 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008043 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008044 Py_END_ALLOW_THREADS
8045 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8046
Ross Lagerwall7807c352011-03-17 20:20:30 +02008047 if (n < 0) {
8048 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008049 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008050 }
Larry Hastings2f936352014-08-05 14:04:04 +10008051 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008052 _PyBytes_Resize(&buffer, n);
8053 return buffer;
8054}
Larry Hastings2f936352014-08-05 14:04:04 +10008055#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008056
Larry Hastings2f936352014-08-05 14:04:04 +10008057
8058/*[clinic input]
8059os.write -> Py_ssize_t
8060
8061 fd: int
8062 data: Py_buffer
8063 /
8064
8065Write a bytes object to a file descriptor.
8066[clinic start generated code]*/
8067
Larry Hastings2f936352014-08-05 14:04:04 +10008068static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008069os_write_impl(PyObject *module, int fd, Py_buffer *data)
8070/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008071{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008072 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008073}
8074
8075#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008076PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008077"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008078sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008080Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008081
Larry Hastings2f936352014-08-05 14:04:04 +10008082/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008083static PyObject *
8084posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8085{
8086 int in, out;
8087 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008088 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008089 off_t offset;
8090
8091#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8092#ifndef __APPLE__
8093 Py_ssize_t len;
8094#endif
8095 PyObject *headers = NULL, *trailers = NULL;
8096 Py_buffer *hbuf, *tbuf;
8097 off_t sbytes;
8098 struct sf_hdtr sf;
8099 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008100 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008101 static char *keywords[] = {"out", "in",
8102 "offset", "count",
8103 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008105 sf.headers = NULL;
8106 sf.trailers = NULL;
8107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008108#ifdef __APPLE__
8109 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008110 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008111#else
8112 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008113 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008114#endif
8115 &headers, &trailers, &flags))
8116 return NULL;
8117 if (headers != NULL) {
8118 if (!PySequence_Check(headers)) {
8119 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008120 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008121 return NULL;
8122 } else {
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008123 Py_ssize_t i = PySequence_Size(headers);
8124 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008125 return NULL;
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008126 if (i > INT_MAX) {
8127 PyErr_SetString(PyExc_OverflowError,
8128 "sendfile() header is too large");
8129 return NULL;
8130 }
8131 if (i > 0) {
8132 sf.hdr_cnt = (int)i;
8133 i = iov_setup(&(sf.headers), &hbuf,
8134 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8135 if (i < 0)
8136 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008137#ifdef __APPLE__
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008138 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008139#endif
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008140 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008141 }
8142 }
8143 if (trailers != NULL) {
8144 if (!PySequence_Check(trailers)) {
8145 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008146 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008147 return NULL;
8148 } else {
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008149 Py_ssize_t i = PySequence_Size(trailers);
8150 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008151 return NULL;
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008152 if (i > INT_MAX) {
8153 PyErr_SetString(PyExc_OverflowError,
8154 "sendfile() trailer is too large");
8155 return NULL;
8156 }
8157 if (i > 0) {
8158 sf.trl_cnt = (int)i;
8159 i = iov_setup(&(sf.trailers), &tbuf,
8160 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8161 if (i < 0)
8162 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008163#ifdef __APPLE__
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008164 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008165#endif
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008166 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008167 }
8168 }
8169
Steve Dower8fc89802015-04-12 00:26:27 -04008170 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008171 do {
8172 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008173#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008174 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008175#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008176 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008177#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008178 Py_END_ALLOW_THREADS
8179 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008180 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008181
8182 if (sf.headers != NULL)
8183 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8184 if (sf.trailers != NULL)
8185 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8186
8187 if (ret < 0) {
8188 if ((errno == EAGAIN) || (errno == EBUSY)) {
8189 if (sbytes != 0) {
8190 // some data has been sent
8191 goto done;
8192 }
8193 else {
8194 // no data has been sent; upper application is supposed
8195 // to retry on EAGAIN or EBUSY
8196 return posix_error();
8197 }
8198 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008199 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008200 }
8201 goto done;
8202
8203done:
8204 #if !defined(HAVE_LARGEFILE_SUPPORT)
8205 return Py_BuildValue("l", sbytes);
8206 #else
8207 return Py_BuildValue("L", sbytes);
8208 #endif
8209
8210#else
8211 Py_ssize_t count;
8212 PyObject *offobj;
8213 static char *keywords[] = {"out", "in",
8214 "offset", "count", NULL};
8215 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8216 keywords, &out, &in, &offobj, &count))
8217 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008218#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008219 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008220 do {
8221 Py_BEGIN_ALLOW_THREADS
8222 ret = sendfile(out, in, NULL, count);
8223 Py_END_ALLOW_THREADS
8224 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008225 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008226 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008227 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008228 }
8229#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008230 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008231 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008232
8233 do {
8234 Py_BEGIN_ALLOW_THREADS
8235 ret = sendfile(out, in, &offset, count);
8236 Py_END_ALLOW_THREADS
8237 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008238 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008239 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008240 return Py_BuildValue("n", ret);
8241#endif
8242}
Larry Hastings2f936352014-08-05 14:04:04 +10008243#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008244
Larry Hastings2f936352014-08-05 14:04:04 +10008245
8246/*[clinic input]
8247os.fstat
8248
8249 fd : int
8250
8251Perform a stat system call on the given file descriptor.
8252
8253Like stat(), but for an open file descriptor.
8254Equivalent to os.stat(fd).
8255[clinic start generated code]*/
8256
Larry Hastings2f936352014-08-05 14:04:04 +10008257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008258os_fstat_impl(PyObject *module, int fd)
8259/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008260{
Victor Stinner8c62be82010-05-06 00:08:46 +00008261 STRUCT_STAT st;
8262 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008263 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008264
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008265 do {
8266 Py_BEGIN_ALLOW_THREADS
8267 res = FSTAT(fd, &st);
8268 Py_END_ALLOW_THREADS
8269 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008271#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008272 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008273#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008274 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008275#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008276 }
Tim Peters5aa91602002-01-30 05:46:57 +00008277
Victor Stinner4195b5c2012-02-08 23:03:19 +01008278 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008279}
8280
Larry Hastings2f936352014-08-05 14:04:04 +10008281
8282/*[clinic input]
8283os.isatty -> bool
8284 fd: int
8285 /
8286
8287Return True if the fd is connected to a terminal.
8288
8289Return True if the file descriptor is an open file descriptor
8290connected to the slave end of a terminal.
8291[clinic start generated code]*/
8292
Larry Hastings2f936352014-08-05 14:04:04 +10008293static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008294os_isatty_impl(PyObject *module, int fd)
8295/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008296{
Steve Dower8fc89802015-04-12 00:26:27 -04008297 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008298 _Py_BEGIN_SUPPRESS_IPH
8299 return_value = isatty(fd);
8300 _Py_END_SUPPRESS_IPH
8301 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008302}
8303
8304
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008305#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008306/*[clinic input]
8307os.pipe
8308
8309Create a pipe.
8310
8311Returns a tuple of two file descriptors:
8312 (read_fd, write_fd)
8313[clinic start generated code]*/
8314
Larry Hastings2f936352014-08-05 14:04:04 +10008315static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008316os_pipe_impl(PyObject *module)
8317/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008318{
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008320#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008321 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008322 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008324#else
8325 int res;
8326#endif
8327
8328#ifdef MS_WINDOWS
8329 attr.nLength = sizeof(attr);
8330 attr.lpSecurityDescriptor = NULL;
8331 attr.bInheritHandle = FALSE;
8332
8333 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008334 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008335 ok = CreatePipe(&read, &write, &attr, 0);
8336 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008337 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8338 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008339 if (fds[0] == -1 || fds[1] == -1) {
8340 CloseHandle(read);
8341 CloseHandle(write);
8342 ok = 0;
8343 }
8344 }
Steve Dowerc3630612016-11-19 18:41:16 -08008345 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008346 Py_END_ALLOW_THREADS
8347
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008349 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008350#else
8351
8352#ifdef HAVE_PIPE2
8353 Py_BEGIN_ALLOW_THREADS
8354 res = pipe2(fds, O_CLOEXEC);
8355 Py_END_ALLOW_THREADS
8356
8357 if (res != 0 && errno == ENOSYS)
8358 {
8359#endif
8360 Py_BEGIN_ALLOW_THREADS
8361 res = pipe(fds);
8362 Py_END_ALLOW_THREADS
8363
8364 if (res == 0) {
8365 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8366 close(fds[0]);
8367 close(fds[1]);
8368 return NULL;
8369 }
8370 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8371 close(fds[0]);
8372 close(fds[1]);
8373 return NULL;
8374 }
8375 }
8376#ifdef HAVE_PIPE2
8377 }
8378#endif
8379
8380 if (res != 0)
8381 return PyErr_SetFromErrno(PyExc_OSError);
8382#endif /* !MS_WINDOWS */
8383 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008384}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008385#endif /* HAVE_PIPE */
8386
Larry Hastings2f936352014-08-05 14:04:04 +10008387
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008388#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008389/*[clinic input]
8390os.pipe2
8391
8392 flags: int
8393 /
8394
8395Create a pipe with flags set atomically.
8396
8397Returns a tuple of two file descriptors:
8398 (read_fd, write_fd)
8399
8400flags can be constructed by ORing together one or more of these values:
8401O_NONBLOCK, O_CLOEXEC.
8402[clinic start generated code]*/
8403
Larry Hastings2f936352014-08-05 14:04:04 +10008404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008405os_pipe2_impl(PyObject *module, int flags)
8406/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008407{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008408 int fds[2];
8409 int res;
8410
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008411 res = pipe2(fds, flags);
8412 if (res != 0)
8413 return posix_error();
8414 return Py_BuildValue("(ii)", fds[0], fds[1]);
8415}
8416#endif /* HAVE_PIPE2 */
8417
Larry Hastings2f936352014-08-05 14:04:04 +10008418
Ross Lagerwall7807c352011-03-17 20:20:30 +02008419#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008420/*[clinic input]
8421os.writev -> Py_ssize_t
8422 fd: int
8423 buffers: object
8424 /
8425
8426Iterate over buffers, and write the contents of each to a file descriptor.
8427
8428Returns the total number of bytes written.
8429buffers must be a sequence of bytes-like objects.
8430[clinic start generated code]*/
8431
Larry Hastings2f936352014-08-05 14:04:04 +10008432static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008433os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8434/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008435{
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008436 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008437 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008438 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008439 struct iovec *iov;
8440 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008441
8442 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008443 PyErr_SetString(PyExc_TypeError,
8444 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008445 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008446 }
Larry Hastings2f936352014-08-05 14:04:04 +10008447 cnt = PySequence_Size(buffers);
Serhiy Storchaka680fea42017-04-19 21:22:49 +03008448 if (cnt < 0)
8449 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008450
Larry Hastings2f936352014-08-05 14:04:04 +10008451 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8452 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008453 }
8454
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008455 do {
8456 Py_BEGIN_ALLOW_THREADS
8457 result = writev(fd, iov, cnt);
8458 Py_END_ALLOW_THREADS
8459 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008460
8461 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008462 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008463 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008464
Georg Brandl306336b2012-06-24 12:55:33 +02008465 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008466}
Larry Hastings2f936352014-08-05 14:04:04 +10008467#endif /* HAVE_WRITEV */
8468
8469
8470#ifdef HAVE_PWRITE
8471/*[clinic input]
8472os.pwrite -> Py_ssize_t
8473
8474 fd: int
8475 buffer: Py_buffer
8476 offset: Py_off_t
8477 /
8478
8479Write bytes to a file descriptor starting at a particular offset.
8480
8481Write buffer to fd, starting at offset bytes from the beginning of
8482the file. Returns the number of bytes writte. Does not change the
8483current file offset.
8484[clinic start generated code]*/
8485
Larry Hastings2f936352014-08-05 14:04:04 +10008486static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008487os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8488/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008489{
8490 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008491 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008492
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008493 do {
8494 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008495 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008496 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008497 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008498 Py_END_ALLOW_THREADS
8499 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008500
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008501 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008502 posix_error();
8503 return size;
8504}
8505#endif /* HAVE_PWRITE */
8506
8507
8508#ifdef HAVE_MKFIFO
8509/*[clinic input]
8510os.mkfifo
8511
8512 path: path_t
8513 mode: int=0o666
8514 *
8515 dir_fd: dir_fd(requires='mkfifoat')=None
8516
8517Create a "fifo" (a POSIX named pipe).
8518
8519If dir_fd is not None, it should be a file descriptor open to a directory,
8520 and path should be relative; path will then be relative to that directory.
8521dir_fd may not be implemented on your platform.
8522 If it is unavailable, using it will raise a NotImplementedError.
8523[clinic start generated code]*/
8524
Larry Hastings2f936352014-08-05 14:04:04 +10008525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008526os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8527/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008528{
8529 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008530 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008531
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008532 do {
8533 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008534#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008535 if (dir_fd != DEFAULT_DIR_FD)
8536 result = mkfifoat(dir_fd, path->narrow, mode);
8537 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008538#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008539 result = mkfifo(path->narrow, mode);
8540 Py_END_ALLOW_THREADS
8541 } while (result != 0 && errno == EINTR &&
8542 !(async_err = PyErr_CheckSignals()));
8543 if (result != 0)
8544 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008545
8546 Py_RETURN_NONE;
8547}
8548#endif /* HAVE_MKFIFO */
8549
8550
8551#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8552/*[clinic input]
8553os.mknod
8554
8555 path: path_t
8556 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008557 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008558 *
8559 dir_fd: dir_fd(requires='mknodat')=None
8560
8561Create a node in the file system.
8562
8563Create a node in the file system (file, device special file or named pipe)
8564at path. mode specifies both the permissions to use and the
8565type of node to be created, being combined (bitwise OR) with one of
8566S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8567device defines the newly created device special file (probably using
8568os.makedev()). Otherwise device is ignored.
8569
8570If dir_fd is not None, it should be a file descriptor open to a directory,
8571 and path should be relative; path will then be relative to that directory.
8572dir_fd may not be implemented on your platform.
8573 If it is unavailable, using it will raise a NotImplementedError.
8574[clinic start generated code]*/
8575
Larry Hastings2f936352014-08-05 14:04:04 +10008576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008577os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008578 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008579/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008580{
8581 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008582 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008583
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008584 do {
8585 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008586#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008587 if (dir_fd != DEFAULT_DIR_FD)
8588 result = mknodat(dir_fd, path->narrow, mode, device);
8589 else
Larry Hastings2f936352014-08-05 14:04:04 +10008590#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008591 result = mknod(path->narrow, mode, device);
8592 Py_END_ALLOW_THREADS
8593 } while (result != 0 && errno == EINTR &&
8594 !(async_err = PyErr_CheckSignals()));
8595 if (result != 0)
8596 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008597
8598 Py_RETURN_NONE;
8599}
8600#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8601
8602
8603#ifdef HAVE_DEVICE_MACROS
8604/*[clinic input]
8605os.major -> unsigned_int
8606
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008607 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008608 /
8609
8610Extracts a device major number from a raw device number.
8611[clinic start generated code]*/
8612
Larry Hastings2f936352014-08-05 14:04:04 +10008613static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008614os_major_impl(PyObject *module, dev_t device)
8615/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008616{
8617 return major(device);
8618}
8619
8620
8621/*[clinic input]
8622os.minor -> unsigned_int
8623
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008624 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008625 /
8626
8627Extracts a device minor number from a raw device number.
8628[clinic start generated code]*/
8629
Larry Hastings2f936352014-08-05 14:04:04 +10008630static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008631os_minor_impl(PyObject *module, dev_t device)
8632/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008633{
8634 return minor(device);
8635}
8636
8637
8638/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008639os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008640
8641 major: int
8642 minor: int
8643 /
8644
8645Composes a raw device number from the major and minor device numbers.
8646[clinic start generated code]*/
8647
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008648static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008649os_makedev_impl(PyObject *module, int major, int minor)
8650/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008651{
8652 return makedev(major, minor);
8653}
8654#endif /* HAVE_DEVICE_MACROS */
8655
8656
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008657#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008658/*[clinic input]
8659os.ftruncate
8660
8661 fd: int
8662 length: Py_off_t
8663 /
8664
8665Truncate a file, specified by file descriptor, to a specific length.
8666[clinic start generated code]*/
8667
Larry Hastings2f936352014-08-05 14:04:04 +10008668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008669os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8670/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008671{
8672 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008673 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008674
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008675 do {
8676 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008677 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008678#ifdef MS_WINDOWS
8679 result = _chsize_s(fd, length);
8680#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008681 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008682#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008683 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684 Py_END_ALLOW_THREADS
8685 } while (result != 0 && errno == EINTR &&
8686 !(async_err = PyErr_CheckSignals()));
8687 if (result != 0)
8688 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008689 Py_RETURN_NONE;
8690}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008691#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008692
8693
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008694#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008695/*[clinic input]
8696os.truncate
8697 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8698 length: Py_off_t
8699
8700Truncate a file, specified by path, to a specific length.
8701
8702On some platforms, path may also be specified as an open file descriptor.
8703 If this functionality is unavailable, using it raises an exception.
8704[clinic start generated code]*/
8705
Larry Hastings2f936352014-08-05 14:04:04 +10008706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008707os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8708/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008709{
8710 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008711#ifdef MS_WINDOWS
8712 int fd;
8713#endif
8714
8715 if (path->fd != -1)
8716 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008717
8718 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008719 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008720#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008721 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008722 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008723 result = -1;
8724 else {
8725 result = _chsize_s(fd, length);
8726 close(fd);
8727 if (result < 0)
8728 errno = result;
8729 }
8730#else
8731 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008732#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008733 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008734 Py_END_ALLOW_THREADS
8735 if (result < 0)
8736 return path_error(path);
8737
8738 Py_RETURN_NONE;
8739}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008740#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008741
Ross Lagerwall7807c352011-03-17 20:20:30 +02008742
Victor Stinnerd6b17692014-09-30 12:20:05 +02008743/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8744 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8745 defined, which is the case in Python on AIX. AIX bug report:
8746 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8747#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8748# define POSIX_FADVISE_AIX_BUG
8749#endif
8750
Victor Stinnerec39e262014-09-30 12:35:58 +02008751
Victor Stinnerd6b17692014-09-30 12:20:05 +02008752#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008753/*[clinic input]
8754os.posix_fallocate
8755
8756 fd: int
8757 offset: Py_off_t
8758 length: Py_off_t
8759 /
8760
8761Ensure a file has allocated at least a particular number of bytes on disk.
8762
8763Ensure that the file specified by fd encompasses a range of bytes
8764starting at offset bytes from the beginning and continuing for length bytes.
8765[clinic start generated code]*/
8766
Larry Hastings2f936352014-08-05 14:04:04 +10008767static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008768os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008769 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008770/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008771{
8772 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008773 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008774
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008775 do {
8776 Py_BEGIN_ALLOW_THREADS
8777 result = posix_fallocate(fd, offset, length);
8778 Py_END_ALLOW_THREADS
8779 } while (result != 0 && errno == EINTR &&
8780 !(async_err = PyErr_CheckSignals()));
8781 if (result != 0)
8782 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008783 Py_RETURN_NONE;
8784}
Victor Stinnerec39e262014-09-30 12:35:58 +02008785#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008786
Ross Lagerwall7807c352011-03-17 20:20:30 +02008787
Victor Stinnerd6b17692014-09-30 12:20:05 +02008788#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008789/*[clinic input]
8790os.posix_fadvise
8791
8792 fd: int
8793 offset: Py_off_t
8794 length: Py_off_t
8795 advice: int
8796 /
8797
8798Announce an intention to access data in a specific pattern.
8799
8800Announce an intention to access data in a specific pattern, thus allowing
8801the kernel to make optimizations.
8802The advice applies to the region of the file specified by fd starting at
8803offset and continuing for length bytes.
8804advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8805POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8806POSIX_FADV_DONTNEED.
8807[clinic start generated code]*/
8808
Larry Hastings2f936352014-08-05 14:04:04 +10008809static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008810os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008811 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008812/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008813{
8814 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008815 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008816
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008817 do {
8818 Py_BEGIN_ALLOW_THREADS
8819 result = posix_fadvise(fd, offset, length, advice);
8820 Py_END_ALLOW_THREADS
8821 } while (result != 0 && errno == EINTR &&
8822 !(async_err = PyErr_CheckSignals()));
8823 if (result != 0)
8824 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008825 Py_RETURN_NONE;
8826}
Victor Stinnerec39e262014-09-30 12:35:58 +02008827#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008828
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008829#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008830
Fred Drake762e2061999-08-26 17:23:54 +00008831/* Save putenv() parameters as values here, so we can collect them when they
8832 * get re-set with another call for the same key. */
8833static PyObject *posix_putenv_garbage;
8834
Larry Hastings2f936352014-08-05 14:04:04 +10008835static void
8836posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008837{
Larry Hastings2f936352014-08-05 14:04:04 +10008838 /* Install the first arg and newstr in posix_putenv_garbage;
8839 * this will cause previous value to be collected. This has to
8840 * happen after the real putenv() call because the old value
8841 * was still accessible until then. */
8842 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8843 /* really not much we can do; just leak */
8844 PyErr_Clear();
8845 else
8846 Py_DECREF(value);
8847}
8848
8849
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008850#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008851/*[clinic input]
8852os.putenv
8853
8854 name: unicode
8855 value: unicode
8856 /
8857
8858Change or add an environment variable.
8859[clinic start generated code]*/
8860
Larry Hastings2f936352014-08-05 14:04:04 +10008861static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008862os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8863/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008864{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008865 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008866
8867 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8868 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008869 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008870 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008871 }
Larry Hastings2f936352014-08-05 14:04:04 +10008872 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008873 PyErr_Format(PyExc_ValueError,
8874 "the environment variable is longer than %u characters",
8875 _MAX_ENV);
8876 goto error;
8877 }
8878
Larry Hastings2f936352014-08-05 14:04:04 +10008879 env = PyUnicode_AsUnicode(unicode);
8880 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008881 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008882 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008884 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008886
Larry Hastings2f936352014-08-05 14:04:04 +10008887 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008888 Py_RETURN_NONE;
8889
8890error:
Larry Hastings2f936352014-08-05 14:04:04 +10008891 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008892 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008893}
Larry Hastings2f936352014-08-05 14:04:04 +10008894#else /* MS_WINDOWS */
8895/*[clinic input]
8896os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008897
Larry Hastings2f936352014-08-05 14:04:04 +10008898 name: FSConverter
8899 value: FSConverter
8900 /
8901
8902Change or add an environment variable.
8903[clinic start generated code]*/
8904
Larry Hastings2f936352014-08-05 14:04:04 +10008905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008906os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8907/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008908{
8909 PyObject *bytes = NULL;
8910 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008911 const char *name_string = PyBytes_AsString(name);
8912 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008913
8914 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8915 if (bytes == NULL) {
8916 PyErr_NoMemory();
8917 return NULL;
8918 }
8919
8920 env = PyBytes_AS_STRING(bytes);
8921 if (putenv(env)) {
8922 Py_DECREF(bytes);
8923 return posix_error();
8924 }
8925
8926 posix_putenv_garbage_setitem(name, bytes);
8927 Py_RETURN_NONE;
8928}
8929#endif /* MS_WINDOWS */
8930#endif /* HAVE_PUTENV */
8931
8932
8933#ifdef HAVE_UNSETENV
8934/*[clinic input]
8935os.unsetenv
8936 name: FSConverter
8937 /
8938
8939Delete an environment variable.
8940[clinic start generated code]*/
8941
Larry Hastings2f936352014-08-05 14:04:04 +10008942static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008943os_unsetenv_impl(PyObject *module, PyObject *name)
8944/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008945{
Victor Stinner984890f2011-11-24 13:53:38 +01008946#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008947 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008948#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008949
Victor Stinner984890f2011-11-24 13:53:38 +01008950#ifdef HAVE_BROKEN_UNSETENV
8951 unsetenv(PyBytes_AS_STRING(name));
8952#else
Victor Stinner65170952011-11-22 22:16:17 +01008953 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008954 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008955 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008956#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008957
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 /* Remove the key from posix_putenv_garbage;
8959 * this will cause it to be collected. This has to
8960 * happen after the real unsetenv() call because the
8961 * old value was still accessible until then.
8962 */
Victor Stinner65170952011-11-22 22:16:17 +01008963 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 /* really not much we can do; just leak */
8965 PyErr_Clear();
8966 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008967 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008968}
Larry Hastings2f936352014-08-05 14:04:04 +10008969#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008970
Larry Hastings2f936352014-08-05 14:04:04 +10008971
8972/*[clinic input]
8973os.strerror
8974
8975 code: int
8976 /
8977
8978Translate an error code to a message string.
8979[clinic start generated code]*/
8980
Larry Hastings2f936352014-08-05 14:04:04 +10008981static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008982os_strerror_impl(PyObject *module, int code)
8983/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008984{
8985 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 if (message == NULL) {
8987 PyErr_SetString(PyExc_ValueError,
8988 "strerror() argument out of range");
8989 return NULL;
8990 }
Victor Stinner1b579672011-12-17 05:47:23 +01008991 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008992}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008993
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008994
Guido van Rossumc9641791998-08-04 15:26:23 +00008995#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008996#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008997/*[clinic input]
8998os.WCOREDUMP -> bool
8999
9000 status: int
9001 /
9002
9003Return True if the process returning status was dumped to a core file.
9004[clinic start generated code]*/
9005
Larry Hastings2f936352014-08-05 14:04:04 +10009006static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009007os_WCOREDUMP_impl(PyObject *module, int status)
9008/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009009{
9010 WAIT_TYPE wait_status;
9011 WAIT_STATUS_INT(wait_status) = status;
9012 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009013}
9014#endif /* WCOREDUMP */
9015
Larry Hastings2f936352014-08-05 14:04:04 +10009016
Fred Drake106c1a02002-04-23 15:58:02 +00009017#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009018/*[clinic input]
9019os.WIFCONTINUED -> bool
9020
9021 status: int
9022
9023Return True if a particular process was continued from a job control stop.
9024
9025Return True if the process returning status was continued from a
9026job control stop.
9027[clinic start generated code]*/
9028
Larry Hastings2f936352014-08-05 14:04:04 +10009029static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009030os_WIFCONTINUED_impl(PyObject *module, int status)
9031/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009032{
9033 WAIT_TYPE wait_status;
9034 WAIT_STATUS_INT(wait_status) = status;
9035 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009036}
9037#endif /* WIFCONTINUED */
9038
Larry Hastings2f936352014-08-05 14:04:04 +10009039
Guido van Rossumc9641791998-08-04 15:26:23 +00009040#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009041/*[clinic input]
9042os.WIFSTOPPED -> bool
9043
9044 status: int
9045
9046Return True if the process returning status was stopped.
9047[clinic start generated code]*/
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009050os_WIFSTOPPED_impl(PyObject *module, int status)
9051/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009052{
9053 WAIT_TYPE wait_status;
9054 WAIT_STATUS_INT(wait_status) = status;
9055 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009056}
9057#endif /* WIFSTOPPED */
9058
Larry Hastings2f936352014-08-05 14:04:04 +10009059
Guido van Rossumc9641791998-08-04 15:26:23 +00009060#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009061/*[clinic input]
9062os.WIFSIGNALED -> bool
9063
9064 status: int
9065
9066Return True if the process returning status was terminated by a signal.
9067[clinic start generated code]*/
9068
Larry Hastings2f936352014-08-05 14:04:04 +10009069static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009070os_WIFSIGNALED_impl(PyObject *module, int status)
9071/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009072{
9073 WAIT_TYPE wait_status;
9074 WAIT_STATUS_INT(wait_status) = status;
9075 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009076}
9077#endif /* WIFSIGNALED */
9078
Larry Hastings2f936352014-08-05 14:04:04 +10009079
Guido van Rossumc9641791998-08-04 15:26:23 +00009080#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009081/*[clinic input]
9082os.WIFEXITED -> bool
9083
9084 status: int
9085
9086Return True if the process returning status exited via the exit() system call.
9087[clinic start generated code]*/
9088
Larry Hastings2f936352014-08-05 14:04:04 +10009089static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009090os_WIFEXITED_impl(PyObject *module, int status)
9091/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009092{
9093 WAIT_TYPE wait_status;
9094 WAIT_STATUS_INT(wait_status) = status;
9095 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009096}
9097#endif /* WIFEXITED */
9098
Larry Hastings2f936352014-08-05 14:04:04 +10009099
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009100#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009101/*[clinic input]
9102os.WEXITSTATUS -> int
9103
9104 status: int
9105
9106Return the process return code from status.
9107[clinic start generated code]*/
9108
Larry Hastings2f936352014-08-05 14:04:04 +10009109static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009110os_WEXITSTATUS_impl(PyObject *module, int status)
9111/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009112{
9113 WAIT_TYPE wait_status;
9114 WAIT_STATUS_INT(wait_status) = status;
9115 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009116}
9117#endif /* WEXITSTATUS */
9118
Larry Hastings2f936352014-08-05 14:04:04 +10009119
Guido van Rossumc9641791998-08-04 15:26:23 +00009120#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009121/*[clinic input]
9122os.WTERMSIG -> int
9123
9124 status: int
9125
9126Return the signal that terminated the process that provided the status value.
9127[clinic start generated code]*/
9128
Larry Hastings2f936352014-08-05 14:04:04 +10009129static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009130os_WTERMSIG_impl(PyObject *module, int status)
9131/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009132{
9133 WAIT_TYPE wait_status;
9134 WAIT_STATUS_INT(wait_status) = status;
9135 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009136}
9137#endif /* WTERMSIG */
9138
Larry Hastings2f936352014-08-05 14:04:04 +10009139
Guido van Rossumc9641791998-08-04 15:26:23 +00009140#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009141/*[clinic input]
9142os.WSTOPSIG -> int
9143
9144 status: int
9145
9146Return the signal that stopped the process that provided the status value.
9147[clinic start generated code]*/
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009150os_WSTOPSIG_impl(PyObject *module, int status)
9151/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009152{
9153 WAIT_TYPE wait_status;
9154 WAIT_STATUS_INT(wait_status) = status;
9155 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009156}
9157#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009158#endif /* HAVE_SYS_WAIT_H */
9159
9160
Thomas Wouters477c8d52006-05-27 19:21:47 +00009161#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009162#ifdef _SCO_DS
9163/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9164 needed definitions in sys/statvfs.h */
9165#define _SVID3
9166#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009167#include <sys/statvfs.h>
9168
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009169static PyObject*
9170_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9172 if (v == NULL)
9173 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009174
9175#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9177 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9178 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9179 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9180 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9181 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9182 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9183 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9184 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9185 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009186#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009187 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9188 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9189 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009190 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009192 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009193 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009194 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009196 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009198 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009200 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9202 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009203#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009204 if (PyErr_Occurred()) {
9205 Py_DECREF(v);
9206 return NULL;
9207 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009208
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009210}
9211
Larry Hastings2f936352014-08-05 14:04:04 +10009212
9213/*[clinic input]
9214os.fstatvfs
9215 fd: int
9216 /
9217
9218Perform an fstatvfs system call on the given fd.
9219
9220Equivalent to statvfs(fd).
9221[clinic start generated code]*/
9222
Larry Hastings2f936352014-08-05 14:04:04 +10009223static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009224os_fstatvfs_impl(PyObject *module, int fd)
9225/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009226{
9227 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009228 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009230
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009231 do {
9232 Py_BEGIN_ALLOW_THREADS
9233 result = fstatvfs(fd, &st);
9234 Py_END_ALLOW_THREADS
9235 } while (result != 0 && errno == EINTR &&
9236 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009237 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009238 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009239
Victor Stinner8c62be82010-05-06 00:08:46 +00009240 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009241}
Larry Hastings2f936352014-08-05 14:04:04 +10009242#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009243
9244
Thomas Wouters477c8d52006-05-27 19:21:47 +00009245#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009246#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009247/*[clinic input]
9248os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009249
Larry Hastings2f936352014-08-05 14:04:04 +10009250 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9251
9252Perform a statvfs system call on the given path.
9253
9254path may always be specified as a string.
9255On some platforms, path may also be specified as an open file descriptor.
9256 If this functionality is unavailable, using it raises an exception.
9257[clinic start generated code]*/
9258
Larry Hastings2f936352014-08-05 14:04:04 +10009259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009260os_statvfs_impl(PyObject *module, path_t *path)
9261/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009262{
9263 int result;
9264 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009265
9266 Py_BEGIN_ALLOW_THREADS
9267#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009268 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009269#ifdef __APPLE__
9270 /* handle weak-linking on Mac OS X 10.3 */
9271 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009272 fd_specified("statvfs", path->fd);
9273 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009274 }
9275#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009276 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009277 }
9278 else
9279#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009280 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009281 Py_END_ALLOW_THREADS
9282
9283 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009284 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009285 }
9286
Larry Hastings2f936352014-08-05 14:04:04 +10009287 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009288}
Larry Hastings2f936352014-08-05 14:04:04 +10009289#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9290
Guido van Rossum94f6f721999-01-06 18:42:14 +00009291
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009292#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009293/*[clinic input]
9294os._getdiskusage
9295
9296 path: Py_UNICODE
9297
9298Return disk usage statistics about the given path as a (total, free) tuple.
9299[clinic start generated code]*/
9300
Larry Hastings2f936352014-08-05 14:04:04 +10009301static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009302os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9303/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009304{
9305 BOOL retval;
9306 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009307
9308 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009309 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009310 Py_END_ALLOW_THREADS
9311 if (retval == 0)
9312 return PyErr_SetFromWindowsErr(0);
9313
9314 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9315}
Larry Hastings2f936352014-08-05 14:04:04 +10009316#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009317
9318
Fred Drakec9680921999-12-13 16:37:25 +00009319/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9320 * It maps strings representing configuration variable names to
9321 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009322 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009323 * rarely-used constants. There are three separate tables that use
9324 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009325 *
9326 * This code is always included, even if none of the interfaces that
9327 * need it are included. The #if hackery needed to avoid it would be
9328 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009329 */
9330struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009331 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009332 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009333};
9334
Fred Drake12c6e2d1999-12-14 21:25:03 +00009335static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009336conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009337 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009338{
Christian Heimes217cfd12007-12-02 14:31:20 +00009339 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009340 int value = _PyLong_AsInt(arg);
9341 if (value == -1 && PyErr_Occurred())
9342 return 0;
9343 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009344 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009345 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009346 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009347 /* look up the value in the table using a binary search */
9348 size_t lo = 0;
9349 size_t mid;
9350 size_t hi = tablesize;
9351 int cmp;
9352 const char *confname;
9353 if (!PyUnicode_Check(arg)) {
9354 PyErr_SetString(PyExc_TypeError,
9355 "configuration names must be strings or integers");
9356 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009358 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009359 if (confname == NULL)
9360 return 0;
9361 while (lo < hi) {
9362 mid = (lo + hi) / 2;
9363 cmp = strcmp(confname, table[mid].name);
9364 if (cmp < 0)
9365 hi = mid;
9366 else if (cmp > 0)
9367 lo = mid + 1;
9368 else {
9369 *valuep = table[mid].value;
9370 return 1;
9371 }
9372 }
9373 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9374 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009376}
9377
9378
9379#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9380static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009381#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009383#endif
9384#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009386#endif
Fred Drakec9680921999-12-13 16:37:25 +00009387#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
9405#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
9408#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009410#endif
9411#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009416#endif
9417#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009419#endif
9420#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009422#endif
9423#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009425#endif
9426#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009428#endif
9429#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009431#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009432#ifdef _PC_ACL_ENABLED
9433 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9434#endif
9435#ifdef _PC_MIN_HOLE_SIZE
9436 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9437#endif
9438#ifdef _PC_ALLOC_SIZE_MIN
9439 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9440#endif
9441#ifdef _PC_REC_INCR_XFER_SIZE
9442 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9443#endif
9444#ifdef _PC_REC_MAX_XFER_SIZE
9445 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9446#endif
9447#ifdef _PC_REC_MIN_XFER_SIZE
9448 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9449#endif
9450#ifdef _PC_REC_XFER_ALIGN
9451 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9452#endif
9453#ifdef _PC_SYMLINK_MAX
9454 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9455#endif
9456#ifdef _PC_XATTR_ENABLED
9457 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9458#endif
9459#ifdef _PC_XATTR_EXISTS
9460 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9461#endif
9462#ifdef _PC_TIMESTAMP_RESOLUTION
9463 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9464#endif
Fred Drakec9680921999-12-13 16:37:25 +00009465};
9466
Fred Drakec9680921999-12-13 16:37:25 +00009467static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009468conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009469{
9470 return conv_confname(arg, valuep, posix_constants_pathconf,
9471 sizeof(posix_constants_pathconf)
9472 / sizeof(struct constdef));
9473}
9474#endif
9475
Larry Hastings2f936352014-08-05 14:04:04 +10009476
Fred Drakec9680921999-12-13 16:37:25 +00009477#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009478/*[clinic input]
9479os.fpathconf -> long
9480
9481 fd: int
9482 name: path_confname
9483 /
9484
9485Return the configuration limit name for the file descriptor fd.
9486
9487If there is no limit, return -1.
9488[clinic start generated code]*/
9489
Larry Hastings2f936352014-08-05 14:04:04 +10009490static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009491os_fpathconf_impl(PyObject *module, int fd, int name)
9492/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009493{
9494 long limit;
9495
9496 errno = 0;
9497 limit = fpathconf(fd, name);
9498 if (limit == -1 && errno != 0)
9499 posix_error();
9500
9501 return limit;
9502}
9503#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009504
9505
9506#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009507/*[clinic input]
9508os.pathconf -> long
9509 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9510 name: path_confname
9511
9512Return the configuration limit name for the file or directory path.
9513
9514If there is no limit, return -1.
9515On some platforms, path may also be specified as an open file descriptor.
9516 If this functionality is unavailable, using it raises an exception.
9517[clinic start generated code]*/
9518
Larry Hastings2f936352014-08-05 14:04:04 +10009519static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009520os_pathconf_impl(PyObject *module, path_t *path, int name)
9521/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009522{
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009524
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009526#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009527 if (path->fd != -1)
9528 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009529 else
9530#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009531 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 if (limit == -1 && errno != 0) {
9533 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009534 /* could be a path or name problem */
9535 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009536 else
Larry Hastings2f936352014-08-05 14:04:04 +10009537 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 }
Larry Hastings2f936352014-08-05 14:04:04 +10009539
9540 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009541}
Larry Hastings2f936352014-08-05 14:04:04 +10009542#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009543
9544#ifdef HAVE_CONFSTR
9545static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009546#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009548#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009549#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009551#endif
9552#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009554#endif
Fred Draked86ed291999-12-15 15:34:33 +00009555#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009557#endif
9558#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009560#endif
9561#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009563#endif
9564#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009566#endif
Fred Drakec9680921999-12-13 16:37:25 +00009567#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
Fred Draked86ed291999-12-15 15:34:33 +00009591#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009593#endif
Fred Drakec9680921999-12-13 16:37:25 +00009594#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
Fred Draked86ed291999-12-15 15:34:33 +00009597#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009599#endif
9600#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009602#endif
9603#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009605#endif
9606#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009608#endif
Fred Drakec9680921999-12-13 16:37:25 +00009609#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
9648#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
Fred Draked86ed291999-12-15 15:34:33 +00009657#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
9663#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009665#endif
9666#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009668#endif
9669#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
9672#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009674#endif
9675#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009677#endif
9678#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009680#endif
9681#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009683#endif
9684#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009686#endif
9687#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009689#endif
9690#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009692#endif
9693#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009695#endif
Fred Drakec9680921999-12-13 16:37:25 +00009696};
9697
9698static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009699conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009700{
9701 return conv_confname(arg, valuep, posix_constants_confstr,
9702 sizeof(posix_constants_confstr)
9703 / sizeof(struct constdef));
9704}
9705
Larry Hastings2f936352014-08-05 14:04:04 +10009706
9707/*[clinic input]
9708os.confstr
9709
9710 name: confstr_confname
9711 /
9712
9713Return a string-valued system configuration variable.
9714[clinic start generated code]*/
9715
Larry Hastings2f936352014-08-05 14:04:04 +10009716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009717os_confstr_impl(PyObject *module, int name)
9718/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009719{
9720 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009721 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009722 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009723
Victor Stinnercb043522010-09-10 23:49:04 +00009724 errno = 0;
9725 len = confstr(name, buffer, sizeof(buffer));
9726 if (len == 0) {
9727 if (errno) {
9728 posix_error();
9729 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009730 }
9731 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009732 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009733 }
9734 }
Victor Stinnercb043522010-09-10 23:49:04 +00009735
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009736 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009737 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009738 char *buf = PyMem_Malloc(len);
9739 if (buf == NULL)
9740 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009741 len2 = confstr(name, buf, len);
9742 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009743 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009744 PyMem_Free(buf);
9745 }
9746 else
9747 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009748 return result;
9749}
Larry Hastings2f936352014-08-05 14:04:04 +10009750#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009751
9752
9753#ifdef HAVE_SYSCONF
9754static struct constdef posix_constants_sysconf[] = {
9755#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
Fred Draked86ed291999-12-15 15:34:33 +00009785#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009787#endif
9788#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009790#endif
Fred Drakec9680921999-12-13 16:37:25 +00009791#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
Fred Drakec9680921999-12-13 16:37:25 +00009794#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
Fred Draked86ed291999-12-15 15:34:33 +00009809#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009811#endif
Fred Drakec9680921999-12-13 16:37:25 +00009812#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
Fred Draked86ed291999-12-15 15:34:33 +00009827#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009829#endif
Fred Drakec9680921999-12-13 16:37:25 +00009830#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
Fred Draked86ed291999-12-15 15:34:33 +00009899#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009901#endif
Fred Drakec9680921999-12-13 16:37:25 +00009902#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
Fred Draked86ed291999-12-15 15:34:33 +00009911#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009913#endif
Fred Drakec9680921999-12-13 16:37:25 +00009914#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
Fred Draked86ed291999-12-15 15:34:33 +00009917#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009919#endif
9920#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009922#endif
Fred Drakec9680921999-12-13 16:37:25 +00009923#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
Fred Draked86ed291999-12-15 15:34:33 +00009935#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009937#endif
Fred Drakec9680921999-12-13 16:37:25 +00009938#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
Fred Draked86ed291999-12-15 15:34:33 +00009959#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009961#endif
Fred Drakec9680921999-12-13 16:37:25 +00009962#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
Fred Draked86ed291999-12-15 15:34:33 +00009968#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009970#endif
Fred Drakec9680921999-12-13 16:37:25 +00009971#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
Fred Draked86ed291999-12-15 15:34:33 +00009998#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010000#endif
10001#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010003#endif
Fred Drakec9680921999-12-13 16:37:25 +000010004#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
Fred Draked86ed291999-12-15 15:34:33 +000010109#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010111#endif
Fred Drakec9680921999-12-13 16:37:25 +000010112#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247};
10248
10249static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010250conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010251{
10252 return conv_confname(arg, valuep, posix_constants_sysconf,
10253 sizeof(posix_constants_sysconf)
10254 / sizeof(struct constdef));
10255}
10256
Larry Hastings2f936352014-08-05 14:04:04 +100010257
10258/*[clinic input]
10259os.sysconf -> long
10260 name: sysconf_confname
10261 /
10262
10263Return an integer-valued system configuration variable.
10264[clinic start generated code]*/
10265
Larry Hastings2f936352014-08-05 14:04:04 +100010266static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010267os_sysconf_impl(PyObject *module, int name)
10268/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010269{
10270 long value;
10271
10272 errno = 0;
10273 value = sysconf(name);
10274 if (value == -1 && errno != 0)
10275 posix_error();
10276 return value;
10277}
10278#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010279
10280
Fred Drakebec628d1999-12-15 18:31:10 +000010281/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010282 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010283 * the exported dictionaries that are used to publish information about the
10284 * names available on the host platform.
10285 *
10286 * Sorting the table at runtime ensures that the table is properly ordered
10287 * when used, even for platforms we're not able to test on. It also makes
10288 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010289 */
Fred Drakebec628d1999-12-15 18:31:10 +000010290
10291static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010292cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010293{
10294 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010296 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010298
10299 return strcmp(c1->name, c2->name);
10300}
10301
10302static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010303setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010304 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010305{
Fred Drakebec628d1999-12-15 18:31:10 +000010306 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010307 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010308
10309 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10310 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010311 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010313
Barry Warsaw3155db32000-04-13 15:20:40 +000010314 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 PyObject *o = PyLong_FromLong(table[i].value);
10316 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10317 Py_XDECREF(o);
10318 Py_DECREF(d);
10319 return -1;
10320 }
10321 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010322 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010323 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010324}
10325
Fred Drakebec628d1999-12-15 18:31:10 +000010326/* Return -1 on failure, 0 on success. */
10327static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010328setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010329{
10330#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010331 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010332 sizeof(posix_constants_pathconf)
10333 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010334 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010335 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010336#endif
10337#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010338 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010339 sizeof(posix_constants_confstr)
10340 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010341 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010342 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010343#endif
10344#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010345 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010346 sizeof(posix_constants_sysconf)
10347 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010348 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010349 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010350#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010351 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010352}
Fred Draked86ed291999-12-15 15:34:33 +000010353
10354
Larry Hastings2f936352014-08-05 14:04:04 +100010355/*[clinic input]
10356os.abort
10357
10358Abort the interpreter immediately.
10359
10360This function 'dumps core' or otherwise fails in the hardest way possible
10361on the hosting operating system. This function never returns.
10362[clinic start generated code]*/
10363
Larry Hastings2f936352014-08-05 14:04:04 +100010364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010365os_abort_impl(PyObject *module)
10366/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010367{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010368 abort();
10369 /*NOTREACHED*/
10370 Py_FatalError("abort() called from Python code didn't abort!");
10371 return NULL;
10372}
Fred Drakebec628d1999-12-15 18:31:10 +000010373
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010374#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010375/* Grab ShellExecute dynamically from shell32 */
10376static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010377static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10378 LPCWSTR, INT);
10379static int
10380check_ShellExecute()
10381{
10382 HINSTANCE hShell32;
10383
10384 /* only recheck */
10385 if (-1 == has_ShellExecute) {
10386 Py_BEGIN_ALLOW_THREADS
10387 hShell32 = LoadLibraryW(L"SHELL32");
10388 Py_END_ALLOW_THREADS
10389 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010390 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10391 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010392 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010393 } else {
10394 has_ShellExecute = 0;
10395 }
10396 }
10397 return has_ShellExecute;
10398}
10399
10400
Steve Dowercc16be82016-09-08 10:35:16 -070010401/*[clinic input]
10402os.startfile
10403 filepath: path_t
10404 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010405
Steve Dowercc16be82016-09-08 10:35:16 -070010406startfile(filepath [, operation])
10407
10408Start a file with its associated application.
10409
10410When "operation" is not specified or "open", this acts like
10411double-clicking the file in Explorer, or giving the file name as an
10412argument to the DOS "start" command: the file is opened with whatever
10413application (if any) its extension is associated.
10414When another "operation" is given, it specifies what should be done with
10415the file. A typical operation is "print".
10416
10417startfile returns as soon as the associated application is launched.
10418There is no option to wait for the application to close, and no way
10419to retrieve the application's exit status.
10420
10421The filepath is relative to the current directory. If you want to use
10422an absolute path, make sure the first character is not a slash ("/");
10423the underlying Win32 ShellExecute function doesn't work if it is.
10424[clinic start generated code]*/
10425
10426static PyObject *
10427os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10428/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10429{
10430 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010431
10432 if(!check_ShellExecute()) {
10433 /* If the OS doesn't have ShellExecute, return a
10434 NotImplementedError. */
10435 return PyErr_Format(PyExc_NotImplementedError,
10436 "startfile not available on this platform");
10437 }
10438
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010440 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010441 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 Py_END_ALLOW_THREADS
10443
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010445 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010446 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 }
Steve Dowercc16be82016-09-08 10:35:16 -070010448 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010449}
Larry Hastings2f936352014-08-05 14:04:04 +100010450#endif /* MS_WINDOWS */
10451
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010452
Martin v. Löwis438b5342002-12-27 10:16:42 +000010453#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010454/*[clinic input]
10455os.getloadavg
10456
10457Return average recent system load information.
10458
10459Return the number of processes in the system run queue averaged over
10460the last 1, 5, and 15 minutes as a tuple of three floats.
10461Raises OSError if the load average was unobtainable.
10462[clinic start generated code]*/
10463
Larry Hastings2f936352014-08-05 14:04:04 +100010464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010465os_getloadavg_impl(PyObject *module)
10466/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010467{
10468 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010469 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010470 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10471 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010472 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010473 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010474}
Larry Hastings2f936352014-08-05 14:04:04 +100010475#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010476
Larry Hastings2f936352014-08-05 14:04:04 +100010477
10478/*[clinic input]
10479os.device_encoding
10480 fd: int
10481
10482Return a string describing the encoding of a terminal's file descriptor.
10483
10484The file descriptor must be attached to a terminal.
10485If the device is not a terminal, return None.
10486[clinic start generated code]*/
10487
Larry Hastings2f936352014-08-05 14:04:04 +100010488static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010489os_device_encoding_impl(PyObject *module, int fd)
10490/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010491{
Brett Cannonefb00c02012-02-29 18:31:31 -050010492 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010493}
10494
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010495
Larry Hastings2f936352014-08-05 14:04:04 +100010496#ifdef HAVE_SETRESUID
10497/*[clinic input]
10498os.setresuid
10499
10500 ruid: uid_t
10501 euid: uid_t
10502 suid: uid_t
10503 /
10504
10505Set the current process's real, effective, and saved user ids.
10506[clinic start generated code]*/
10507
Larry Hastings2f936352014-08-05 14:04:04 +100010508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010509os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10510/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010511{
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 if (setresuid(ruid, euid, suid) < 0)
10513 return posix_error();
10514 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010515}
Larry Hastings2f936352014-08-05 14:04:04 +100010516#endif /* HAVE_SETRESUID */
10517
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010518
10519#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010520/*[clinic input]
10521os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010522
Larry Hastings2f936352014-08-05 14:04:04 +100010523 rgid: gid_t
10524 egid: gid_t
10525 sgid: gid_t
10526 /
10527
10528Set the current process's real, effective, and saved group ids.
10529[clinic start generated code]*/
10530
Larry Hastings2f936352014-08-05 14:04:04 +100010531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010532os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10533/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010534{
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 if (setresgid(rgid, egid, sgid) < 0)
10536 return posix_error();
10537 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010538}
Larry Hastings2f936352014-08-05 14:04:04 +100010539#endif /* HAVE_SETRESGID */
10540
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010541
10542#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010543/*[clinic input]
10544os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010545
Larry Hastings2f936352014-08-05 14:04:04 +100010546Return a tuple of the current process's real, effective, and saved user ids.
10547[clinic start generated code]*/
10548
Larry Hastings2f936352014-08-05 14:04:04 +100010549static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010550os_getresuid_impl(PyObject *module)
10551/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010552{
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 if (getresuid(&ruid, &euid, &suid) < 0)
10555 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010556 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10557 _PyLong_FromUid(euid),
10558 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010559}
Larry Hastings2f936352014-08-05 14:04:04 +100010560#endif /* HAVE_GETRESUID */
10561
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010562
10563#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010564/*[clinic input]
10565os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010566
Larry Hastings2f936352014-08-05 14:04:04 +100010567Return a tuple of the current process's real, effective, and saved group ids.
10568[clinic start generated code]*/
10569
Larry Hastings2f936352014-08-05 14:04:04 +100010570static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010571os_getresgid_impl(PyObject *module)
10572/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010573{
10574 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 if (getresgid(&rgid, &egid, &sgid) < 0)
10576 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010577 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10578 _PyLong_FromGid(egid),
10579 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010580}
Larry Hastings2f936352014-08-05 14:04:04 +100010581#endif /* HAVE_GETRESGID */
10582
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010583
Benjamin Peterson9428d532011-09-14 11:45:52 -040010584#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010585/*[clinic input]
10586os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010587
Larry Hastings2f936352014-08-05 14:04:04 +100010588 path: path_t(allow_fd=True)
10589 attribute: path_t
10590 *
10591 follow_symlinks: bool = True
10592
10593Return the value of extended attribute attribute on path.
10594
10595path may be either a string or an open file descriptor.
10596If follow_symlinks is False, and the last element of the path is a symbolic
10597 link, getxattr will examine the symbolic link itself instead of the file
10598 the link points to.
10599
10600[clinic start generated code]*/
10601
Larry Hastings2f936352014-08-05 14:04:04 +100010602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010603os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010604 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010605/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010606{
10607 Py_ssize_t i;
10608 PyObject *buffer = NULL;
10609
10610 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10611 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010612
Larry Hastings9cf065c2012-06-22 16:30:09 -070010613 for (i = 0; ; i++) {
10614 void *ptr;
10615 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010616 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010617 Py_ssize_t buffer_size = buffer_sizes[i];
10618 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010619 path_error(path);
10620 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 }
10622 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10623 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010624 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010625 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626
Larry Hastings9cf065c2012-06-22 16:30:09 -070010627 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010628 if (path->fd >= 0)
10629 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010630 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010631 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010632 else
Larry Hastings2f936352014-08-05 14:04:04 +100010633 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010635
Larry Hastings9cf065c2012-06-22 16:30:09 -070010636 if (result < 0) {
10637 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010638 if (errno == ERANGE)
10639 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010640 path_error(path);
10641 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010642 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010643
Larry Hastings9cf065c2012-06-22 16:30:09 -070010644 if (result != buffer_size) {
10645 /* Can only shrink. */
10646 _PyBytes_Resize(&buffer, result);
10647 }
10648 break;
10649 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650
Larry Hastings9cf065c2012-06-22 16:30:09 -070010651 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652}
10653
Larry Hastings2f936352014-08-05 14:04:04 +100010654
10655/*[clinic input]
10656os.setxattr
10657
10658 path: path_t(allow_fd=True)
10659 attribute: path_t
10660 value: Py_buffer
10661 flags: int = 0
10662 *
10663 follow_symlinks: bool = True
10664
10665Set extended attribute attribute on path to value.
10666
10667path may be either a string or an open file descriptor.
10668If follow_symlinks is False, and the last element of the path is a symbolic
10669 link, setxattr will modify the symbolic link itself instead of the file
10670 the link points to.
10671
10672[clinic start generated code]*/
10673
Benjamin Peterson799bd802011-08-31 22:15:17 -040010674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010675os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010676 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010677/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010678{
Larry Hastings2f936352014-08-05 14:04:04 +100010679 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010680
Larry Hastings2f936352014-08-05 14:04:04 +100010681 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010682 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010683
Benjamin Peterson799bd802011-08-31 22:15:17 -040010684 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010685 if (path->fd > -1)
10686 result = fsetxattr(path->fd, attribute->narrow,
10687 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010688 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010689 result = setxattr(path->narrow, attribute->narrow,
10690 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010691 else
Larry Hastings2f936352014-08-05 14:04:04 +100010692 result = lsetxattr(path->narrow, attribute->narrow,
10693 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010694 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010695
Larry Hastings9cf065c2012-06-22 16:30:09 -070010696 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010697 path_error(path);
10698 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010699 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010700
Larry Hastings2f936352014-08-05 14:04:04 +100010701 Py_RETURN_NONE;
10702}
10703
10704
10705/*[clinic input]
10706os.removexattr
10707
10708 path: path_t(allow_fd=True)
10709 attribute: path_t
10710 *
10711 follow_symlinks: bool = True
10712
10713Remove extended attribute attribute on path.
10714
10715path may be either a string or an open file descriptor.
10716If follow_symlinks is False, and the last element of the path is a symbolic
10717 link, removexattr will modify the symbolic link itself instead of the file
10718 the link points to.
10719
10720[clinic start generated code]*/
10721
Larry Hastings2f936352014-08-05 14:04:04 +100010722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010723os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010724 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010725/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010726{
10727 ssize_t result;
10728
10729 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10730 return NULL;
10731
10732 Py_BEGIN_ALLOW_THREADS;
10733 if (path->fd > -1)
10734 result = fremovexattr(path->fd, attribute->narrow);
10735 else if (follow_symlinks)
10736 result = removexattr(path->narrow, attribute->narrow);
10737 else
10738 result = lremovexattr(path->narrow, attribute->narrow);
10739 Py_END_ALLOW_THREADS;
10740
10741 if (result) {
10742 return path_error(path);
10743 }
10744
10745 Py_RETURN_NONE;
10746}
10747
10748
10749/*[clinic input]
10750os.listxattr
10751
10752 path: path_t(allow_fd=True, nullable=True) = None
10753 *
10754 follow_symlinks: bool = True
10755
10756Return a list of extended attributes on path.
10757
10758path may be either None, a string, or an open file descriptor.
10759if path is None, listxattr will examine the current directory.
10760If follow_symlinks is False, and the last element of the path is a symbolic
10761 link, listxattr will examine the symbolic link itself instead of the file
10762 the link points to.
10763[clinic start generated code]*/
10764
Larry Hastings2f936352014-08-05 14:04:04 +100010765static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010766os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10767/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010768{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010769 Py_ssize_t i;
10770 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010771 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010773
Larry Hastings2f936352014-08-05 14:04:04 +100010774 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010775 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010776
Larry Hastings2f936352014-08-05 14:04:04 +100010777 name = path->narrow ? path->narrow : ".";
10778
Larry Hastings9cf065c2012-06-22 16:30:09 -070010779 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010780 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010782 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783 Py_ssize_t buffer_size = buffer_sizes[i];
10784 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010785 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010786 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010787 break;
10788 }
10789 buffer = PyMem_MALLOC(buffer_size);
10790 if (!buffer) {
10791 PyErr_NoMemory();
10792 break;
10793 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010794
Larry Hastings9cf065c2012-06-22 16:30:09 -070010795 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010796 if (path->fd > -1)
10797 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010798 else if (follow_symlinks)
10799 length = listxattr(name, buffer, buffer_size);
10800 else
10801 length = llistxattr(name, buffer, buffer_size);
10802 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010803
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010805 if (errno == ERANGE) {
10806 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010807 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010808 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010809 }
Larry Hastings2f936352014-08-05 14:04:04 +100010810 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010811 break;
10812 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010813
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814 result = PyList_New(0);
10815 if (!result) {
10816 goto exit;
10817 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818
Larry Hastings9cf065c2012-06-22 16:30:09 -070010819 end = buffer + length;
10820 for (trace = start = buffer; trace != end; trace++) {
10821 if (!*trace) {
10822 int error;
10823 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10824 trace - start);
10825 if (!attribute) {
10826 Py_DECREF(result);
10827 result = NULL;
10828 goto exit;
10829 }
10830 error = PyList_Append(result, attribute);
10831 Py_DECREF(attribute);
10832 if (error) {
10833 Py_DECREF(result);
10834 result = NULL;
10835 goto exit;
10836 }
10837 start = trace + 1;
10838 }
10839 }
10840 break;
10841 }
10842exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 if (buffer)
10844 PyMem_FREE(buffer);
10845 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010846}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010847#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010848
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010849
Larry Hastings2f936352014-08-05 14:04:04 +100010850/*[clinic input]
10851os.urandom
10852
10853 size: Py_ssize_t
10854 /
10855
10856Return a bytes object containing random bytes suitable for cryptographic use.
10857[clinic start generated code]*/
10858
Larry Hastings2f936352014-08-05 14:04:04 +100010859static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010860os_urandom_impl(PyObject *module, Py_ssize_t size)
10861/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010862{
10863 PyObject *bytes;
10864 int result;
10865
Georg Brandl2fb477c2012-02-21 00:33:36 +010010866 if (size < 0)
10867 return PyErr_Format(PyExc_ValueError,
10868 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010869 bytes = PyBytes_FromStringAndSize(NULL, size);
10870 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010871 return NULL;
10872
Victor Stinnere66987e2016-09-06 16:33:52 -070010873 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010874 if (result == -1) {
10875 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010876 return NULL;
10877 }
Larry Hastings2f936352014-08-05 14:04:04 +100010878 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010879}
10880
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010881/* Terminal size querying */
10882
10883static PyTypeObject TerminalSizeType;
10884
10885PyDoc_STRVAR(TerminalSize_docstring,
10886 "A tuple of (columns, lines) for holding terminal window size");
10887
10888static PyStructSequence_Field TerminalSize_fields[] = {
10889 {"columns", "width of the terminal window in characters"},
10890 {"lines", "height of the terminal window in characters"},
10891 {NULL, NULL}
10892};
10893
10894static PyStructSequence_Desc TerminalSize_desc = {
10895 "os.terminal_size",
10896 TerminalSize_docstring,
10897 TerminalSize_fields,
10898 2,
10899};
10900
10901#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010902/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010903PyDoc_STRVAR(termsize__doc__,
10904 "Return the size of the terminal window as (columns, lines).\n" \
10905 "\n" \
10906 "The optional argument fd (default standard output) specifies\n" \
10907 "which file descriptor should be queried.\n" \
10908 "\n" \
10909 "If the file descriptor is not connected to a terminal, an OSError\n" \
10910 "is thrown.\n" \
10911 "\n" \
10912 "This function will only be defined if an implementation is\n" \
10913 "available for this system.\n" \
10914 "\n" \
10915 "shutil.get_terminal_size is the high-level function which should \n" \
10916 "normally be used, os.get_terminal_size is the low-level implementation.");
10917
10918static PyObject*
10919get_terminal_size(PyObject *self, PyObject *args)
10920{
10921 int columns, lines;
10922 PyObject *termsize;
10923
10924 int fd = fileno(stdout);
10925 /* Under some conditions stdout may not be connected and
10926 * fileno(stdout) may point to an invalid file descriptor. For example
10927 * GUI apps don't have valid standard streams by default.
10928 *
10929 * If this happens, and the optional fd argument is not present,
10930 * the ioctl below will fail returning EBADF. This is what we want.
10931 */
10932
10933 if (!PyArg_ParseTuple(args, "|i", &fd))
10934 return NULL;
10935
10936#ifdef TERMSIZE_USE_IOCTL
10937 {
10938 struct winsize w;
10939 if (ioctl(fd, TIOCGWINSZ, &w))
10940 return PyErr_SetFromErrno(PyExc_OSError);
10941 columns = w.ws_col;
10942 lines = w.ws_row;
10943 }
10944#endif /* TERMSIZE_USE_IOCTL */
10945
10946#ifdef TERMSIZE_USE_CONIO
10947 {
10948 DWORD nhandle;
10949 HANDLE handle;
10950 CONSOLE_SCREEN_BUFFER_INFO csbi;
10951 switch (fd) {
10952 case 0: nhandle = STD_INPUT_HANDLE;
10953 break;
10954 case 1: nhandle = STD_OUTPUT_HANDLE;
10955 break;
10956 case 2: nhandle = STD_ERROR_HANDLE;
10957 break;
10958 default:
10959 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10960 }
10961 handle = GetStdHandle(nhandle);
10962 if (handle == NULL)
10963 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10964 if (handle == INVALID_HANDLE_VALUE)
10965 return PyErr_SetFromWindowsErr(0);
10966
10967 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10968 return PyErr_SetFromWindowsErr(0);
10969
10970 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10971 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10972 }
10973#endif /* TERMSIZE_USE_CONIO */
10974
10975 termsize = PyStructSequence_New(&TerminalSizeType);
10976 if (termsize == NULL)
10977 return NULL;
10978 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10979 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10980 if (PyErr_Occurred()) {
10981 Py_DECREF(termsize);
10982 return NULL;
10983 }
10984 return termsize;
10985}
10986#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10987
Larry Hastings2f936352014-08-05 14:04:04 +100010988
10989/*[clinic input]
10990os.cpu_count
10991
Charles-François Natali80d62e62015-08-13 20:37:08 +010010992Return the number of CPUs in the system; return None if indeterminable.
10993
10994This number is not equivalent to the number of CPUs the current process can
10995use. The number of usable CPUs can be obtained with
10996``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010997[clinic start generated code]*/
10998
Larry Hastings2f936352014-08-05 14:04:04 +100010999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011000os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011001/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011002{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011003 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011004#ifdef MS_WINDOWS
11005 SYSTEM_INFO sysinfo;
11006 GetSystemInfo(&sysinfo);
11007 ncpu = sysinfo.dwNumberOfProcessors;
11008#elif defined(__hpux)
11009 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11010#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11011 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011012#elif defined(__DragonFly__) || \
11013 defined(__OpenBSD__) || \
11014 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011015 defined(__NetBSD__) || \
11016 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011017 int mib[2];
11018 size_t len = sizeof(ncpu);
11019 mib[0] = CTL_HW;
11020 mib[1] = HW_NCPU;
11021 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11022 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011023#endif
11024 if (ncpu >= 1)
11025 return PyLong_FromLong(ncpu);
11026 else
11027 Py_RETURN_NONE;
11028}
11029
Victor Stinnerdaf45552013-08-28 00:53:59 +020011030
Larry Hastings2f936352014-08-05 14:04:04 +100011031/*[clinic input]
11032os.get_inheritable -> bool
11033
11034 fd: int
11035 /
11036
11037Get the close-on-exe flag of the specified file descriptor.
11038[clinic start generated code]*/
11039
Larry Hastings2f936352014-08-05 14:04:04 +100011040static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011041os_get_inheritable_impl(PyObject *module, int fd)
11042/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011043{
Steve Dower8fc89802015-04-12 00:26:27 -040011044 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011045 _Py_BEGIN_SUPPRESS_IPH
11046 return_value = _Py_get_inheritable(fd);
11047 _Py_END_SUPPRESS_IPH
11048 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011049}
11050
11051
11052/*[clinic input]
11053os.set_inheritable
11054 fd: int
11055 inheritable: int
11056 /
11057
11058Set the inheritable flag of the specified file descriptor.
11059[clinic start generated code]*/
11060
Larry Hastings2f936352014-08-05 14:04:04 +100011061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011062os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11063/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011064{
Steve Dower8fc89802015-04-12 00:26:27 -040011065 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011066
Steve Dower8fc89802015-04-12 00:26:27 -040011067 _Py_BEGIN_SUPPRESS_IPH
11068 result = _Py_set_inheritable(fd, inheritable, NULL);
11069 _Py_END_SUPPRESS_IPH
11070 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011071 return NULL;
11072 Py_RETURN_NONE;
11073}
11074
11075
11076#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011077/*[clinic input]
11078os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011079 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011080 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011081
Larry Hastings2f936352014-08-05 14:04:04 +100011082Get the close-on-exe flag of the specified file descriptor.
11083[clinic start generated code]*/
11084
Larry Hastings2f936352014-08-05 14:04:04 +100011085static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011086os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011087/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011088{
11089 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011090
11091 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11092 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011093 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011094 }
11095
Larry Hastings2f936352014-08-05 14:04:04 +100011096 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011097}
11098
Victor Stinnerdaf45552013-08-28 00:53:59 +020011099
Larry Hastings2f936352014-08-05 14:04:04 +100011100/*[clinic input]
11101os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011102 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011103 inheritable: bool
11104 /
11105
11106Set the inheritable flag of the specified handle.
11107[clinic start generated code]*/
11108
Larry Hastings2f936352014-08-05 14:04:04 +100011109static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011110os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011111 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011112/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011113{
11114 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011115 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11116 PyErr_SetFromWindowsErr(0);
11117 return NULL;
11118 }
11119 Py_RETURN_NONE;
11120}
Larry Hastings2f936352014-08-05 14:04:04 +100011121#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011122
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011123#ifndef MS_WINDOWS
11124PyDoc_STRVAR(get_blocking__doc__,
11125 "get_blocking(fd) -> bool\n" \
11126 "\n" \
11127 "Get the blocking mode of the file descriptor:\n" \
11128 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11129
11130static PyObject*
11131posix_get_blocking(PyObject *self, PyObject *args)
11132{
11133 int fd;
11134 int blocking;
11135
11136 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11137 return NULL;
11138
Steve Dower8fc89802015-04-12 00:26:27 -040011139 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011140 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011141 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011142 if (blocking < 0)
11143 return NULL;
11144 return PyBool_FromLong(blocking);
11145}
11146
11147PyDoc_STRVAR(set_blocking__doc__,
11148 "set_blocking(fd, blocking)\n" \
11149 "\n" \
11150 "Set the blocking mode of the specified file descriptor.\n" \
11151 "Set the O_NONBLOCK flag if blocking is False,\n" \
11152 "clear the O_NONBLOCK flag otherwise.");
11153
11154static PyObject*
11155posix_set_blocking(PyObject *self, PyObject *args)
11156{
Steve Dower8fc89802015-04-12 00:26:27 -040011157 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011158
11159 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11160 return NULL;
11161
Steve Dower8fc89802015-04-12 00:26:27 -040011162 _Py_BEGIN_SUPPRESS_IPH
11163 result = _Py_set_blocking(fd, blocking);
11164 _Py_END_SUPPRESS_IPH
11165 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011166 return NULL;
11167 Py_RETURN_NONE;
11168}
11169#endif /* !MS_WINDOWS */
11170
11171
Victor Stinner6036e442015-03-08 01:58:04 +010011172PyDoc_STRVAR(posix_scandir__doc__,
11173"scandir(path='.') -> iterator of DirEntry objects for given path");
11174
11175static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11176
11177typedef struct {
11178 PyObject_HEAD
11179 PyObject *name;
11180 PyObject *path;
11181 PyObject *stat;
11182 PyObject *lstat;
11183#ifdef MS_WINDOWS
11184 struct _Py_stat_struct win32_lstat;
Victor Stinner68d29802017-03-09 18:43:39 +010011185 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011186 int got_file_index;
11187#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011188#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011189 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011190#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011191 ino_t d_ino;
11192#endif
11193} DirEntry;
11194
11195static void
11196DirEntry_dealloc(DirEntry *entry)
11197{
11198 Py_XDECREF(entry->name);
11199 Py_XDECREF(entry->path);
11200 Py_XDECREF(entry->stat);
11201 Py_XDECREF(entry->lstat);
11202 Py_TYPE(entry)->tp_free((PyObject *)entry);
11203}
11204
11205/* Forward reference */
11206static int
11207DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11208
11209/* Set exception and return -1 on error, 0 for False, 1 for True */
11210static int
11211DirEntry_is_symlink(DirEntry *self)
11212{
11213#ifdef MS_WINDOWS
11214 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011215#elif defined(HAVE_DIRENT_D_TYPE)
11216 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011217 if (self->d_type != DT_UNKNOWN)
11218 return self->d_type == DT_LNK;
11219 else
11220 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011221#else
11222 /* POSIX without d_type */
11223 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011224#endif
11225}
11226
11227static PyObject *
11228DirEntry_py_is_symlink(DirEntry *self)
11229{
11230 int result;
11231
11232 result = DirEntry_is_symlink(self);
11233 if (result == -1)
11234 return NULL;
11235 return PyBool_FromLong(result);
11236}
11237
11238static PyObject *
11239DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11240{
11241 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011242 STRUCT_STAT st;
11243 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011244
11245#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011246 if (PyUnicode_FSDecoder(self->path, &ub)) {
11247 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011248#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011249 if (PyUnicode_FSConverter(self->path, &ub)) {
11250 const char *path = PyBytes_AS_STRING(ub);
11251#endif
11252 if (follow_symlinks)
11253 result = STAT(path, &st);
11254 else
11255 result = LSTAT(path, &st);
11256 Py_DECREF(ub);
11257 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011258 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011259
11260 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011261 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011262
11263 return _pystat_fromstructstat(&st);
11264}
11265
11266static PyObject *
11267DirEntry_get_lstat(DirEntry *self)
11268{
11269 if (!self->lstat) {
11270#ifdef MS_WINDOWS
11271 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11272#else /* POSIX */
11273 self->lstat = DirEntry_fetch_stat(self, 0);
11274#endif
11275 }
11276 Py_XINCREF(self->lstat);
11277 return self->lstat;
11278}
11279
11280static PyObject *
11281DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11282{
11283 if (!follow_symlinks)
11284 return DirEntry_get_lstat(self);
11285
11286 if (!self->stat) {
11287 int result = DirEntry_is_symlink(self);
11288 if (result == -1)
11289 return NULL;
11290 else if (result)
11291 self->stat = DirEntry_fetch_stat(self, 1);
11292 else
11293 self->stat = DirEntry_get_lstat(self);
11294 }
11295
11296 Py_XINCREF(self->stat);
11297 return self->stat;
11298}
11299
11300static PyObject *
11301DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11302{
11303 int follow_symlinks = 1;
11304
11305 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11306 follow_symlinks_keywords, &follow_symlinks))
11307 return NULL;
11308
11309 return DirEntry_get_stat(self, follow_symlinks);
11310}
11311
11312/* Set exception and return -1 on error, 0 for False, 1 for True */
11313static int
11314DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11315{
11316 PyObject *stat = NULL;
11317 PyObject *st_mode = NULL;
11318 long mode;
11319 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011320#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011321 int is_symlink;
11322 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011323#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011324#ifdef MS_WINDOWS
11325 unsigned long dir_bits;
11326#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011327 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011328
11329#ifdef MS_WINDOWS
11330 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11331 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011332#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011333 is_symlink = self->d_type == DT_LNK;
11334 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11335#endif
11336
Victor Stinner35a97c02015-03-08 02:59:09 +010011337#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011338 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011339#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011340 stat = DirEntry_get_stat(self, follow_symlinks);
11341 if (!stat) {
11342 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11343 /* If file doesn't exist (anymore), then return False
11344 (i.e., say it's not a file/directory) */
11345 PyErr_Clear();
11346 return 0;
11347 }
11348 goto error;
11349 }
11350 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11351 if (!st_mode)
11352 goto error;
11353
11354 mode = PyLong_AsLong(st_mode);
11355 if (mode == -1 && PyErr_Occurred())
11356 goto error;
11357 Py_CLEAR(st_mode);
11358 Py_CLEAR(stat);
11359 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011360#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011361 }
11362 else if (is_symlink) {
11363 assert(mode_bits != S_IFLNK);
11364 result = 0;
11365 }
11366 else {
11367 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11368#ifdef MS_WINDOWS
11369 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11370 if (mode_bits == S_IFDIR)
11371 result = dir_bits != 0;
11372 else
11373 result = dir_bits == 0;
11374#else /* POSIX */
11375 if (mode_bits == S_IFDIR)
11376 result = self->d_type == DT_DIR;
11377 else
11378 result = self->d_type == DT_REG;
11379#endif
11380 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011381#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011382
11383 return result;
11384
11385error:
11386 Py_XDECREF(st_mode);
11387 Py_XDECREF(stat);
11388 return -1;
11389}
11390
11391static PyObject *
11392DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11393{
11394 int result;
11395
11396 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11397 if (result == -1)
11398 return NULL;
11399 return PyBool_FromLong(result);
11400}
11401
11402static PyObject *
11403DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11404{
11405 int follow_symlinks = 1;
11406
11407 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11408 follow_symlinks_keywords, &follow_symlinks))
11409 return NULL;
11410
11411 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11412}
11413
11414static PyObject *
11415DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11416{
11417 int follow_symlinks = 1;
11418
11419 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11420 follow_symlinks_keywords, &follow_symlinks))
11421 return NULL;
11422
11423 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11424}
11425
11426static PyObject *
11427DirEntry_inode(DirEntry *self)
11428{
11429#ifdef MS_WINDOWS
11430 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011431 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011432 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011433 STRUCT_STAT stat;
11434 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011435
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011436 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011437 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011438 path = PyUnicode_AsUnicode(unicode);
11439 result = LSTAT(path, &stat);
11440 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011441
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011442 if (result != 0)
11443 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011444
11445 self->win32_file_index = stat.st_ino;
11446 self->got_file_index = 1;
11447 }
Victor Stinner68d29802017-03-09 18:43:39 +010011448 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11449 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011450#else /* POSIX */
11451#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011452 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011453#else
11454 return PyLong_FromLong((long)self->d_ino);
11455#endif
11456#endif
11457}
11458
11459static PyObject *
11460DirEntry_repr(DirEntry *self)
11461{
11462 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11463}
11464
Brett Cannon96881cd2016-06-10 14:37:21 -070011465static PyObject *
11466DirEntry_fspath(DirEntry *self)
11467{
11468 Py_INCREF(self->path);
11469 return self->path;
11470}
11471
Victor Stinner6036e442015-03-08 01:58:04 +010011472static PyMemberDef DirEntry_members[] = {
11473 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11474 "the entry's base filename, relative to scandir() \"path\" argument"},
11475 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11476 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11477 {NULL}
11478};
11479
11480static PyMethodDef DirEntry_methods[] = {
11481 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11482 "return True if the entry is a directory; cached per entry"
11483 },
11484 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11485 "return True if the entry is a file; cached per entry"
11486 },
11487 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11488 "return True if the entry is a symbolic link; cached per entry"
11489 },
11490 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11491 "return stat_result object for the entry; cached per entry"
11492 },
11493 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11494 "return inode of the entry; cached per entry",
11495 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011496 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11497 "returns the path for the entry",
11498 },
Victor Stinner6036e442015-03-08 01:58:04 +010011499 {NULL}
11500};
11501
Benjamin Peterson5646de42015-04-12 17:56:34 -040011502static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011503 PyVarObject_HEAD_INIT(NULL, 0)
11504 MODNAME ".DirEntry", /* tp_name */
11505 sizeof(DirEntry), /* tp_basicsize */
11506 0, /* tp_itemsize */
11507 /* methods */
11508 (destructor)DirEntry_dealloc, /* tp_dealloc */
11509 0, /* tp_print */
11510 0, /* tp_getattr */
11511 0, /* tp_setattr */
11512 0, /* tp_compare */
11513 (reprfunc)DirEntry_repr, /* tp_repr */
11514 0, /* tp_as_number */
11515 0, /* tp_as_sequence */
11516 0, /* tp_as_mapping */
11517 0, /* tp_hash */
11518 0, /* tp_call */
11519 0, /* tp_str */
11520 0, /* tp_getattro */
11521 0, /* tp_setattro */
11522 0, /* tp_as_buffer */
11523 Py_TPFLAGS_DEFAULT, /* tp_flags */
11524 0, /* tp_doc */
11525 0, /* tp_traverse */
11526 0, /* tp_clear */
11527 0, /* tp_richcompare */
11528 0, /* tp_weaklistoffset */
11529 0, /* tp_iter */
11530 0, /* tp_iternext */
11531 DirEntry_methods, /* tp_methods */
11532 DirEntry_members, /* tp_members */
11533};
11534
11535#ifdef MS_WINDOWS
11536
11537static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011538join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011539{
11540 Py_ssize_t path_len;
11541 Py_ssize_t size;
11542 wchar_t *result;
11543 wchar_t ch;
11544
11545 if (!path_wide) { /* Default arg: "." */
11546 path_wide = L".";
11547 path_len = 1;
11548 }
11549 else {
11550 path_len = wcslen(path_wide);
11551 }
11552
11553 /* The +1's are for the path separator and the NUL */
11554 size = path_len + 1 + wcslen(filename) + 1;
11555 result = PyMem_New(wchar_t, size);
11556 if (!result) {
11557 PyErr_NoMemory();
11558 return NULL;
11559 }
11560 wcscpy(result, path_wide);
11561 if (path_len > 0) {
11562 ch = result[path_len - 1];
11563 if (ch != SEP && ch != ALTSEP && ch != L':')
11564 result[path_len++] = SEP;
11565 wcscpy(result + path_len, filename);
11566 }
11567 return result;
11568}
11569
11570static PyObject *
11571DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11572{
11573 DirEntry *entry;
11574 BY_HANDLE_FILE_INFORMATION file_info;
11575 ULONG reparse_tag;
11576 wchar_t *joined_path;
11577
11578 entry = PyObject_New(DirEntry, &DirEntryType);
11579 if (!entry)
11580 return NULL;
11581 entry->name = NULL;
11582 entry->path = NULL;
11583 entry->stat = NULL;
11584 entry->lstat = NULL;
11585 entry->got_file_index = 0;
11586
11587 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11588 if (!entry->name)
11589 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011590 if (path->narrow) {
11591 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11592 if (!entry->name)
11593 goto error;
11594 }
Victor Stinner6036e442015-03-08 01:58:04 +010011595
11596 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11597 if (!joined_path)
11598 goto error;
11599
11600 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11601 PyMem_Free(joined_path);
11602 if (!entry->path)
11603 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011604 if (path->narrow) {
11605 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11606 if (!entry->path)
11607 goto error;
11608 }
Victor Stinner6036e442015-03-08 01:58:04 +010011609
Steve Dowercc16be82016-09-08 10:35:16 -070011610 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011611 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11612
11613 return (PyObject *)entry;
11614
11615error:
11616 Py_DECREF(entry);
11617 return NULL;
11618}
11619
11620#else /* POSIX */
11621
11622static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011623join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011624{
11625 Py_ssize_t path_len;
11626 Py_ssize_t size;
11627 char *result;
11628
11629 if (!path_narrow) { /* Default arg: "." */
11630 path_narrow = ".";
11631 path_len = 1;
11632 }
11633 else {
11634 path_len = strlen(path_narrow);
11635 }
11636
11637 if (filename_len == -1)
11638 filename_len = strlen(filename);
11639
11640 /* The +1's are for the path separator and the NUL */
11641 size = path_len + 1 + filename_len + 1;
11642 result = PyMem_New(char, size);
11643 if (!result) {
11644 PyErr_NoMemory();
11645 return NULL;
11646 }
11647 strcpy(result, path_narrow);
11648 if (path_len > 0 && result[path_len - 1] != '/')
11649 result[path_len++] = '/';
11650 strcpy(result + path_len, filename);
11651 return result;
11652}
11653
11654static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011655DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011656 ino_t d_ino
11657#ifdef HAVE_DIRENT_D_TYPE
11658 , unsigned char d_type
11659#endif
11660 )
Victor Stinner6036e442015-03-08 01:58:04 +010011661{
11662 DirEntry *entry;
11663 char *joined_path;
11664
11665 entry = PyObject_New(DirEntry, &DirEntryType);
11666 if (!entry)
11667 return NULL;
11668 entry->name = NULL;
11669 entry->path = NULL;
11670 entry->stat = NULL;
11671 entry->lstat = NULL;
11672
11673 joined_path = join_path_filename(path->narrow, name, name_len);
11674 if (!joined_path)
11675 goto error;
11676
11677 if (!path->narrow || !PyBytes_Check(path->object)) {
11678 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11679 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11680 }
11681 else {
11682 entry->name = PyBytes_FromStringAndSize(name, name_len);
11683 entry->path = PyBytes_FromString(joined_path);
11684 }
11685 PyMem_Free(joined_path);
11686 if (!entry->name || !entry->path)
11687 goto error;
11688
Victor Stinner35a97c02015-03-08 02:59:09 +010011689#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011690 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011691#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011692 entry->d_ino = d_ino;
11693
11694 return (PyObject *)entry;
11695
11696error:
11697 Py_XDECREF(entry);
11698 return NULL;
11699}
11700
11701#endif
11702
11703
11704typedef struct {
11705 PyObject_HEAD
11706 path_t path;
11707#ifdef MS_WINDOWS
11708 HANDLE handle;
11709 WIN32_FIND_DATAW file_data;
11710 int first_time;
11711#else /* POSIX */
11712 DIR *dirp;
11713#endif
11714} ScandirIterator;
11715
11716#ifdef MS_WINDOWS
11717
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011718static int
11719ScandirIterator_is_closed(ScandirIterator *iterator)
11720{
11721 return iterator->handle == INVALID_HANDLE_VALUE;
11722}
11723
Victor Stinner6036e442015-03-08 01:58:04 +010011724static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011725ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011726{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011727 HANDLE handle = iterator->handle;
11728
11729 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011730 return;
11731
Victor Stinner6036e442015-03-08 01:58:04 +010011732 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011733 Py_BEGIN_ALLOW_THREADS
11734 FindClose(handle);
11735 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011736}
11737
11738static PyObject *
11739ScandirIterator_iternext(ScandirIterator *iterator)
11740{
11741 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11742 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011743 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011744
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011745 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011746 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011747 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011748
11749 while (1) {
11750 if (!iterator->first_time) {
11751 Py_BEGIN_ALLOW_THREADS
11752 success = FindNextFileW(iterator->handle, file_data);
11753 Py_END_ALLOW_THREADS
11754 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011755 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011756 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011757 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011758 break;
11759 }
11760 }
11761 iterator->first_time = 0;
11762
11763 /* Skip over . and .. */
11764 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011765 wcscmp(file_data->cFileName, L"..") != 0) {
11766 entry = DirEntry_from_find_data(&iterator->path, file_data);
11767 if (!entry)
11768 break;
11769 return entry;
11770 }
Victor Stinner6036e442015-03-08 01:58:04 +010011771
11772 /* Loop till we get a non-dot directory or finish iterating */
11773 }
11774
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011775 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011776 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011777 return NULL;
11778}
11779
11780#else /* POSIX */
11781
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011782static int
11783ScandirIterator_is_closed(ScandirIterator *iterator)
11784{
11785 return !iterator->dirp;
11786}
11787
Victor Stinner6036e442015-03-08 01:58:04 +010011788static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011789ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011790{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011791 DIR *dirp = iterator->dirp;
11792
11793 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011794 return;
11795
Victor Stinner6036e442015-03-08 01:58:04 +010011796 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011797 Py_BEGIN_ALLOW_THREADS
11798 closedir(dirp);
11799 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011800 return;
11801}
11802
11803static PyObject *
11804ScandirIterator_iternext(ScandirIterator *iterator)
11805{
11806 struct dirent *direntp;
11807 Py_ssize_t name_len;
11808 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011809 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011810
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011811 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011812 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011813 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011814
11815 while (1) {
11816 errno = 0;
11817 Py_BEGIN_ALLOW_THREADS
11818 direntp = readdir(iterator->dirp);
11819 Py_END_ALLOW_THREADS
11820
11821 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011822 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011823 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011824 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011825 break;
11826 }
11827
11828 /* Skip over . and .. */
11829 name_len = NAMLEN(direntp);
11830 is_dot = direntp->d_name[0] == '.' &&
11831 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11832 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011833 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011834 name_len, direntp->d_ino
11835#ifdef HAVE_DIRENT_D_TYPE
11836 , direntp->d_type
11837#endif
11838 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011839 if (!entry)
11840 break;
11841 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011842 }
11843
11844 /* Loop till we get a non-dot directory or finish iterating */
11845 }
11846
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011847 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011848 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011849 return NULL;
11850}
11851
11852#endif
11853
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011854static PyObject *
11855ScandirIterator_close(ScandirIterator *self, PyObject *args)
11856{
11857 ScandirIterator_closedir(self);
11858 Py_RETURN_NONE;
11859}
11860
11861static PyObject *
11862ScandirIterator_enter(PyObject *self, PyObject *args)
11863{
11864 Py_INCREF(self);
11865 return self;
11866}
11867
11868static PyObject *
11869ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11870{
11871 ScandirIterator_closedir(self);
11872 Py_RETURN_NONE;
11873}
11874
Victor Stinner6036e442015-03-08 01:58:04 +010011875static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011876ScandirIterator_finalize(ScandirIterator *iterator)
11877{
11878 PyObject *error_type, *error_value, *error_traceback;
11879
11880 /* Save the current exception, if any. */
11881 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11882
11883 if (!ScandirIterator_is_closed(iterator)) {
11884 ScandirIterator_closedir(iterator);
11885
11886 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11887 "unclosed scandir iterator %R", iterator)) {
11888 /* Spurious errors can appear at shutdown */
11889 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11890 PyErr_WriteUnraisable((PyObject *) iterator);
11891 }
11892 }
11893 }
11894
Victor Stinner7bfa4092016-03-23 00:43:54 +010011895 path_cleanup(&iterator->path);
11896
11897 /* Restore the saved exception. */
11898 PyErr_Restore(error_type, error_value, error_traceback);
11899}
11900
11901static void
Victor Stinner6036e442015-03-08 01:58:04 +010011902ScandirIterator_dealloc(ScandirIterator *iterator)
11903{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011904 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11905 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011906
Victor Stinner6036e442015-03-08 01:58:04 +010011907 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11908}
11909
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011910static PyMethodDef ScandirIterator_methods[] = {
11911 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11912 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11913 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11914 {NULL}
11915};
11916
Benjamin Peterson5646de42015-04-12 17:56:34 -040011917static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011918 PyVarObject_HEAD_INIT(NULL, 0)
11919 MODNAME ".ScandirIterator", /* tp_name */
11920 sizeof(ScandirIterator), /* tp_basicsize */
11921 0, /* tp_itemsize */
11922 /* methods */
11923 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11924 0, /* tp_print */
11925 0, /* tp_getattr */
11926 0, /* tp_setattr */
11927 0, /* tp_compare */
11928 0, /* tp_repr */
11929 0, /* tp_as_number */
11930 0, /* tp_as_sequence */
11931 0, /* tp_as_mapping */
11932 0, /* tp_hash */
11933 0, /* tp_call */
11934 0, /* tp_str */
11935 0, /* tp_getattro */
11936 0, /* tp_setattro */
11937 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011938 Py_TPFLAGS_DEFAULT
11939 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011940 0, /* tp_doc */
11941 0, /* tp_traverse */
11942 0, /* tp_clear */
11943 0, /* tp_richcompare */
11944 0, /* tp_weaklistoffset */
11945 PyObject_SelfIter, /* tp_iter */
11946 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011947 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011948 0, /* tp_members */
11949 0, /* tp_getset */
11950 0, /* tp_base */
11951 0, /* tp_dict */
11952 0, /* tp_descr_get */
11953 0, /* tp_descr_set */
11954 0, /* tp_dictoffset */
11955 0, /* tp_init */
11956 0, /* tp_alloc */
11957 0, /* tp_new */
11958 0, /* tp_free */
11959 0, /* tp_is_gc */
11960 0, /* tp_bases */
11961 0, /* tp_mro */
11962 0, /* tp_cache */
11963 0, /* tp_subclasses */
11964 0, /* tp_weaklist */
11965 0, /* tp_del */
11966 0, /* tp_version_tag */
11967 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011968};
11969
11970static PyObject *
11971posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11972{
11973 ScandirIterator *iterator;
11974 static char *keywords[] = {"path", NULL};
11975#ifdef MS_WINDOWS
11976 wchar_t *path_strW;
11977#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011978 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011979#endif
11980
11981 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11982 if (!iterator)
11983 return NULL;
11984 memset(&iterator->path, 0, sizeof(path_t));
11985 iterator->path.function_name = "scandir";
11986 iterator->path.nullable = 1;
11987
11988#ifdef MS_WINDOWS
11989 iterator->handle = INVALID_HANDLE_VALUE;
11990#else
11991 iterator->dirp = NULL;
11992#endif
11993
11994 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11995 path_converter, &iterator->path))
11996 goto error;
11997
Victor Stinner6036e442015-03-08 01:58:04 +010011998#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011999 iterator->first_time = 1;
12000
12001 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12002 if (!path_strW)
12003 goto error;
12004
12005 Py_BEGIN_ALLOW_THREADS
12006 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12007 Py_END_ALLOW_THREADS
12008
12009 PyMem_Free(path_strW);
12010
12011 if (iterator->handle == INVALID_HANDLE_VALUE) {
12012 path_error(&iterator->path);
12013 goto error;
12014 }
12015#else /* POSIX */
12016 if (iterator->path.narrow)
12017 path = iterator->path.narrow;
12018 else
12019 path = ".";
12020
12021 errno = 0;
12022 Py_BEGIN_ALLOW_THREADS
12023 iterator->dirp = opendir(path);
12024 Py_END_ALLOW_THREADS
12025
12026 if (!iterator->dirp) {
12027 path_error(&iterator->path);
12028 goto error;
12029 }
12030#endif
12031
12032 return (PyObject *)iterator;
12033
12034error:
12035 Py_DECREF(iterator);
12036 return NULL;
12037}
12038
Ethan Furman410ef8e2016-06-04 12:06:26 -070012039/*
12040 Return the file system path representation of the object.
12041
12042 If the object is str or bytes, then allow it to pass through with
12043 an incremented refcount. If the object defines __fspath__(), then
12044 return the result of that method. All other types raise a TypeError.
12045*/
12046PyObject *
12047PyOS_FSPath(PyObject *path)
12048{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012049 /* For error message reasons, this function is manually inlined in
12050 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012051 _Py_IDENTIFIER(__fspath__);
12052 PyObject *func = NULL;
12053 PyObject *path_repr = NULL;
12054
12055 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12056 Py_INCREF(path);
12057 return path;
12058 }
12059
12060 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12061 if (NULL == func) {
12062 return PyErr_Format(PyExc_TypeError,
12063 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012064 "not %.200s",
12065 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012066 }
12067
12068 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12069 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012070 if (NULL == path_repr) {
12071 return NULL;
12072 }
12073
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012074 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12075 PyErr_Format(PyExc_TypeError,
12076 "expected %.200s.__fspath__() to return str or bytes, "
12077 "not %.200s", Py_TYPE(path)->tp_name,
12078 Py_TYPE(path_repr)->tp_name);
12079 Py_DECREF(path_repr);
12080 return NULL;
12081 }
12082
Ethan Furman410ef8e2016-06-04 12:06:26 -070012083 return path_repr;
12084}
12085
12086/*[clinic input]
12087os.fspath
12088
12089 path: object
12090
12091Return the file system path representation of the object.
12092
Brett Cannonb4f43e92016-06-09 14:32:08 -070012093If the object is str or bytes, then allow it to pass through as-is. If the
12094object defines __fspath__(), then return the result of that method. All other
12095types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012096[clinic start generated code]*/
12097
12098static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012099os_fspath_impl(PyObject *module, PyObject *path)
12100/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012101{
12102 return PyOS_FSPath(path);
12103}
Victor Stinner6036e442015-03-08 01:58:04 +010012104
Victor Stinner9b1f4742016-09-06 16:18:52 -070012105#ifdef HAVE_GETRANDOM_SYSCALL
12106/*[clinic input]
12107os.getrandom
12108
12109 size: Py_ssize_t
12110 flags: int=0
12111
12112Obtain a series of random bytes.
12113[clinic start generated code]*/
12114
12115static PyObject *
12116os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12117/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12118{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012119 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012120 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012121
12122 if (size < 0) {
12123 errno = EINVAL;
12124 return posix_error();
12125 }
12126
Victor Stinnerec2319c2016-09-20 23:00:59 +020012127 bytes = PyBytes_FromStringAndSize(NULL, size);
12128 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012129 PyErr_NoMemory();
12130 return NULL;
12131 }
12132
12133 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012134 n = syscall(SYS_getrandom,
12135 PyBytes_AS_STRING(bytes),
12136 PyBytes_GET_SIZE(bytes),
12137 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012138 if (n < 0 && errno == EINTR) {
12139 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012140 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012141 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012142
12143 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012144 continue;
12145 }
12146 break;
12147 }
12148
12149 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012150 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012151 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012152 }
12153
Victor Stinnerec2319c2016-09-20 23:00:59 +020012154 if (n != size) {
12155 _PyBytes_Resize(&bytes, n);
12156 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012157
12158 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012159
12160error:
12161 Py_DECREF(bytes);
12162 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012163}
12164#endif /* HAVE_GETRANDOM_SYSCALL */
12165
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012166#include "clinic/posixmodule.c.h"
12167
Larry Hastings7726ac92014-01-31 22:03:12 -080012168/*[clinic input]
12169dump buffer
12170[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012171/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012172
Larry Hastings31826802013-10-19 00:09:25 -070012173
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012174static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012175
12176 OS_STAT_METHODDEF
12177 OS_ACCESS_METHODDEF
12178 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012179 OS_CHDIR_METHODDEF
12180 OS_CHFLAGS_METHODDEF
12181 OS_CHMOD_METHODDEF
12182 OS_FCHMOD_METHODDEF
12183 OS_LCHMOD_METHODDEF
12184 OS_CHOWN_METHODDEF
12185 OS_FCHOWN_METHODDEF
12186 OS_LCHOWN_METHODDEF
12187 OS_LCHFLAGS_METHODDEF
12188 OS_CHROOT_METHODDEF
12189 OS_CTERMID_METHODDEF
12190 OS_GETCWD_METHODDEF
12191 OS_GETCWDB_METHODDEF
12192 OS_LINK_METHODDEF
12193 OS_LISTDIR_METHODDEF
12194 OS_LSTAT_METHODDEF
12195 OS_MKDIR_METHODDEF
12196 OS_NICE_METHODDEF
12197 OS_GETPRIORITY_METHODDEF
12198 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012199#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012200 {"readlink", (PyCFunction)posix_readlink,
12201 METH_VARARGS | METH_KEYWORDS,
12202 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012203#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012204#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012205 {"readlink", (PyCFunction)win_readlink,
12206 METH_VARARGS | METH_KEYWORDS,
12207 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012208#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012209 OS_RENAME_METHODDEF
12210 OS_REPLACE_METHODDEF
12211 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012212 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012213 OS_SYMLINK_METHODDEF
12214 OS_SYSTEM_METHODDEF
12215 OS_UMASK_METHODDEF
12216 OS_UNAME_METHODDEF
12217 OS_UNLINK_METHODDEF
12218 OS_REMOVE_METHODDEF
12219 OS_UTIME_METHODDEF
12220 OS_TIMES_METHODDEF
12221 OS__EXIT_METHODDEF
12222 OS_EXECV_METHODDEF
12223 OS_EXECVE_METHODDEF
12224 OS_SPAWNV_METHODDEF
12225 OS_SPAWNVE_METHODDEF
12226 OS_FORK1_METHODDEF
12227 OS_FORK_METHODDEF
12228 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12229 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12230 OS_SCHED_GETPARAM_METHODDEF
12231 OS_SCHED_GETSCHEDULER_METHODDEF
12232 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12233 OS_SCHED_SETPARAM_METHODDEF
12234 OS_SCHED_SETSCHEDULER_METHODDEF
12235 OS_SCHED_YIELD_METHODDEF
12236 OS_SCHED_SETAFFINITY_METHODDEF
12237 OS_SCHED_GETAFFINITY_METHODDEF
12238 OS_OPENPTY_METHODDEF
12239 OS_FORKPTY_METHODDEF
12240 OS_GETEGID_METHODDEF
12241 OS_GETEUID_METHODDEF
12242 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012243#ifdef HAVE_GETGROUPLIST
12244 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12245#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012246 OS_GETGROUPS_METHODDEF
12247 OS_GETPID_METHODDEF
12248 OS_GETPGRP_METHODDEF
12249 OS_GETPPID_METHODDEF
12250 OS_GETUID_METHODDEF
12251 OS_GETLOGIN_METHODDEF
12252 OS_KILL_METHODDEF
12253 OS_KILLPG_METHODDEF
12254 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012255#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012256 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012257#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012258 OS_SETUID_METHODDEF
12259 OS_SETEUID_METHODDEF
12260 OS_SETREUID_METHODDEF
12261 OS_SETGID_METHODDEF
12262 OS_SETEGID_METHODDEF
12263 OS_SETREGID_METHODDEF
12264 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012265#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012266 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012267#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012268 OS_GETPGID_METHODDEF
12269 OS_SETPGRP_METHODDEF
12270 OS_WAIT_METHODDEF
12271 OS_WAIT3_METHODDEF
12272 OS_WAIT4_METHODDEF
12273 OS_WAITID_METHODDEF
12274 OS_WAITPID_METHODDEF
12275 OS_GETSID_METHODDEF
12276 OS_SETSID_METHODDEF
12277 OS_SETPGID_METHODDEF
12278 OS_TCGETPGRP_METHODDEF
12279 OS_TCSETPGRP_METHODDEF
12280 OS_OPEN_METHODDEF
12281 OS_CLOSE_METHODDEF
12282 OS_CLOSERANGE_METHODDEF
12283 OS_DEVICE_ENCODING_METHODDEF
12284 OS_DUP_METHODDEF
12285 OS_DUP2_METHODDEF
12286 OS_LOCKF_METHODDEF
12287 OS_LSEEK_METHODDEF
12288 OS_READ_METHODDEF
12289 OS_READV_METHODDEF
12290 OS_PREAD_METHODDEF
12291 OS_WRITE_METHODDEF
12292 OS_WRITEV_METHODDEF
12293 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012294#ifdef HAVE_SENDFILE
12295 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12296 posix_sendfile__doc__},
12297#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012298 OS_FSTAT_METHODDEF
12299 OS_ISATTY_METHODDEF
12300 OS_PIPE_METHODDEF
12301 OS_PIPE2_METHODDEF
12302 OS_MKFIFO_METHODDEF
12303 OS_MKNOD_METHODDEF
12304 OS_MAJOR_METHODDEF
12305 OS_MINOR_METHODDEF
12306 OS_MAKEDEV_METHODDEF
12307 OS_FTRUNCATE_METHODDEF
12308 OS_TRUNCATE_METHODDEF
12309 OS_POSIX_FALLOCATE_METHODDEF
12310 OS_POSIX_FADVISE_METHODDEF
12311 OS_PUTENV_METHODDEF
12312 OS_UNSETENV_METHODDEF
12313 OS_STRERROR_METHODDEF
12314 OS_FCHDIR_METHODDEF
12315 OS_FSYNC_METHODDEF
12316 OS_SYNC_METHODDEF
12317 OS_FDATASYNC_METHODDEF
12318 OS_WCOREDUMP_METHODDEF
12319 OS_WIFCONTINUED_METHODDEF
12320 OS_WIFSTOPPED_METHODDEF
12321 OS_WIFSIGNALED_METHODDEF
12322 OS_WIFEXITED_METHODDEF
12323 OS_WEXITSTATUS_METHODDEF
12324 OS_WTERMSIG_METHODDEF
12325 OS_WSTOPSIG_METHODDEF
12326 OS_FSTATVFS_METHODDEF
12327 OS_STATVFS_METHODDEF
12328 OS_CONFSTR_METHODDEF
12329 OS_SYSCONF_METHODDEF
12330 OS_FPATHCONF_METHODDEF
12331 OS_PATHCONF_METHODDEF
12332 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012333 OS__GETFULLPATHNAME_METHODDEF
12334 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012335 OS__GETDISKUSAGE_METHODDEF
12336 OS__GETFINALPATHNAME_METHODDEF
12337 OS__GETVOLUMEPATHNAME_METHODDEF
12338 OS_GETLOADAVG_METHODDEF
12339 OS_URANDOM_METHODDEF
12340 OS_SETRESUID_METHODDEF
12341 OS_SETRESGID_METHODDEF
12342 OS_GETRESUID_METHODDEF
12343 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012344
Larry Hastings2f936352014-08-05 14:04:04 +100012345 OS_GETXATTR_METHODDEF
12346 OS_SETXATTR_METHODDEF
12347 OS_REMOVEXATTR_METHODDEF
12348 OS_LISTXATTR_METHODDEF
12349
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012350#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12351 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12352#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012353 OS_CPU_COUNT_METHODDEF
12354 OS_GET_INHERITABLE_METHODDEF
12355 OS_SET_INHERITABLE_METHODDEF
12356 OS_GET_HANDLE_INHERITABLE_METHODDEF
12357 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012358#ifndef MS_WINDOWS
12359 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12360 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12361#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012362 {"scandir", (PyCFunction)posix_scandir,
12363 METH_VARARGS | METH_KEYWORDS,
12364 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012365 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012366 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012367 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012368};
12369
12370
Brian Curtin52173d42010-12-02 18:29:18 +000012371#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012372static int
Brian Curtin52173d42010-12-02 18:29:18 +000012373enable_symlink()
12374{
12375 HANDLE tok;
12376 TOKEN_PRIVILEGES tok_priv;
12377 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012378
12379 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012380 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012381
12382 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012383 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012384
12385 tok_priv.PrivilegeCount = 1;
12386 tok_priv.Privileges[0].Luid = luid;
12387 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12388
12389 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12390 sizeof(TOKEN_PRIVILEGES),
12391 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012392 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012393
Brian Curtin3b4499c2010-12-28 14:31:47 +000012394 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12395 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012396}
12397#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12398
Barry Warsaw4a342091996-12-19 23:50:02 +000012399static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012401{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012402#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012404#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012405#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012407#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012408#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012410#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012411#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012413#endif
Fred Drakec9680921999-12-13 16:37:25 +000012414#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012416#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012417#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012419#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012420#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012422#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012423#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012424 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012425#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012426#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012428#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012429#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012430 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#endif
12432#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012433 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012434#endif
12435#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012437#endif
12438#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012439 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012440#endif
12441#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012442 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012443#endif
12444#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012445 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012446#endif
12447#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012449#endif
12450#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012452#endif
12453#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012454 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012455#endif
12456#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012457 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012458#endif
12459#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012460 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012461#endif
12462#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012463 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012464#endif
12465#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012466 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012467#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012468#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012469 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012470#endif
12471#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012472 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012473#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012474#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012475 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012476#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012477#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012478 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012479#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012480#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012481#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012483#endif
12484#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012486#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012487#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012488#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012489 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012490#endif
12491#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012492 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012493#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012494#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012495 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012496#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012497#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012498 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012499#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012500#ifdef O_TMPFILE
12501 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12502#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012503#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012504 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012505#endif
12506#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012507 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012508#endif
12509#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012510 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012511#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012512#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012513 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012514#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012515#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012516 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012517#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012518
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012519
Jesus Cea94363612012-06-22 18:32:07 +020012520#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012522#endif
12523#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012525#endif
12526
Tim Peters5aa91602002-01-30 05:46:57 +000012527/* MS Windows */
12528#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012529 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012531#endif
12532#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012533 /* Optimize for short life (keep in memory). */
12534 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012535 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012536#endif
12537#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012538 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012539 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012540#endif
12541#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012542 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012544#endif
12545#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012547 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012548#endif
12549
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012550/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012551#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012552 /* Send a SIGIO signal whenever input or output
12553 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012555#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012556#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012557 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012559#endif
12560#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012561 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012563#endif
12564#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012567#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012568#ifdef O_NOLINKS
12569 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012571#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012572#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012573 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012575#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012576
Victor Stinner8c62be82010-05-06 00:08:46 +000012577 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012598#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012599#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012601#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012602#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012604#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012605#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012606 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012607#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012608#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012609 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012610#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012611#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012612 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012613#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012614#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012615 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012616#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012617#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012618 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012619#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012620#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012622#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012623#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012624 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012625#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012626#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012628#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012629
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012630 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012631#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012633#endif /* ST_RDONLY */
12634#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012636#endif /* ST_NOSUID */
12637
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012638 /* GNU extensions */
12639#ifdef ST_NODEV
12640 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12641#endif /* ST_NODEV */
12642#ifdef ST_NOEXEC
12643 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12644#endif /* ST_NOEXEC */
12645#ifdef ST_SYNCHRONOUS
12646 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12647#endif /* ST_SYNCHRONOUS */
12648#ifdef ST_MANDLOCK
12649 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12650#endif /* ST_MANDLOCK */
12651#ifdef ST_WRITE
12652 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12653#endif /* ST_WRITE */
12654#ifdef ST_APPEND
12655 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12656#endif /* ST_APPEND */
12657#ifdef ST_NOATIME
12658 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12659#endif /* ST_NOATIME */
12660#ifdef ST_NODIRATIME
12661 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12662#endif /* ST_NODIRATIME */
12663#ifdef ST_RELATIME
12664 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12665#endif /* ST_RELATIME */
12666
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012667 /* FreeBSD sendfile() constants */
12668#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012669 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012670#endif
12671#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012673#endif
12674#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012676#endif
12677
Ross Lagerwall7807c352011-03-17 20:20:30 +020012678 /* constants for posix_fadvise */
12679#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012681#endif
12682#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684#endif
12685#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012693#endif
12694#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697
12698 /* constants for waitid */
12699#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12701 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12702 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012703#endif
12704#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012705 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012706#endif
12707#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012709#endif
12710#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012712#endif
12713#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012715#endif
12716#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012718#endif
12719#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012721#endif
12722#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012724#endif
12725
12726 /* constants for lockf */
12727#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012729#endif
12730#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012732#endif
12733#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012735#endif
12736#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012738#endif
12739
Guido van Rossum246bc171999-02-01 23:54:31 +000012740#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12742 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12743 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12744 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12745 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012746#endif
12747
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012748#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012749#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012751#endif
12752#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012754#endif
12755#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012757#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012758#ifdef SCHED_SPORADIC
Serhiy Storchakaf75f6ed2017-06-15 16:57:53 +030012759 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012760#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012761#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012763#endif
12764#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012766#endif
12767#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012769#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012770#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012772#endif
12773#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012775#endif
12776#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012777 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012778#endif
12779#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012781#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012782#endif
12783
Benjamin Peterson9428d532011-09-14 11:45:52 -040012784#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12786 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12787 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012788#endif
12789
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012790#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012792#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012793#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012795#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012796#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012798#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012799#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012801#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012802#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012804#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012805#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012806 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012807#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012808#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012809 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012810#endif
12811
Victor Stinner9b1f4742016-09-06 16:18:52 -070012812#ifdef HAVE_GETRANDOM_SYSCALL
12813 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12814 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12815#endif
12816
Victor Stinner8c62be82010-05-06 00:08:46 +000012817 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012818}
12819
12820
Martin v. Löwis1a214512008-06-11 05:26:20 +000012821static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012822 PyModuleDef_HEAD_INIT,
12823 MODNAME,
12824 posix__doc__,
12825 -1,
12826 posix_methods,
12827 NULL,
12828 NULL,
12829 NULL,
12830 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012831};
12832
12833
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012834static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012835
12836#ifdef HAVE_FACCESSAT
12837 "HAVE_FACCESSAT",
12838#endif
12839
12840#ifdef HAVE_FCHDIR
12841 "HAVE_FCHDIR",
12842#endif
12843
12844#ifdef HAVE_FCHMOD
12845 "HAVE_FCHMOD",
12846#endif
12847
12848#ifdef HAVE_FCHMODAT
12849 "HAVE_FCHMODAT",
12850#endif
12851
12852#ifdef HAVE_FCHOWN
12853 "HAVE_FCHOWN",
12854#endif
12855
Larry Hastings00964ed2013-08-12 13:49:30 -040012856#ifdef HAVE_FCHOWNAT
12857 "HAVE_FCHOWNAT",
12858#endif
12859
Larry Hastings9cf065c2012-06-22 16:30:09 -070012860#ifdef HAVE_FEXECVE
12861 "HAVE_FEXECVE",
12862#endif
12863
12864#ifdef HAVE_FDOPENDIR
12865 "HAVE_FDOPENDIR",
12866#endif
12867
Georg Brandl306336b2012-06-24 12:55:33 +020012868#ifdef HAVE_FPATHCONF
12869 "HAVE_FPATHCONF",
12870#endif
12871
Larry Hastings9cf065c2012-06-22 16:30:09 -070012872#ifdef HAVE_FSTATAT
12873 "HAVE_FSTATAT",
12874#endif
12875
12876#ifdef HAVE_FSTATVFS
12877 "HAVE_FSTATVFS",
12878#endif
12879
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012880#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012881 "HAVE_FTRUNCATE",
12882#endif
12883
Larry Hastings9cf065c2012-06-22 16:30:09 -070012884#ifdef HAVE_FUTIMENS
12885 "HAVE_FUTIMENS",
12886#endif
12887
12888#ifdef HAVE_FUTIMES
12889 "HAVE_FUTIMES",
12890#endif
12891
12892#ifdef HAVE_FUTIMESAT
12893 "HAVE_FUTIMESAT",
12894#endif
12895
12896#ifdef HAVE_LINKAT
12897 "HAVE_LINKAT",
12898#endif
12899
12900#ifdef HAVE_LCHFLAGS
12901 "HAVE_LCHFLAGS",
12902#endif
12903
12904#ifdef HAVE_LCHMOD
12905 "HAVE_LCHMOD",
12906#endif
12907
12908#ifdef HAVE_LCHOWN
12909 "HAVE_LCHOWN",
12910#endif
12911
12912#ifdef HAVE_LSTAT
12913 "HAVE_LSTAT",
12914#endif
12915
12916#ifdef HAVE_LUTIMES
12917 "HAVE_LUTIMES",
12918#endif
12919
12920#ifdef HAVE_MKDIRAT
12921 "HAVE_MKDIRAT",
12922#endif
12923
12924#ifdef HAVE_MKFIFOAT
12925 "HAVE_MKFIFOAT",
12926#endif
12927
12928#ifdef HAVE_MKNODAT
12929 "HAVE_MKNODAT",
12930#endif
12931
12932#ifdef HAVE_OPENAT
12933 "HAVE_OPENAT",
12934#endif
12935
12936#ifdef HAVE_READLINKAT
12937 "HAVE_READLINKAT",
12938#endif
12939
12940#ifdef HAVE_RENAMEAT
12941 "HAVE_RENAMEAT",
12942#endif
12943
12944#ifdef HAVE_SYMLINKAT
12945 "HAVE_SYMLINKAT",
12946#endif
12947
12948#ifdef HAVE_UNLINKAT
12949 "HAVE_UNLINKAT",
12950#endif
12951
12952#ifdef HAVE_UTIMENSAT
12953 "HAVE_UTIMENSAT",
12954#endif
12955
12956#ifdef MS_WINDOWS
12957 "MS_WINDOWS",
12958#endif
12959
12960 NULL
12961};
12962
12963
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012964PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012965INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012966{
Victor Stinner8c62be82010-05-06 00:08:46 +000012967 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012968 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012969 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012970
Brian Curtin52173d42010-12-02 18:29:18 +000012971#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012972 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012973#endif
12974
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 m = PyModule_Create(&posixmodule);
12976 if (m == NULL)
12977 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012978
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 /* Initialize environ dictionary */
12980 v = convertenviron();
12981 Py_XINCREF(v);
12982 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12983 return NULL;
12984 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012985
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 if (all_ins(m))
12987 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012988
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 if (setup_confname_tables(m))
12990 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012991
Victor Stinner8c62be82010-05-06 00:08:46 +000012992 Py_INCREF(PyExc_OSError);
12993 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012994
Guido van Rossumb3d39562000-01-31 18:41:26 +000012995#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012996 if (posix_putenv_garbage == NULL)
12997 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012998#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012999
Victor Stinner8c62be82010-05-06 00:08:46 +000013000 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013001#if defined(HAVE_WAITID) && !defined(__APPLE__)
13002 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013003 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13004 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013005#endif
13006
Christian Heimes25827622013-10-12 01:27:08 +020013007 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013008 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13009 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13010 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013011 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13012 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 structseq_new = StatResultType.tp_new;
13014 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013015
Christian Heimes25827622013-10-12 01:27:08 +020013016 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013017 if (PyStructSequence_InitType2(&StatVFSResultType,
13018 &statvfs_result_desc) < 0)
13019 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013020#ifdef NEED_TICKS_PER_SECOND
13021# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013022 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013023# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013024 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013025# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013026 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013027# endif
13028#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013029
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013030#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013031 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013032 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13033 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013034 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013035#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013036
13037 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013038 if (PyStructSequence_InitType2(&TerminalSizeType,
13039 &TerminalSize_desc) < 0)
13040 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013041
13042 /* initialize scandir types */
13043 if (PyType_Ready(&ScandirIteratorType) < 0)
13044 return NULL;
13045 if (PyType_Ready(&DirEntryType) < 0)
13046 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013047 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013048#if defined(HAVE_WAITID) && !defined(__APPLE__)
13049 Py_INCREF((PyObject*) &WaitidResultType);
13050 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13051#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013052 Py_INCREF((PyObject*) &StatResultType);
13053 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13054 Py_INCREF((PyObject*) &StatVFSResultType);
13055 PyModule_AddObject(m, "statvfs_result",
13056 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013057
13058#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013059 Py_INCREF(&SchedParamType);
13060 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013061#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013062
Larry Hastings605a62d2012-06-24 04:33:36 -070013063 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013064 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13065 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013066 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13067
13068 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013069 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13070 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013071 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13072
Thomas Wouters477c8d52006-05-27 19:21:47 +000013073#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013074 /*
13075 * Step 2 of weak-linking support on Mac OS X.
13076 *
13077 * The code below removes functions that are not available on the
13078 * currently active platform.
13079 *
13080 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013081 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013082 * OSX 10.4.
13083 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013084#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013085 if (fstatvfs == NULL) {
13086 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13087 return NULL;
13088 }
13089 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013090#endif /* HAVE_FSTATVFS */
13091
13092#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013093 if (statvfs == NULL) {
13094 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13095 return NULL;
13096 }
13097 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013098#endif /* HAVE_STATVFS */
13099
13100# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013101 if (lchown == NULL) {
13102 if (PyObject_DelAttrString(m, "lchown") == -1) {
13103 return NULL;
13104 }
13105 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013106#endif /* HAVE_LCHOWN */
13107
13108
13109#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013110
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013111 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013112 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13113
Larry Hastings6fe20b32012-04-19 15:07:49 -070013114 billion = PyLong_FromLong(1000000000);
13115 if (!billion)
13116 return NULL;
13117
Larry Hastings9cf065c2012-06-22 16:30:09 -070013118 /* suppress "function not used" warnings */
13119 {
13120 int ignored;
13121 fd_specified("", -1);
13122 follow_symlinks_specified("", 1);
13123 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13124 dir_fd_converter(Py_None, &ignored);
13125 dir_fd_unavailable(Py_None, &ignored);
13126 }
13127
13128 /*
13129 * provide list of locally available functions
13130 * so os.py can populate support_* lists
13131 */
13132 list = PyList_New(0);
13133 if (!list)
13134 return NULL;
13135 for (trace = have_functions; *trace; trace++) {
13136 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13137 if (!unicode)
13138 return NULL;
13139 if (PyList_Append(list, unicode))
13140 return NULL;
13141 Py_DECREF(unicode);
13142 }
13143 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013144
13145 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013146 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013147
13148 initialized = 1;
13149
Victor Stinner8c62be82010-05-06 00:08:46 +000013150 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013151}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013152
13153#ifdef __cplusplus
13154}
13155#endif