blob: 0f12f4d737bb652f7fc71a2ca8f6a062d719f8a6 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020035/* On android API level 21, 'AT_EACCESS' is not declared although
36 * HAVE_FACCESSAT is defined. */
37#ifdef __ANDROID__
38#undef HAVE_FACCESSAT
39#endif
40
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000041#include <stdio.h> /* needed for ctermid() */
42
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#ifdef __cplusplus
44extern "C" {
45#endif
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000048"This module provides access to operating system functionality that is\n\
49standardized by the C Standard and the POSIX standard (a thinly\n\
50disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000053
Ross Lagerwall4d076da2011-03-18 06:56:53 +020054#ifdef HAVE_SYS_UIO_H
55#include <sys/uio.h>
56#endif
57
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000059#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060#endif /* HAVE_SYS_TYPES_H */
61
62#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000065
Guido van Rossum36bc6801995-06-14 22:54:23 +000066#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000067#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000068#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000071#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000073
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#ifdef HAVE_FCNTL_H
75#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000076#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Guido van Rossuma6535fd2001-10-18 19:44:10 +000078#ifdef HAVE_GRP_H
79#include <grp.h>
80#endif
81
Barry Warsaw5676bd12003-01-07 20:57:09 +000082#ifdef HAVE_SYSEXITS_H
83#include <sysexits.h>
84#endif /* HAVE_SYSEXITS_H */
85
Anthony Baxter8a560de2004-10-13 15:30:56 +000086#ifdef HAVE_SYS_LOADAVG_H
87#include <sys/loadavg.h>
88#endif
89
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000090#ifdef HAVE_LANGINFO_H
91#include <langinfo.h>
92#endif
93
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000094#ifdef HAVE_SYS_SENDFILE_H
95#include <sys/sendfile.h>
96#endif
97
Benjamin Peterson94b580d2011-08-02 17:30:04 -050098#ifdef HAVE_SCHED_H
99#include <sched.h>
100#endif
101
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500102#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500103#undef HAVE_SCHED_SETAFFINITY
104#endif
105
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200106#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400107#define USE_XATTRS
108#endif
109
110#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400111#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400112#endif
113
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
115#ifdef HAVE_SYS_SOCKET_H
116#include <sys/socket.h>
117#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#endif
119
Victor Stinner8b905bd2011-10-25 13:34:04 +0200120#ifdef HAVE_DLFCN_H
121#include <dlfcn.h>
122#endif
123
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200124#ifdef __hpux
125#include <sys/mpctl.h>
126#endif
127
128#if defined(__DragonFly__) || \
129 defined(__OpenBSD__) || \
130 defined(__FreeBSD__) || \
131 defined(__NetBSD__) || \
132 defined(__APPLE__)
133#include <sys/sysctl.h>
134#endif
135
Victor Stinner9b1f4742016-09-06 16:18:52 -0700136#ifdef HAVE_LINUX_RANDOM_H
137# include <linux/random.h>
138#endif
139#ifdef HAVE_GETRANDOM_SYSCALL
140# include <sys/syscall.h>
141#endif
142
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100143#if defined(MS_WINDOWS)
144# define TERMSIZE_USE_CONIO
145#elif defined(HAVE_SYS_IOCTL_H)
146# include <sys/ioctl.h>
147# if defined(HAVE_TERMIOS_H)
148# include <termios.h>
149# endif
150# if defined(TIOCGWINSZ)
151# define TERMSIZE_USE_IOCTL
152# endif
153#endif /* MS_WINDOWS */
154
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000156/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#include <process.h>
161#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000163#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000164#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700167#define HAVE_WSPAWNV 1
168#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#define HAVE_SYSTEM 1
171#define HAVE_CWAIT 1
172#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000173#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000174#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175/* Unix functions that the configure script doesn't check for */
176#define HAVE_EXECV 1
177#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000179#define HAVE_FORK1 1
180#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_GETEGID 1
182#define HAVE_GETEUID 1
183#define HAVE_GETGID 1
184#define HAVE_GETPPID 1
185#define HAVE_GETUID 1
186#define HAVE_KILL 1
187#define HAVE_OPENDIR 1
188#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000189#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000193#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000194
Victor Stinnera2f7c002012-02-08 03:36:25 +0100195
Larry Hastings61272b72014-01-07 12:41:53 -0800196/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000197# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800198module os
Larry Hastings61272b72014-01-07 12:41:53 -0800199[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000200/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100201
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000204#if defined(__sgi)&&_COMPILER_VERSION>=700
205/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
206 (default) */
207extern char *ctermid_r(char *);
208#endif
209
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000210#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000214#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#endif
220#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chdir(char *);
222extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int chdir(const char *);
225extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000228/*#ifdef HAVE_FCHMOD
229extern int fchmod(int, mode_t);
230#endif*/
231/*#ifdef HAVE_LCHMOD
232extern int lchmod(const char *, mode_t);
233#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chown(const char *, uid_t, gid_t);
235extern char *getcwd(char *, int);
236extern char *strerror(int);
237extern int link(const char *, const char *);
238extern int rename(const char *, const char *);
239extern int stat(const char *, struct stat *);
240extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000243#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_UTIME_H
252#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000255#ifdef HAVE_SYS_UTIME_H
256#include <sys/utime.h>
257#define HAVE_UTIME_H /* pretend we do for the rest of this file */
258#endif /* HAVE_SYS_UTIME_H */
259
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#ifdef HAVE_SYS_TIMES_H
261#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef HAVE_SYS_PARAM_H
265#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
268#ifdef HAVE_SYS_UTSNAME_H
269#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#define NAMLEN(dirent) strlen((dirent)->d_name)
275#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000276#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#include <direct.h>
278#define NAMLEN(dirent) strlen((dirent)->d_name)
279#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000294#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
301#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100313#ifndef IO_REPARSE_TAG_MOUNT_POINT
314#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000317#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000319#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000320#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000321#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
322#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000323static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000324#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000325#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#if defined(PATH_MAX) && PATH_MAX > 1024
329#define MAXPATHLEN PATH_MAX
330#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000332#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000333#endif /* MAXPATHLEN */
334
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000335#ifdef UNION_WAIT
336/* Emulate some macros on systems that have a union instead of macros */
337
338#ifndef WIFEXITED
339#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
340#endif
341
342#ifndef WEXITSTATUS
343#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
344#endif
345
346#ifndef WTERMSIG
347#define WTERMSIG(u_wait) ((u_wait).w_termsig)
348#endif
349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350#define WAIT_TYPE union wait
351#define WAIT_STATUS_INT(s) (s.w_status)
352
353#else /* !UNION_WAIT */
354#define WAIT_TYPE int
355#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000356#endif /* UNION_WAIT */
357
Greg Wardb48bc172000-03-01 21:51:56 +0000358/* Don't use the "_r" form if we don't need it (also, won't have a
359 prototype for it, at least on Solaris -- maybe others as well?). */
360#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
361#define USE_CTERMID_R
362#endif
363
Fred Drake699f3522000-06-29 21:12:41 +0000364/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000365#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000366#undef FSTAT
367#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200368#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700370# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200371# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800372# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000373#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000376# define FSTAT fstat
377# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000378#endif
379
Tim Peters11b23062003-04-23 02:39:17 +0000380#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#include <sys/mkdev.h>
382#else
383#if defined(MAJOR_IN_SYSMACROS)
384#include <sys/sysmacros.h>
385#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000386#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
387#include <sys/mkdev.h>
388#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000389#endif
Fred Drake699f3522000-06-29 21:12:41 +0000390
Victor Stinner6edddfa2013-11-24 19:22:57 +0100391#define DWORD_MAX 4294967295U
392
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200393#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100394#define INITFUNC PyInit_nt
395#define MODNAME "nt"
396#else
397#define INITFUNC PyInit_posix
398#define MODNAME "posix"
399#endif
400
401#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200402/* defined in fileutils.c */
403PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
404PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
405 ULONG, struct _Py_stat_struct *);
406#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700407
408#ifdef MS_WINDOWS
409static int
410win32_warn_bytes_api()
411{
412 return PyErr_WarnEx(PyExc_DeprecationWarning,
413 "The Windows bytes API has been deprecated, "
414 "use Unicode filenames instead",
415 1);
416}
417#endif
418
419
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200420#ifndef MS_WINDOWS
421PyObject *
422_PyLong_FromUid(uid_t uid)
423{
424 if (uid == (uid_t)-1)
425 return PyLong_FromLong(-1);
426 return PyLong_FromUnsignedLong(uid);
427}
428
429PyObject *
430_PyLong_FromGid(gid_t gid)
431{
432 if (gid == (gid_t)-1)
433 return PyLong_FromLong(-1);
434 return PyLong_FromUnsignedLong(gid);
435}
436
437int
438_Py_Uid_Converter(PyObject *obj, void *p)
439{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700440 uid_t uid;
441 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200442 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200443 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700444 unsigned long uresult;
445
446 index = PyNumber_Index(obj);
447 if (index == NULL) {
448 PyErr_Format(PyExc_TypeError,
449 "uid should be integer, not %.200s",
450 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200451 return 0;
452 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700453
454 /*
455 * Handling uid_t is complicated for two reasons:
456 * * Although uid_t is (always?) unsigned, it still
457 * accepts -1.
458 * * We don't know its size in advance--it may be
459 * bigger than an int, or it may be smaller than
460 * a long.
461 *
462 * So a bit of defensive programming is in order.
463 * Start with interpreting the value passed
464 * in as a signed long and see if it works.
465 */
466
467 result = PyLong_AsLongAndOverflow(index, &overflow);
468
469 if (!overflow) {
470 uid = (uid_t)result;
471
472 if (result == -1) {
473 if (PyErr_Occurred())
474 goto fail;
475 /* It's a legitimate -1, we're done. */
476 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200477 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700478
479 /* Any other negative number is disallowed. */
480 if (result < 0)
481 goto underflow;
482
483 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200484 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700485 (long)uid != result)
486 goto underflow;
487 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200488 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700489
490 if (overflow < 0)
491 goto underflow;
492
493 /*
494 * Okay, the value overflowed a signed long. If it
495 * fits in an *unsigned* long, it may still be okay,
496 * as uid_t may be unsigned long on this platform.
497 */
498 uresult = PyLong_AsUnsignedLong(index);
499 if (PyErr_Occurred()) {
500 if (PyErr_ExceptionMatches(PyExc_OverflowError))
501 goto overflow;
502 goto fail;
503 }
504
505 uid = (uid_t)uresult;
506
507 /*
508 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
509 * but this value would get interpreted as (uid_t)-1 by chown
510 * and its siblings. That's not what the user meant! So we
511 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100512 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 */
514 if (uid == (uid_t)-1)
515 goto overflow;
516
517 /* Ensure the value wasn't truncated. */
518 if (sizeof(uid_t) < sizeof(long) &&
519 (unsigned long)uid != uresult)
520 goto overflow;
521 /* fallthrough */
522
523success:
524 Py_DECREF(index);
525 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 return 1;
527
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200529 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 "uid is less than minimum");
531 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200534 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 "uid is greater than maximum");
536 /* fallthrough */
537
538fail:
539 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200540 return 0;
541}
542
543int
544_Py_Gid_Converter(PyObject *obj, void *p)
545{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700546 gid_t gid;
547 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200548 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200549 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700550 unsigned long uresult;
551
552 index = PyNumber_Index(obj);
553 if (index == NULL) {
554 PyErr_Format(PyExc_TypeError,
555 "gid should be integer, not %.200s",
556 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200557 return 0;
558 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700559
560 /*
561 * Handling gid_t is complicated for two reasons:
562 * * Although gid_t is (always?) unsigned, it still
563 * accepts -1.
564 * * We don't know its size in advance--it may be
565 * bigger than an int, or it may be smaller than
566 * a long.
567 *
568 * So a bit of defensive programming is in order.
569 * Start with interpreting the value passed
570 * in as a signed long and see if it works.
571 */
572
573 result = PyLong_AsLongAndOverflow(index, &overflow);
574
575 if (!overflow) {
576 gid = (gid_t)result;
577
578 if (result == -1) {
579 if (PyErr_Occurred())
580 goto fail;
581 /* It's a legitimate -1, we're done. */
582 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200583 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700584
585 /* Any other negative number is disallowed. */
586 if (result < 0) {
587 goto underflow;
588 }
589
590 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592 (long)gid != result)
593 goto underflow;
594 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200595 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700596
597 if (overflow < 0)
598 goto underflow;
599
600 /*
601 * Okay, the value overflowed a signed long. If it
602 * fits in an *unsigned* long, it may still be okay,
603 * as gid_t may be unsigned long on this platform.
604 */
605 uresult = PyLong_AsUnsignedLong(index);
606 if (PyErr_Occurred()) {
607 if (PyErr_ExceptionMatches(PyExc_OverflowError))
608 goto overflow;
609 goto fail;
610 }
611
612 gid = (gid_t)uresult;
613
614 /*
615 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
616 * but this value would get interpreted as (gid_t)-1 by chown
617 * and its siblings. That's not what the user meant! So we
618 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100619 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 */
621 if (gid == (gid_t)-1)
622 goto overflow;
623
624 /* Ensure the value wasn't truncated. */
625 if (sizeof(gid_t) < sizeof(long) &&
626 (unsigned long)gid != uresult)
627 goto overflow;
628 /* fallthrough */
629
630success:
631 Py_DECREF(index);
632 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200633 return 1;
634
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 "gid is less than minimum");
638 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642 "gid is greater than maximum");
643 /* fallthrough */
644
645fail:
646 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200647 return 0;
648}
649#endif /* MS_WINDOWS */
650
651
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700652#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800653
654
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200655#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
656static int
657_Py_Dev_Converter(PyObject *obj, void *p)
658{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200659 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200660 if (PyErr_Occurred())
661 return 0;
662 return 1;
663}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800664#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200665
666
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400668/*
669 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
670 * without the int cast, the value gets interpreted as uint (4291925331),
671 * which doesn't play nicely with all the initializer lines in this file that
672 * look like this:
673 * int dir_fd = DEFAULT_DIR_FD;
674 */
675#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700676#else
677#define DEFAULT_DIR_FD (-100)
678#endif
679
680static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300681_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200682{
683 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684 long long_value;
685
686 PyObject *index = PyNumber_Index(o);
687 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 return 0;
689 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300691 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 long_value = PyLong_AsLongAndOverflow(index, &overflow);
693 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300694 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200695 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700696 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 return 0;
699 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200700 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700702 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700703 return 0;
704 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700705
Larry Hastings9cf065c2012-06-22 16:30:09 -0700706 *p = (int)long_value;
707 return 1;
708}
709
710static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200711dir_fd_converter(PyObject *o, void *p)
712{
713 if (o == Py_None) {
714 *(int *)p = DEFAULT_DIR_FD;
715 return 1;
716 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300717 else if (PyIndex_Check(o)) {
718 return _fd_converter(o, (int *)p);
719 }
720 else {
721 PyErr_Format(PyExc_TypeError,
722 "argument should be integer or None, not %.200s",
723 Py_TYPE(o)->tp_name);
724 return 0;
725 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700726}
727
728
Larry Hastings9cf065c2012-06-22 16:30:09 -0700729/*
730 * A PyArg_ParseTuple "converter" function
731 * that handles filesystem paths in the manner
732 * preferred by the os module.
733 *
734 * path_converter accepts (Unicode) strings and their
735 * subclasses, and bytes and their subclasses. What
736 * it does with the argument depends on the platform:
737 *
738 * * On Windows, if we get a (Unicode) string we
739 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700740 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700741 *
742 * * On all other platforms, strings are encoded
743 * to bytes using PyUnicode_FSConverter, then we
744 * extract the char * from the bytes object and
745 * return that.
746 *
747 * path_converter also optionally accepts signed
748 * integers (representing open file descriptors) instead
749 * of path strings.
750 *
751 * Input fields:
752 * path.nullable
753 * If nonzero, the path is permitted to be None.
754 * path.allow_fd
755 * If nonzero, the path is permitted to be a file handle
756 * (a signed int) instead of a string.
757 * path.function_name
758 * If non-NULL, path_converter will use that as the name
759 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700760 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761 * path.argument_name
762 * If non-NULL, path_converter will use that as the name
763 * of the parameter in error messages.
764 * (If path.argument_name is NULL it uses "path".)
765 *
766 * Output fields:
767 * path.wide
768 * Points to the path if it was expressed as Unicode
769 * and was not encoded. (Only used on Windows.)
770 * path.narrow
771 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700772 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000773 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700774 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700775 * path.fd
776 * Contains a file descriptor if path.accept_fd was true
777 * and the caller provided a signed integer instead of any
778 * sort of string.
779 *
780 * WARNING: if your "path" parameter is optional, and is
781 * unspecified, path_converter will never get called.
782 * So if you set allow_fd, you *MUST* initialize path.fd = -1
783 * yourself!
784 * path.length
785 * The length of the path in characters, if specified as
786 * a string.
787 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800788 * The original object passed in (if get a PathLike object,
789 * the result of PyOS_FSPath() is treated as the original object).
790 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700791 * path.cleanup
792 * For internal use only. May point to a temporary object.
793 * (Pay no attention to the man behind the curtain.)
794 *
795 * At most one of path.wide or path.narrow will be non-NULL.
796 * If path was None and path.nullable was set,
797 * or if path was an integer and path.allow_fd was set,
798 * both path.wide and path.narrow will be NULL
799 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200800 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700801 * path_converter takes care to not write to the path_t
802 * unless it's successful. However it must reset the
803 * "cleanup" field each time it's called.
804 *
805 * Use as follows:
806 * path_t path;
807 * memset(&path, 0, sizeof(path));
808 * PyArg_ParseTuple(args, "O&", path_converter, &path);
809 * // ... use values from path ...
810 * path_cleanup(&path);
811 *
812 * (Note that if PyArg_Parse fails you don't need to call
813 * path_cleanup(). However it is safe to do so.)
814 */
815typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100816 const char *function_name;
817 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700818 int nullable;
819 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300820 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700821#ifdef MS_WINDOWS
822 BOOL narrow;
823#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300824 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700825#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700826 int fd;
827 Py_ssize_t length;
828 PyObject *object;
829 PyObject *cleanup;
830} path_t;
831
Steve Dowercc16be82016-09-08 10:35:16 -0700832#ifdef MS_WINDOWS
833#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
834 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
835#else
Larry Hastings2f936352014-08-05 14:04:04 +1000836#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
837 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700838#endif
Larry Hastings31826802013-10-19 00:09:25 -0700839
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800841path_cleanup(path_t *path)
842{
843 Py_CLEAR(path->object);
844 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700845}
846
847static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300848path_converter(PyObject *o, void *p)
849{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700850 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800851 PyObject *bytes = NULL;
852 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700853 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300854 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700855#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800856 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700857 const wchar_t *wide;
858#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859
860#define FORMAT_EXCEPTION(exc, fmt) \
861 PyErr_Format(exc, "%s%s" fmt, \
862 path->function_name ? path->function_name : "", \
863 path->function_name ? ": " : "", \
864 path->argument_name ? path->argument_name : "path")
865
866 /* Py_CLEANUP_SUPPORTED support */
867 if (o == NULL) {
868 path_cleanup(path);
869 return 1;
870 }
871
Brett Cannon3f9183b2016-08-26 14:44:48 -0700872 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800873 path->object = path->cleanup = NULL;
874 /* path->object owns a reference to the original object */
875 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300877 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700878 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700879#ifdef MS_WINDOWS
880 path->narrow = FALSE;
881#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700883#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700884 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800885 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700886 }
887
Brett Cannon3f9183b2016-08-26 14:44:48 -0700888 /* Only call this here so that we don't treat the return value of
889 os.fspath() as an fd or buffer. */
890 is_index = path->allow_fd && PyIndex_Check(o);
891 is_buffer = PyObject_CheckBuffer(o);
892 is_bytes = PyBytes_Check(o);
893 is_unicode = PyUnicode_Check(o);
894
895 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
896 /* Inline PyOS_FSPath() for better error messages. */
897 _Py_IDENTIFIER(__fspath__);
898 PyObject *func = NULL;
899
900 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
901 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800902 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700903 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800904 /* still owns a reference to the original object */
905 Py_DECREF(o);
906 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700907 Py_DECREF(func);
908 if (NULL == o) {
909 goto error_exit;
910 }
911 else if (PyUnicode_Check(o)) {
912 is_unicode = 1;
913 }
914 else if (PyBytes_Check(o)) {
915 is_bytes = 1;
916 }
917 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800918 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700919 }
920 }
921
922 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700923#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +0200924 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100925 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800926 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700927 }
Victor Stinner59799a82013-11-13 14:17:30 +0100928 if (length > 32767) {
929 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +0800930 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300932 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300933 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +0800934 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300935 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700936
937 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +0800938 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800940 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300942 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800943 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300944 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945#endif
946 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700947 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300948 bytes = o;
949 Py_INCREF(bytes);
950 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700951 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300952 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
953 "%s%s%s should be %s, not %.200s",
954 path->function_name ? path->function_name : "",
955 path->function_name ? ": " : "",
956 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700957 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
958 "integer or None" :
959 path->allow_fd ? "string, bytes, os.PathLike or integer" :
960 path->nullable ? "string, bytes, os.PathLike or None" :
961 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300962 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800963 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300964 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300965 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800967 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 }
969 }
Steve Dowercc16be82016-09-08 10:35:16 -0700970 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300971 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800972 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300973 }
974 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700975#ifdef MS_WINDOWS
976 path->narrow = FALSE;
977#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300978 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700979#endif
Xiang Zhang04316c42017-01-08 23:26:57 +0800980 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300981 }
982 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800983 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300984 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
985 path->function_name ? path->function_name : "",
986 path->function_name ? ": " : "",
987 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700988 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
989 "integer or None" :
990 path->allow_fd ? "string, bytes, os.PathLike or integer" :
991 path->nullable ? "string, bytes, os.PathLike or None" :
992 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300993 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +0800994 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 }
996
Larry Hastings9cf065c2012-06-22 16:30:09 -0700997 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700998 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200999 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001000 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001001 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002 }
1003
Steve Dowercc16be82016-09-08 10:35:16 -07001004#ifdef MS_WINDOWS
1005 wo = PyUnicode_DecodeFSDefaultAndSize(
1006 narrow,
1007 length
1008 );
1009 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001011 }
1012
Xiang Zhang04316c42017-01-08 23:26:57 +08001013 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001014 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001015 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001016 }
1017 if (length > 32767) {
1018 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001019 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001020 }
1021 if (wcslen(wide) != length) {
1022 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001023 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001024 }
1025 path->wide = wide;
1026 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001027 path->cleanup = wo;
1028 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001029#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001030 path->wide = NULL;
1031 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001032 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001033 /* Still a reference owned by path->object, don't have to
1034 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001035 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001036 }
1037 else {
1038 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001039 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001040#endif
1041 path->fd = -1;
1042
1043 success_exit:
1044 path->length = length;
1045 path->object = o;
1046 return Py_CLEANUP_SUPPORTED;
1047
1048 error_exit:
1049 Py_XDECREF(o);
1050 Py_XDECREF(bytes);
1051#ifdef MS_WINDOWS
1052 Py_XDECREF(wo);
1053#endif
1054 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055}
1056
1057static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001058argument_unavailable_error(const char *function_name, const char *argument_name)
1059{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001060 PyErr_Format(PyExc_NotImplementedError,
1061 "%s%s%s unavailable on this platform",
1062 (function_name != NULL) ? function_name : "",
1063 (function_name != NULL) ? ": ": "",
1064 argument_name);
1065}
1066
1067static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001068dir_fd_unavailable(PyObject *o, void *p)
1069{
1070 int dir_fd;
1071 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001072 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001073 if (dir_fd != DEFAULT_DIR_FD) {
1074 argument_unavailable_error(NULL, "dir_fd");
1075 return 0;
1076 }
1077 *(int *)p = dir_fd;
1078 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079}
1080
1081static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001082fd_specified(const char *function_name, int fd)
1083{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 if (fd == -1)
1085 return 0;
1086
1087 argument_unavailable_error(function_name, "fd");
1088 return 1;
1089}
1090
1091static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001092follow_symlinks_specified(const char *function_name, int follow_symlinks)
1093{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001094 if (follow_symlinks)
1095 return 0;
1096
1097 argument_unavailable_error(function_name, "follow_symlinks");
1098 return 1;
1099}
1100
1101static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001102path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1103{
Steve Dowercc16be82016-09-08 10:35:16 -07001104 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1105#ifndef MS_WINDOWS
1106 && !path->narrow
1107#endif
1108 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 PyErr_Format(PyExc_ValueError,
1110 "%s: can't specify dir_fd without matching path",
1111 function_name);
1112 return 1;
1113 }
1114 return 0;
1115}
1116
1117static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001118dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1119{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001120 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1121 PyErr_Format(PyExc_ValueError,
1122 "%s: can't specify both dir_fd and fd",
1123 function_name);
1124 return 1;
1125 }
1126 return 0;
1127}
1128
1129static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001130fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1131 int follow_symlinks)
1132{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001133 if ((fd > 0) && (!follow_symlinks)) {
1134 PyErr_Format(PyExc_ValueError,
1135 "%s: cannot use fd and follow_symlinks together",
1136 function_name);
1137 return 1;
1138 }
1139 return 0;
1140}
1141
1142static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001143dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1144 int follow_symlinks)
1145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1147 PyErr_Format(PyExc_ValueError,
1148 "%s: cannot use dir_fd and follow_symlinks together",
1149 function_name);
1150 return 1;
1151 }
1152 return 0;
1153}
1154
Larry Hastings2f936352014-08-05 14:04:04 +10001155#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001156 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001157#else
Larry Hastings2f936352014-08-05 14:04:04 +10001158 typedef off_t Py_off_t;
1159#endif
1160
1161static int
1162Py_off_t_converter(PyObject *arg, void *addr)
1163{
1164#ifdef HAVE_LARGEFILE_SUPPORT
1165 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1166#else
1167 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001168#endif
1169 if (PyErr_Occurred())
1170 return 0;
1171 return 1;
1172}
Larry Hastings2f936352014-08-05 14:04:04 +10001173
1174static PyObject *
1175PyLong_FromPy_off_t(Py_off_t offset)
1176{
1177#ifdef HAVE_LARGEFILE_SUPPORT
1178 return PyLong_FromLongLong(offset);
1179#else
1180 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001181#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001182}
1183
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001184#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001185
1186static int
Brian Curtind25aef52011-06-13 15:16:04 -05001187win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001188{
Martin Panter70214ad2016-08-04 02:38:59 +00001189 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1190 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001191 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001192
1193 if (0 == DeviceIoControl(
1194 reparse_point_handle,
1195 FSCTL_GET_REPARSE_POINT,
1196 NULL, 0, /* in buffer */
1197 target_buffer, sizeof(target_buffer),
1198 &n_bytes_returned,
1199 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001200 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001201
1202 if (reparse_tag)
1203 *reparse_tag = rdb->ReparseTag;
1204
Brian Curtind25aef52011-06-13 15:16:04 -05001205 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001206}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001207
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001208#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001209
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001210/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001211#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001212/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001213** environ directly, we must obtain it with _NSGetEnviron(). See also
1214** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001215*/
1216#include <crt_externs.h>
1217static char **environ;
1218#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001220#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221
Barry Warsaw53699e91996-12-10 23:23:01 +00001222static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001223convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001224{
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001226#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001228#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001229 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001230#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001231
Victor Stinner8c62be82010-05-06 00:08:46 +00001232 d = PyDict_New();
1233 if (d == NULL)
1234 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001235#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001236 if (environ == NULL)
1237 environ = *_NSGetEnviron();
1238#endif
1239#ifdef MS_WINDOWS
1240 /* _wenviron must be initialized in this way if the program is started
1241 through main() instead of wmain(). */
1242 _wgetenv(L"");
1243 if (_wenviron == NULL)
1244 return d;
1245 /* This part ignores errors */
1246 for (e = _wenviron; *e != NULL; e++) {
1247 PyObject *k;
1248 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001249 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001250 if (p == NULL)
1251 continue;
1252 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1253 if (k == NULL) {
1254 PyErr_Clear();
1255 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001256 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001257 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1258 if (v == NULL) {
1259 PyErr_Clear();
1260 Py_DECREF(k);
1261 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001262 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001263 if (PyDict_GetItem(d, k) == NULL) {
1264 if (PyDict_SetItem(d, k, v) != 0)
1265 PyErr_Clear();
1266 }
1267 Py_DECREF(k);
1268 Py_DECREF(v);
1269 }
1270#else
1271 if (environ == NULL)
1272 return d;
1273 /* This part ignores errors */
1274 for (e = environ; *e != NULL; e++) {
1275 PyObject *k;
1276 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001277 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 if (p == NULL)
1279 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001280 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001281 if (k == NULL) {
1282 PyErr_Clear();
1283 continue;
1284 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001285 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001286 if (v == NULL) {
1287 PyErr_Clear();
1288 Py_DECREF(k);
1289 continue;
1290 }
1291 if (PyDict_GetItem(d, k) == NULL) {
1292 if (PyDict_SetItem(d, k, v) != 0)
1293 PyErr_Clear();
1294 }
1295 Py_DECREF(k);
1296 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001297 }
1298#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300}
1301
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302/* Set a POSIX-specific error from errno, and return NULL */
1303
Barry Warsawd58d7641998-07-23 16:14:40 +00001304static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001305posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001306{
Victor Stinner8c62be82010-05-06 00:08:46 +00001307 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308}
Mark Hammondef8b6542001-05-13 08:04:26 +00001309
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001310#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001311static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001312win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001313{
Victor Stinner8c62be82010-05-06 00:08:46 +00001314 /* XXX We should pass the function name along in the future.
1315 (winreg.c also wants to pass the function name.)
1316 This would however require an additional param to the
1317 Windows error object, which is non-trivial.
1318 */
1319 errno = GetLastError();
1320 if (filename)
1321 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1322 else
1323 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001324}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001325
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001326static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001327win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001328{
1329 /* XXX - see win32_error for comments on 'function' */
1330 errno = GetLastError();
1331 if (filename)
1332 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001333 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001334 errno,
1335 filename);
1336 else
1337 return PyErr_SetFromWindowsErr(errno);
1338}
1339
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001340#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341
Larry Hastings9cf065c2012-06-22 16:30:09 -07001342static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001343path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001344{
1345#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001346 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1347 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001348#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001349 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001350#endif
1351}
1352
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001353static PyObject *
1354path_object_error2(PyObject *path, PyObject *path2)
1355{
1356#ifdef MS_WINDOWS
1357 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1358 PyExc_OSError, 0, path, path2);
1359#else
1360 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1361#endif
1362}
1363
1364static PyObject *
1365path_error(path_t *path)
1366{
1367 return path_object_error(path->object);
1368}
Larry Hastings31826802013-10-19 00:09:25 -07001369
Larry Hastingsb0827312014-02-09 22:05:19 -08001370static PyObject *
1371path_error2(path_t *path, path_t *path2)
1372{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001373 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001374}
1375
1376
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377/* POSIX generic methods */
1378
Larry Hastings2f936352014-08-05 14:04:04 +10001379static int
1380fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001381{
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001383 int *pointer = (int *)p;
1384 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001386 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001387 *pointer = fd;
1388 return 1;
1389}
1390
1391static PyObject *
1392posix_fildes_fd(int fd, int (*func)(int))
1393{
1394 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001395 int async_err = 0;
1396
1397 do {
1398 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001399 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001400 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001401 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001402 Py_END_ALLOW_THREADS
1403 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1404 if (res != 0)
1405 return (!async_err) ? posix_error() : NULL;
1406 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001407}
Guido van Rossum21142a01999-01-08 21:05:37 +00001408
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001409
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001410#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411/* This is a reimplementation of the C library's chdir function,
1412 but one that produces Win32 errors instead of DOS error codes.
1413 chdir is essentially a wrapper around SetCurrentDirectory; however,
1414 it also needs to set "magic" environment variables indicating
1415 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001416static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417win32_wchdir(LPCWSTR path)
1418{
Victor Stinnered537822015-12-13 21:40:26 +01001419 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 int result;
1421 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001422
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 if(!SetCurrentDirectoryW(path))
1424 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001425 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 if (!result)
1427 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001428 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001429 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 if (!new_path) {
1431 SetLastError(ERROR_OUTOFMEMORY);
1432 return FALSE;
1433 }
1434 result = GetCurrentDirectoryW(result, new_path);
1435 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001436 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 return FALSE;
1438 }
1439 }
1440 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1441 wcsncmp(new_path, L"//", 2) == 0)
1442 /* UNC path, nothing to do. */
1443 return TRUE;
1444 env[1] = new_path[0];
1445 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001446 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001447 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001449}
1450#endif
1451
Martin v. Löwis14694662006-02-03 12:54:16 +00001452#ifdef MS_WINDOWS
1453/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1454 - time stamps are restricted to second resolution
1455 - file modification times suffer from forth-and-back conversions between
1456 UTC and local time
1457 Therefore, we implement our own stat, based on the Win32 API directly.
1458*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001459#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001460#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001461
Victor Stinner6036e442015-03-08 01:58:04 +01001462static void
Steve Dowercc16be82016-09-08 10:35:16 -07001463find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1464 BY_HANDLE_FILE_INFORMATION *info,
1465 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001466{
1467 memset(info, 0, sizeof(*info));
1468 info->dwFileAttributes = pFileData->dwFileAttributes;
1469 info->ftCreationTime = pFileData->ftCreationTime;
1470 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1471 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1472 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1473 info->nFileSizeLow = pFileData->nFileSizeLow;
1474/* info->nNumberOfLinks = 1; */
1475 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1476 *reparse_tag = pFileData->dwReserved0;
1477 else
1478 *reparse_tag = 0;
1479}
1480
Guido van Rossumd8faa362007-04-27 19:54:29 +00001481static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001482attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001483{
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 HANDLE hFindFile;
1485 WIN32_FIND_DATAW FileData;
1486 hFindFile = FindFirstFileW(pszFile, &FileData);
1487 if (hFindFile == INVALID_HANDLE_VALUE)
1488 return FALSE;
1489 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001490 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001492}
1493
Brian Curtind25aef52011-06-13 15:16:04 -05001494static BOOL
1495get_target_path(HANDLE hdl, wchar_t **target_path)
1496{
1497 int buf_size, result_length;
1498 wchar_t *buf;
1499
1500 /* We have a good handle to the target, use it to determine
1501 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001502 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1503 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001504 if(!buf_size)
1505 return FALSE;
1506
Victor Stinnerc36674a2016-03-16 14:30:16 +01001507 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001508 if (!buf) {
1509 SetLastError(ERROR_OUTOFMEMORY);
1510 return FALSE;
1511 }
1512
Steve Dower2ea51c92015-03-20 21:49:12 -07001513 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001514 buf, buf_size, VOLUME_NAME_DOS);
1515
1516 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001517 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001518 return FALSE;
1519 }
1520
1521 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001522 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001523 return FALSE;
1524 }
1525
1526 buf[result_length] = 0;
1527
1528 *target_path = buf;
1529 return TRUE;
1530}
1531
1532static int
Steve Dowercc16be82016-09-08 10:35:16 -07001533win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001534 BOOL traverse)
1535{
Victor Stinner26de69d2011-06-17 15:15:38 +02001536 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001537 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001539 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001540 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001541 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001542
Steve Dowercc16be82016-09-08 10:35:16 -07001543 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001544 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001545 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001546 0, /* share mode */
1547 NULL, /* security attributes */
1548 OPEN_EXISTING,
1549 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001550 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1551 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001552 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001553 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1554 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001555 NULL);
1556
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001557 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558 /* Either the target doesn't exist, or we don't have access to
1559 get a handle to it. If the former, we need to return an error.
1560 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001561 DWORD lastError = GetLastError();
1562 if (lastError != ERROR_ACCESS_DENIED &&
1563 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001564 return -1;
1565 /* Could not get attributes on open file. Fall back to
1566 reading the directory. */
1567 if (!attributes_from_dir(path, &info, &reparse_tag))
1568 /* Very strange. This should not fail now */
1569 return -1;
1570 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1571 if (traverse) {
1572 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001573 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001574 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001576 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001577 } else {
1578 if (!GetFileInformationByHandle(hFile, &info)) {
1579 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001580 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001581 }
1582 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001583 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1584 return -1;
1585
1586 /* Close the outer open file handle now that we're about to
1587 reopen it with different flags. */
1588 if (!CloseHandle(hFile))
1589 return -1;
1590
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001591 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001592 /* In order to call GetFinalPathNameByHandle we need to open
1593 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001594 hFile2 = CreateFileW(
1595 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1596 NULL, OPEN_EXISTING,
1597 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1598 NULL);
1599 if (hFile2 == INVALID_HANDLE_VALUE)
1600 return -1;
1601
1602 if (!get_target_path(hFile2, &target_path))
1603 return -1;
1604
Steve Dowercc16be82016-09-08 10:35:16 -07001605 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001606 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 return code;
1608 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001609 } else
1610 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001611 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001612 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001613
1614 /* Set S_IEXEC if it is an .exe, .bat, ... */
1615 dot = wcsrchr(path, '.');
1616 if (dot) {
1617 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1618 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1619 result->st_mode |= 0111;
1620 }
1621 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622}
1623
1624static int
Steve Dowercc16be82016-09-08 10:35:16 -07001625win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 /* Protocol violation: we explicitly clear errno, instead of
1628 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001629 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 errno = 0;
1631 return code;
1632}
Brian Curtind25aef52011-06-13 15:16:04 -05001633/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001634
1635 In Posix, stat automatically traverses symlinks and returns the stat
1636 structure for the target. In Windows, the equivalent GetFileAttributes by
1637 default does not traverse symlinks and instead returns attributes for
1638 the symlink.
1639
1640 Therefore, win32_lstat will get the attributes traditionally, and
1641 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001642 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001643
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001644static int
Steve Dowercc16be82016-09-08 10:35:16 -07001645win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001646{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001647 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001648}
1649
Victor Stinner8c62be82010-05-06 00:08:46 +00001650static int
Steve Dowercc16be82016-09-08 10:35:16 -07001651win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001652{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001653 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001654}
1655
Martin v. Löwis14694662006-02-03 12:54:16 +00001656#endif /* MS_WINDOWS */
1657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001659"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001660This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001661 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001662or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1663\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001664Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1665or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001666\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001667See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001668
1669static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001670 {"st_mode", "protection bits"},
1671 {"st_ino", "inode"},
1672 {"st_dev", "device"},
1673 {"st_nlink", "number of hard links"},
1674 {"st_uid", "user ID of owner"},
1675 {"st_gid", "group ID of owner"},
1676 {"st_size", "total size, in bytes"},
1677 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1678 {NULL, "integer time of last access"},
1679 {NULL, "integer time of last modification"},
1680 {NULL, "integer time of last change"},
1681 {"st_atime", "time of last access"},
1682 {"st_mtime", "time of last modification"},
1683 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001684 {"st_atime_ns", "time of last access in nanoseconds"},
1685 {"st_mtime_ns", "time of last modification in nanoseconds"},
1686 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001687#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001689#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001690#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001691 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001692#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001693#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001694 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001695#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001696#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001697 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001698#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001699#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001700 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001701#endif
1702#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001703 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001704#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001705#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1706 {"st_file_attributes", "Windows file attribute bits"},
1707#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001708 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001709};
1710
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001711#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001712#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001713#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001714#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001715#endif
1716
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001717#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001718#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1719#else
1720#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1721#endif
1722
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001723#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001724#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1725#else
1726#define ST_RDEV_IDX ST_BLOCKS_IDX
1727#endif
1728
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001729#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1730#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1731#else
1732#define ST_FLAGS_IDX ST_RDEV_IDX
1733#endif
1734
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001735#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001736#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001737#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001738#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001739#endif
1740
1741#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1742#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1743#else
1744#define ST_BIRTHTIME_IDX ST_GEN_IDX
1745#endif
1746
Zachary Ware63f277b2014-06-19 09:46:37 -05001747#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1748#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1749#else
1750#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1751#endif
1752
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001753static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 "stat_result", /* name */
1755 stat_result__doc__, /* doc */
1756 stat_result_fields,
1757 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001758};
1759
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001760PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001761"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1762This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001763 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001764or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001766See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001767
1768static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001769 {"f_bsize", },
1770 {"f_frsize", },
1771 {"f_blocks", },
1772 {"f_bfree", },
1773 {"f_bavail", },
1774 {"f_files", },
1775 {"f_ffree", },
1776 {"f_favail", },
1777 {"f_flag", },
1778 {"f_namemax",},
1779 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780};
1781
1782static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001783 "statvfs_result", /* name */
1784 statvfs_result__doc__, /* doc */
1785 statvfs_result_fields,
1786 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001787};
1788
Ross Lagerwall7807c352011-03-17 20:20:30 +02001789#if defined(HAVE_WAITID) && !defined(__APPLE__)
1790PyDoc_STRVAR(waitid_result__doc__,
1791"waitid_result: Result from waitid.\n\n\
1792This object may be accessed either as a tuple of\n\
1793 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1794or via the attributes si_pid, si_uid, and so on.\n\
1795\n\
1796See os.waitid for more information.");
1797
1798static PyStructSequence_Field waitid_result_fields[] = {
1799 {"si_pid", },
1800 {"si_uid", },
1801 {"si_signo", },
1802 {"si_status", },
1803 {"si_code", },
1804 {0}
1805};
1806
1807static PyStructSequence_Desc waitid_result_desc = {
1808 "waitid_result", /* name */
1809 waitid_result__doc__, /* doc */
1810 waitid_result_fields,
1811 5
1812};
1813static PyTypeObject WaitidResultType;
1814#endif
1815
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001816static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001817static PyTypeObject StatResultType;
1818static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001819#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001820static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001821#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001822static newfunc structseq_new;
1823
1824static PyObject *
1825statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1826{
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 PyStructSequence *result;
1828 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001829
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 result = (PyStructSequence*)structseq_new(type, args, kwds);
1831 if (!result)
1832 return NULL;
1833 /* If we have been initialized from a tuple,
1834 st_?time might be set to None. Initialize it
1835 from the int slots. */
1836 for (i = 7; i <= 9; i++) {
1837 if (result->ob_item[i+3] == Py_None) {
1838 Py_DECREF(Py_None);
1839 Py_INCREF(result->ob_item[i]);
1840 result->ob_item[i+3] = result->ob_item[i];
1841 }
1842 }
1843 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001844}
1845
1846
1847
1848/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001849static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001850
1851PyDoc_STRVAR(stat_float_times__doc__,
1852"stat_float_times([newval]) -> oldval\n\n\
1853Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001854\n\
1855If value is True, future calls to stat() return floats; if it is False,\n\
1856future calls return ints.\n\
1857If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001858
Larry Hastings2f936352014-08-05 14:04:04 +10001859/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001860static PyObject*
1861stat_float_times(PyObject* self, PyObject *args)
1862{
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 int newval = -1;
1864 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1865 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001866 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1867 "stat_float_times() is deprecated",
1868 1))
1869 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001870 if (newval == -1)
1871 /* Return old value */
1872 return PyBool_FromLong(_stat_float_times);
1873 _stat_float_times = newval;
1874 Py_INCREF(Py_None);
1875 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001876}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001877
Larry Hastings6fe20b32012-04-19 15:07:49 -07001878static PyObject *billion = NULL;
1879
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001880static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001881fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001882{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001883 PyObject *s = _PyLong_FromTime_t(sec);
1884 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1885 PyObject *s_in_ns = NULL;
1886 PyObject *ns_total = NULL;
1887 PyObject *float_s = NULL;
1888
1889 if (!(s && ns_fractional))
1890 goto exit;
1891
1892 s_in_ns = PyNumber_Multiply(s, billion);
1893 if (!s_in_ns)
1894 goto exit;
1895
1896 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1897 if (!ns_total)
1898 goto exit;
1899
Victor Stinner4195b5c2012-02-08 23:03:19 +01001900 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001901 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1902 if (!float_s)
1903 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001904 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001905 else {
1906 float_s = s;
1907 Py_INCREF(float_s);
1908 }
1909
1910 PyStructSequence_SET_ITEM(v, index, s);
1911 PyStructSequence_SET_ITEM(v, index+3, float_s);
1912 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1913 s = NULL;
1914 float_s = NULL;
1915 ns_total = NULL;
1916exit:
1917 Py_XDECREF(s);
1918 Py_XDECREF(ns_fractional);
1919 Py_XDECREF(s_in_ns);
1920 Py_XDECREF(ns_total);
1921 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001922}
1923
Tim Peters5aa91602002-01-30 05:46:57 +00001924/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001925 (used by posix_stat() and posix_fstat()) */
1926static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001927_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001928{
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 unsigned long ansec, mnsec, cnsec;
1930 PyObject *v = PyStructSequence_New(&StatResultType);
1931 if (v == NULL)
1932 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001935#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001936 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001937 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001938#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001939 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001940#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001941#ifdef MS_WINDOWS
1942 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001943#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001944 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001945#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001947#if defined(MS_WINDOWS)
1948 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1949 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1950#else
1951 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1952 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1953#endif
Fred Drake699f3522000-06-29 21:12:41 +00001954#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001956 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001957#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001959#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001960
Martin v. Löwis14694662006-02-03 12:54:16 +00001961#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 ansec = st->st_atim.tv_nsec;
1963 mnsec = st->st_mtim.tv_nsec;
1964 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001965#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 ansec = st->st_atimespec.tv_nsec;
1967 mnsec = st->st_mtimespec.tv_nsec;
1968 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001969#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 ansec = st->st_atime_nsec;
1971 mnsec = st->st_mtime_nsec;
1972 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001973#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001976 fill_time(v, 7, st->st_atime, ansec);
1977 fill_time(v, 8, st->st_mtime, mnsec);
1978 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001979
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001980#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001981 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1982 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001983#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001984#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1986 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001987#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001988#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1990 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001991#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001992#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001993 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1994 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001995#endif
1996#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001998 PyObject *val;
1999 unsigned long bsec,bnsec;
2000 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002001#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002002 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002003#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002004 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002005#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002006 if (_stat_float_times) {
2007 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2008 } else {
2009 val = PyLong_FromLong((long)bsec);
2010 }
2011 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2012 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002014#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002015#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2017 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002018#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002019#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2020 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2021 PyLong_FromUnsignedLong(st->st_file_attributes));
2022#endif
Fred Drake699f3522000-06-29 21:12:41 +00002023
Victor Stinner8c62be82010-05-06 00:08:46 +00002024 if (PyErr_Occurred()) {
2025 Py_DECREF(v);
2026 return NULL;
2027 }
Fred Drake699f3522000-06-29 21:12:41 +00002028
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002030}
2031
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002032/* POSIX methods */
2033
Guido van Rossum94f6f721999-01-06 18:42:14 +00002034
2035static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002036posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002037 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002038{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002039 STRUCT_STAT st;
2040 int result;
2041
2042#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2043 if (follow_symlinks_specified(function_name, follow_symlinks))
2044 return NULL;
2045#endif
2046
2047 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2048 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2049 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2050 return NULL;
2051
2052 Py_BEGIN_ALLOW_THREADS
2053 if (path->fd != -1)
2054 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002055#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002056 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002057 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002058 else
Steve Dowercc16be82016-09-08 10:35:16 -07002059 result = win32_lstat(path->wide, &st);
2060#else
2061 else
2062#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002063 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2064 result = LSTAT(path->narrow, &st);
2065 else
Steve Dowercc16be82016-09-08 10:35:16 -07002066#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002067#ifdef HAVE_FSTATAT
2068 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2069 result = fstatat(dir_fd, path->narrow, &st,
2070 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2071 else
Steve Dowercc16be82016-09-08 10:35:16 -07002072#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002073 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002074#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075 Py_END_ALLOW_THREADS
2076
Victor Stinner292c8352012-10-30 02:17:38 +01002077 if (result != 0) {
2078 return path_error(path);
2079 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002080
2081 return _pystat_fromstructstat(&st);
2082}
2083
Larry Hastings2f936352014-08-05 14:04:04 +10002084/*[python input]
2085
2086for s in """
2087
2088FACCESSAT
2089FCHMODAT
2090FCHOWNAT
2091FSTATAT
2092LINKAT
2093MKDIRAT
2094MKFIFOAT
2095MKNODAT
2096OPENAT
2097READLINKAT
2098SYMLINKAT
2099UNLINKAT
2100
2101""".strip().split():
2102 s = s.strip()
2103 print("""
2104#ifdef HAVE_{s}
2105 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002106#else
Larry Hastings2f936352014-08-05 14:04:04 +10002107 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002108#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002109""".rstrip().format(s=s))
2110
2111for s in """
2112
2113FCHDIR
2114FCHMOD
2115FCHOWN
2116FDOPENDIR
2117FEXECVE
2118FPATHCONF
2119FSTATVFS
2120FTRUNCATE
2121
2122""".strip().split():
2123 s = s.strip()
2124 print("""
2125#ifdef HAVE_{s}
2126 #define PATH_HAVE_{s} 1
2127#else
2128 #define PATH_HAVE_{s} 0
2129#endif
2130
2131""".rstrip().format(s=s))
2132[python start generated code]*/
2133
2134#ifdef HAVE_FACCESSAT
2135 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2136#else
2137 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2138#endif
2139
2140#ifdef HAVE_FCHMODAT
2141 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2142#else
2143 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2144#endif
2145
2146#ifdef HAVE_FCHOWNAT
2147 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2148#else
2149 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2150#endif
2151
2152#ifdef HAVE_FSTATAT
2153 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2154#else
2155 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2156#endif
2157
2158#ifdef HAVE_LINKAT
2159 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2160#else
2161 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2162#endif
2163
2164#ifdef HAVE_MKDIRAT
2165 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2166#else
2167 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2168#endif
2169
2170#ifdef HAVE_MKFIFOAT
2171 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2172#else
2173 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2174#endif
2175
2176#ifdef HAVE_MKNODAT
2177 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2178#else
2179 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2180#endif
2181
2182#ifdef HAVE_OPENAT
2183 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2184#else
2185 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2186#endif
2187
2188#ifdef HAVE_READLINKAT
2189 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2190#else
2191 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2192#endif
2193
2194#ifdef HAVE_SYMLINKAT
2195 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_UNLINKAT
2201 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_FCHDIR
2207 #define PATH_HAVE_FCHDIR 1
2208#else
2209 #define PATH_HAVE_FCHDIR 0
2210#endif
2211
2212#ifdef HAVE_FCHMOD
2213 #define PATH_HAVE_FCHMOD 1
2214#else
2215 #define PATH_HAVE_FCHMOD 0
2216#endif
2217
2218#ifdef HAVE_FCHOWN
2219 #define PATH_HAVE_FCHOWN 1
2220#else
2221 #define PATH_HAVE_FCHOWN 0
2222#endif
2223
2224#ifdef HAVE_FDOPENDIR
2225 #define PATH_HAVE_FDOPENDIR 1
2226#else
2227 #define PATH_HAVE_FDOPENDIR 0
2228#endif
2229
2230#ifdef HAVE_FEXECVE
2231 #define PATH_HAVE_FEXECVE 1
2232#else
2233 #define PATH_HAVE_FEXECVE 0
2234#endif
2235
2236#ifdef HAVE_FPATHCONF
2237 #define PATH_HAVE_FPATHCONF 1
2238#else
2239 #define PATH_HAVE_FPATHCONF 0
2240#endif
2241
2242#ifdef HAVE_FSTATVFS
2243 #define PATH_HAVE_FSTATVFS 1
2244#else
2245 #define PATH_HAVE_FSTATVFS 0
2246#endif
2247
2248#ifdef HAVE_FTRUNCATE
2249 #define PATH_HAVE_FTRUNCATE 1
2250#else
2251 #define PATH_HAVE_FTRUNCATE 0
2252#endif
2253/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002254
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002255#ifdef MS_WINDOWS
2256 #undef PATH_HAVE_FTRUNCATE
2257 #define PATH_HAVE_FTRUNCATE 1
2258#endif
Larry Hastings31826802013-10-19 00:09:25 -07002259
Larry Hastings61272b72014-01-07 12:41:53 -08002260/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002261
2262class path_t_converter(CConverter):
2263
2264 type = "path_t"
2265 impl_by_reference = True
2266 parse_by_reference = True
2267
2268 converter = 'path_converter'
2269
2270 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002271 # right now path_t doesn't support default values.
2272 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002273 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002274 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002275
Larry Hastings2f936352014-08-05 14:04:04 +10002276 if self.c_default not in (None, 'Py_None'):
2277 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002278
2279 self.nullable = nullable
2280 self.allow_fd = allow_fd
2281
Larry Hastings7726ac92014-01-31 22:03:12 -08002282 def pre_render(self):
2283 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002284 if isinstance(value, str):
2285 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002286 return str(int(bool(value)))
2287
2288 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002289 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002290 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002291 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002292 strify(self.nullable),
2293 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002294 )
2295
2296 def cleanup(self):
2297 return "path_cleanup(&" + self.name + ");\n"
2298
2299
2300class dir_fd_converter(CConverter):
2301 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002302
Larry Hastings2f936352014-08-05 14:04:04 +10002303 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002304 if self.default in (unspecified, None):
2305 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002306 if isinstance(requires, str):
2307 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2308 else:
2309 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002310
Larry Hastings2f936352014-08-05 14:04:04 +10002311class fildes_converter(CConverter):
2312 type = 'int'
2313 converter = 'fildes_converter'
2314
2315class uid_t_converter(CConverter):
2316 type = "uid_t"
2317 converter = '_Py_Uid_Converter'
2318
2319class gid_t_converter(CConverter):
2320 type = "gid_t"
2321 converter = '_Py_Gid_Converter'
2322
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002323class dev_t_converter(CConverter):
2324 type = 'dev_t'
2325 converter = '_Py_Dev_Converter'
2326
2327class dev_t_return_converter(unsigned_long_return_converter):
2328 type = 'dev_t'
2329 conversion_fn = '_PyLong_FromDev'
2330 unsigned_cast = '(dev_t)'
2331
Larry Hastings2f936352014-08-05 14:04:04 +10002332class FSConverter_converter(CConverter):
2333 type = 'PyObject *'
2334 converter = 'PyUnicode_FSConverter'
2335 def converter_init(self):
2336 if self.default is not unspecified:
2337 fail("FSConverter_converter does not support default values")
2338 self.c_default = 'NULL'
2339
2340 def cleanup(self):
2341 return "Py_XDECREF(" + self.name + ");\n"
2342
2343class pid_t_converter(CConverter):
2344 type = 'pid_t'
2345 format_unit = '" _Py_PARSE_PID "'
2346
2347class idtype_t_converter(int_converter):
2348 type = 'idtype_t'
2349
2350class id_t_converter(CConverter):
2351 type = 'id_t'
2352 format_unit = '" _Py_PARSE_PID "'
2353
Benjamin Petersonca470632016-09-06 13:47:26 -07002354class intptr_t_converter(CConverter):
2355 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002356 format_unit = '" _Py_PARSE_INTPTR "'
2357
2358class Py_off_t_converter(CConverter):
2359 type = 'Py_off_t'
2360 converter = 'Py_off_t_converter'
2361
2362class Py_off_t_return_converter(long_return_converter):
2363 type = 'Py_off_t'
2364 conversion_fn = 'PyLong_FromPy_off_t'
2365
2366class path_confname_converter(CConverter):
2367 type="int"
2368 converter="conv_path_confname"
2369
2370class confstr_confname_converter(path_confname_converter):
2371 converter='conv_confstr_confname'
2372
2373class sysconf_confname_converter(path_confname_converter):
2374 converter="conv_sysconf_confname"
2375
2376class sched_param_converter(CConverter):
2377 type = 'struct sched_param'
2378 converter = 'convert_sched_param'
2379 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002380
Larry Hastings61272b72014-01-07 12:41:53 -08002381[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002382/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002383
Larry Hastings61272b72014-01-07 12:41:53 -08002384/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002385
Larry Hastings2a727912014-01-16 11:32:01 -08002386os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002387
2388 path : path_t(allow_fd=True)
2389 Path to be examined; can be string, bytes, or open-file-descriptor int.
2390
2391 *
2392
Larry Hastings2f936352014-08-05 14:04:04 +10002393 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002394 If not None, it should be a file descriptor open to a directory,
2395 and path should be a relative string; path will then be relative to
2396 that directory.
2397
2398 follow_symlinks: bool = True
2399 If False, and the last element of the path is a symbolic link,
2400 stat will examine the symbolic link itself instead of the file
2401 the link points to.
2402
2403Perform a stat system call on the given path.
2404
2405dir_fd and follow_symlinks may not be implemented
2406 on your platform. If they are unavailable, using them will raise a
2407 NotImplementedError.
2408
2409It's an error to use dir_fd or follow_symlinks when specifying path as
2410 an open file descriptor.
2411
Larry Hastings61272b72014-01-07 12:41:53 -08002412[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002413
Larry Hastings31826802013-10-19 00:09:25 -07002414static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002415os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2416/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002417{
2418 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2419}
2420
Larry Hastings2f936352014-08-05 14:04:04 +10002421
2422/*[clinic input]
2423os.lstat
2424
2425 path : path_t
2426
2427 *
2428
2429 dir_fd : dir_fd(requires='fstatat') = None
2430
2431Perform a stat system call on the given path, without following symbolic links.
2432
2433Like stat(), but do not follow symbolic links.
2434Equivalent to stat(path, follow_symlinks=False).
2435[clinic start generated code]*/
2436
Larry Hastings2f936352014-08-05 14:04:04 +10002437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002438os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2439/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002440{
2441 int follow_symlinks = 0;
2442 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2443}
Larry Hastings31826802013-10-19 00:09:25 -07002444
Larry Hastings2f936352014-08-05 14:04:04 +10002445
Larry Hastings61272b72014-01-07 12:41:53 -08002446/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002447os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002448
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002449 path: path_t
2450 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002451
2452 mode: int
2453 Operating-system mode bitfield. Can be F_OK to test existence,
2454 or the inclusive-OR of R_OK, W_OK, and X_OK.
2455
2456 *
2457
Larry Hastings2f936352014-08-05 14:04:04 +10002458 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002459 If not None, it should be a file descriptor open to a directory,
2460 and path should be relative; path will then be relative to that
2461 directory.
2462
2463 effective_ids: bool = False
2464 If True, access will use the effective uid/gid instead of
2465 the real uid/gid.
2466
2467 follow_symlinks: bool = True
2468 If False, and the last element of the path is a symbolic link,
2469 access will examine the symbolic link itself instead of the file
2470 the link points to.
2471
2472Use the real uid/gid to test for access to a path.
2473
2474{parameters}
2475dir_fd, effective_ids, and follow_symlinks may not be implemented
2476 on your platform. If they are unavailable, using them will raise a
2477 NotImplementedError.
2478
2479Note that most operations will use the effective uid/gid, therefore this
2480 routine can be used in a suid/sgid environment to test if the invoking user
2481 has the specified access to the path.
2482
Larry Hastings61272b72014-01-07 12:41:53 -08002483[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002484
Larry Hastings2f936352014-08-05 14:04:04 +10002485static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002486os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002487 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002488/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002489{
Larry Hastings2f936352014-08-05 14:04:04 +10002490 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002491
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002492#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002493 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002494#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002495 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002496#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002497
Larry Hastings9cf065c2012-06-22 16:30:09 -07002498#ifndef HAVE_FACCESSAT
2499 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002500 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002501
2502 if (effective_ids) {
2503 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002504 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002505 }
2506#endif
2507
2508#ifdef MS_WINDOWS
2509 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002510 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002511 Py_END_ALLOW_THREADS
2512
2513 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002514 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002515 * * we didn't get a -1, and
2516 * * write access wasn't requested,
2517 * * or the file isn't read-only,
2518 * * or it's a directory.
2519 * (Directories cannot be read-only on Windows.)
2520 */
Larry Hastings2f936352014-08-05 14:04:04 +10002521 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002522 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002523 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002524 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002525#else
2526
2527 Py_BEGIN_ALLOW_THREADS
2528#ifdef HAVE_FACCESSAT
2529 if ((dir_fd != DEFAULT_DIR_FD) ||
2530 effective_ids ||
2531 !follow_symlinks) {
2532 int flags = 0;
2533 if (!follow_symlinks)
2534 flags |= AT_SYMLINK_NOFOLLOW;
2535 if (effective_ids)
2536 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002537 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002538 }
2539 else
2540#endif
Larry Hastings31826802013-10-19 00:09:25 -07002541 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002543 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544#endif
2545
Larry Hastings9cf065c2012-06-22 16:30:09 -07002546 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002547}
2548
Guido van Rossumd371ff11999-01-25 16:12:23 +00002549#ifndef F_OK
2550#define F_OK 0
2551#endif
2552#ifndef R_OK
2553#define R_OK 4
2554#endif
2555#ifndef W_OK
2556#define W_OK 2
2557#endif
2558#ifndef X_OK
2559#define X_OK 1
2560#endif
2561
Larry Hastings31826802013-10-19 00:09:25 -07002562
Guido van Rossumd371ff11999-01-25 16:12:23 +00002563#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002564/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002565os.ttyname -> DecodeFSDefault
2566
2567 fd: int
2568 Integer file descriptor handle.
2569
2570 /
2571
2572Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002573[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002574
Larry Hastings31826802013-10-19 00:09:25 -07002575static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002576os_ttyname_impl(PyObject *module, int fd)
2577/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002578{
2579 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002580
Larry Hastings31826802013-10-19 00:09:25 -07002581 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002582 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002583 posix_error();
2584 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002585}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002586#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002587
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002588#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002589/*[clinic input]
2590os.ctermid
2591
2592Return the name of the controlling terminal for this process.
2593[clinic start generated code]*/
2594
Larry Hastings2f936352014-08-05 14:04:04 +10002595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002596os_ctermid_impl(PyObject *module)
2597/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002598{
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 char *ret;
2600 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002601
Greg Wardb48bc172000-03-01 21:51:56 +00002602#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002604#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002605 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002606#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002607 if (ret == NULL)
2608 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002609 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002610}
Larry Hastings2f936352014-08-05 14:04:04 +10002611#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002612
Larry Hastings2f936352014-08-05 14:04:04 +10002613
2614/*[clinic input]
2615os.chdir
2616
2617 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2618
2619Change the current working directory to the specified path.
2620
2621path may always be specified as a string.
2622On some platforms, path may also be specified as an open file descriptor.
2623 If this functionality is unavailable, using it raises an exception.
2624[clinic start generated code]*/
2625
Larry Hastings2f936352014-08-05 14:04:04 +10002626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002627os_chdir_impl(PyObject *module, path_t *path)
2628/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002629{
2630 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002631
2632 Py_BEGIN_ALLOW_THREADS
2633#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002634 /* on unix, success = 0, on windows, success = !0 */
2635 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002636#else
2637#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002638 if (path->fd != -1)
2639 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002640 else
2641#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002642 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643#endif
2644 Py_END_ALLOW_THREADS
2645
2646 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002647 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648 }
2649
Larry Hastings2f936352014-08-05 14:04:04 +10002650 Py_RETURN_NONE;
2651}
2652
2653
2654#ifdef HAVE_FCHDIR
2655/*[clinic input]
2656os.fchdir
2657
2658 fd: fildes
2659
2660Change to the directory of the given file descriptor.
2661
2662fd must be opened on a directory, not a file.
2663Equivalent to os.chdir(fd).
2664
2665[clinic start generated code]*/
2666
Fred Drake4d1e64b2002-04-15 19:40:07 +00002667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002668os_fchdir_impl(PyObject *module, int fd)
2669/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002670{
Larry Hastings2f936352014-08-05 14:04:04 +10002671 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002672}
2673#endif /* HAVE_FCHDIR */
2674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Larry Hastings2f936352014-08-05 14:04:04 +10002676/*[clinic input]
2677os.chmod
2678
2679 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2680 Path to be modified. May always be specified as a str or bytes.
2681 On some platforms, path may also be specified as an open file descriptor.
2682 If this functionality is unavailable, using it raises an exception.
2683
2684 mode: int
2685 Operating-system mode bitfield.
2686
2687 *
2688
2689 dir_fd : dir_fd(requires='fchmodat') = None
2690 If not None, it should be a file descriptor open to a directory,
2691 and path should be relative; path will then be relative to that
2692 directory.
2693
2694 follow_symlinks: bool = True
2695 If False, and the last element of the path is a symbolic link,
2696 chmod will modify the symbolic link itself instead of the file
2697 the link points to.
2698
2699Change the access permissions of a file.
2700
2701It is an error to use dir_fd or follow_symlinks when specifying path as
2702 an open file descriptor.
2703dir_fd and follow_symlinks may not be implemented on your platform.
2704 If they are unavailable, using them will raise a NotImplementedError.
2705
2706[clinic start generated code]*/
2707
Larry Hastings2f936352014-08-05 14:04:04 +10002708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002709os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002710 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002711/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002712{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002713 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002714
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002715#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002716 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002718
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719#ifdef HAVE_FCHMODAT
2720 int fchmodat_nofollow_unsupported = 0;
2721#endif
2722
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2724 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002725 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726#endif
2727
2728#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002729 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002730 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002731 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002732 result = 0;
2733 else {
2734 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002735 attr &= ~FILE_ATTRIBUTE_READONLY;
2736 else
2737 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002738 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002739 }
2740 Py_END_ALLOW_THREADS
2741
2742 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002743 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002744 }
2745#else /* MS_WINDOWS */
2746 Py_BEGIN_ALLOW_THREADS
2747#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002748 if (path->fd != -1)
2749 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002750 else
2751#endif
2752#ifdef HAVE_LCHMOD
2753 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002754 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002755 else
2756#endif
2757#ifdef HAVE_FCHMODAT
2758 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2759 /*
2760 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2761 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002762 * and then says it isn't implemented yet.
2763 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002764 *
2765 * Once it is supported, os.chmod will automatically
2766 * support dir_fd and follow_symlinks=False. (Hopefully.)
2767 * Until then, we need to be careful what exception we raise.
2768 */
Larry Hastings2f936352014-08-05 14:04:04 +10002769 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002770 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2771 /*
2772 * But wait! We can't throw the exception without allowing threads,
2773 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2774 */
2775 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002776 result &&
2777 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2778 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002779 }
2780 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002781#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002782 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002783 Py_END_ALLOW_THREADS
2784
2785 if (result) {
2786#ifdef HAVE_FCHMODAT
2787 if (fchmodat_nofollow_unsupported) {
2788 if (dir_fd != DEFAULT_DIR_FD)
2789 dir_fd_and_follow_symlinks_invalid("chmod",
2790 dir_fd, follow_symlinks);
2791 else
2792 follow_symlinks_specified("chmod", follow_symlinks);
2793 }
2794 else
2795#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002796 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797 }
2798#endif
2799
Larry Hastings2f936352014-08-05 14:04:04 +10002800 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002801}
2802
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803
Christian Heimes4e30a842007-11-30 22:12:06 +00002804#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002805/*[clinic input]
2806os.fchmod
2807
2808 fd: int
2809 mode: int
2810
2811Change the access permissions of the file given by file descriptor fd.
2812
2813Equivalent to os.chmod(fd, mode).
2814[clinic start generated code]*/
2815
Larry Hastings2f936352014-08-05 14:04:04 +10002816static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002817os_fchmod_impl(PyObject *module, int fd, int mode)
2818/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002819{
2820 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002821 int async_err = 0;
2822
2823 do {
2824 Py_BEGIN_ALLOW_THREADS
2825 res = fchmod(fd, mode);
2826 Py_END_ALLOW_THREADS
2827 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2828 if (res != 0)
2829 return (!async_err) ? posix_error() : NULL;
2830
Victor Stinner8c62be82010-05-06 00:08:46 +00002831 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002832}
2833#endif /* HAVE_FCHMOD */
2834
Larry Hastings2f936352014-08-05 14:04:04 +10002835
Christian Heimes4e30a842007-11-30 22:12:06 +00002836#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002837/*[clinic input]
2838os.lchmod
2839
2840 path: path_t
2841 mode: int
2842
2843Change the access permissions of a file, without following symbolic links.
2844
2845If path is a symlink, this affects the link itself rather than the target.
2846Equivalent to chmod(path, mode, follow_symlinks=False)."
2847[clinic start generated code]*/
2848
Larry Hastings2f936352014-08-05 14:04:04 +10002849static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002850os_lchmod_impl(PyObject *module, path_t *path, int mode)
2851/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002852{
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002854 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002855 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002856 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002857 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002858 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002859 return NULL;
2860 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002862}
2863#endif /* HAVE_LCHMOD */
2864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002865
Thomas Wouterscf297e42007-02-23 15:07:44 +00002866#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002867/*[clinic input]
2868os.chflags
2869
2870 path: path_t
2871 flags: unsigned_long(bitwise=True)
2872 follow_symlinks: bool=True
2873
2874Set file flags.
2875
2876If follow_symlinks is False, and the last element of the path is a symbolic
2877 link, chflags will change flags on the symbolic link itself instead of the
2878 file the link points to.
2879follow_symlinks may not be implemented on your platform. If it is
2880unavailable, using it will raise a NotImplementedError.
2881
2882[clinic start generated code]*/
2883
Larry Hastings2f936352014-08-05 14:04:04 +10002884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002885os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002886 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002887/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002888{
2889 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890
2891#ifndef HAVE_LCHFLAGS
2892 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002893 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002894#endif
2895
Victor Stinner8c62be82010-05-06 00:08:46 +00002896 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897#ifdef HAVE_LCHFLAGS
2898 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002899 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900 else
2901#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002902 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002904
Larry Hastings2f936352014-08-05 14:04:04 +10002905 if (result)
2906 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002907
Larry Hastings2f936352014-08-05 14:04:04 +10002908 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002909}
2910#endif /* HAVE_CHFLAGS */
2911
Larry Hastings2f936352014-08-05 14:04:04 +10002912
Thomas Wouterscf297e42007-02-23 15:07:44 +00002913#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002914/*[clinic input]
2915os.lchflags
2916
2917 path: path_t
2918 flags: unsigned_long(bitwise=True)
2919
2920Set file flags.
2921
2922This function will not follow symbolic links.
2923Equivalent to chflags(path, flags, follow_symlinks=False).
2924[clinic start generated code]*/
2925
Larry Hastings2f936352014-08-05 14:04:04 +10002926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002927os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2928/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002929{
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002931 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002932 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002934 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002935 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002936 }
Victor Stinner292c8352012-10-30 02:17:38 +01002937 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002938}
2939#endif /* HAVE_LCHFLAGS */
2940
Larry Hastings2f936352014-08-05 14:04:04 +10002941
Martin v. Löwis244edc82001-10-04 22:44:26 +00002942#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002943/*[clinic input]
2944os.chroot
2945 path: path_t
2946
2947Change root directory to path.
2948
2949[clinic start generated code]*/
2950
Larry Hastings2f936352014-08-05 14:04:04 +10002951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002952os_chroot_impl(PyObject *module, path_t *path)
2953/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002954{
2955 int res;
2956 Py_BEGIN_ALLOW_THREADS
2957 res = chroot(path->narrow);
2958 Py_END_ALLOW_THREADS
2959 if (res < 0)
2960 return path_error(path);
2961 Py_RETURN_NONE;
2962}
2963#endif /* HAVE_CHROOT */
2964
Martin v. Löwis244edc82001-10-04 22:44:26 +00002965
Guido van Rossum21142a01999-01-08 21:05:37 +00002966#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002967/*[clinic input]
2968os.fsync
2969
2970 fd: fildes
2971
2972Force write of fd to disk.
2973[clinic start generated code]*/
2974
Larry Hastings2f936352014-08-05 14:04:04 +10002975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002976os_fsync_impl(PyObject *module, int fd)
2977/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002978{
2979 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002980}
2981#endif /* HAVE_FSYNC */
2982
Larry Hastings2f936352014-08-05 14:04:04 +10002983
Ross Lagerwall7807c352011-03-17 20:20:30 +02002984#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002985/*[clinic input]
2986os.sync
2987
2988Force write of everything to disk.
2989[clinic start generated code]*/
2990
Larry Hastings2f936352014-08-05 14:04:04 +10002991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002992os_sync_impl(PyObject *module)
2993/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002994{
2995 Py_BEGIN_ALLOW_THREADS
2996 sync();
2997 Py_END_ALLOW_THREADS
2998 Py_RETURN_NONE;
2999}
Larry Hastings2f936352014-08-05 14:04:04 +10003000#endif /* HAVE_SYNC */
3001
Ross Lagerwall7807c352011-03-17 20:20:30 +02003002
Guido van Rossum21142a01999-01-08 21:05:37 +00003003#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003004#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003005extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3006#endif
3007
Larry Hastings2f936352014-08-05 14:04:04 +10003008/*[clinic input]
3009os.fdatasync
3010
3011 fd: fildes
3012
3013Force write of fd to disk without forcing update of metadata.
3014[clinic start generated code]*/
3015
Larry Hastings2f936352014-08-05 14:04:04 +10003016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003017os_fdatasync_impl(PyObject *module, int fd)
3018/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003019{
3020 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003021}
3022#endif /* HAVE_FDATASYNC */
3023
3024
Fredrik Lundh10723342000-07-10 16:38:09 +00003025#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003026/*[clinic input]
3027os.chown
3028
3029 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3030 Path to be examined; can be string, bytes, or open-file-descriptor int.
3031
3032 uid: uid_t
3033
3034 gid: gid_t
3035
3036 *
3037
3038 dir_fd : dir_fd(requires='fchownat') = None
3039 If not None, it should be a file descriptor open to a directory,
3040 and path should be relative; path will then be relative to that
3041 directory.
3042
3043 follow_symlinks: bool = True
3044 If False, and the last element of the path is a symbolic link,
3045 stat will examine the symbolic link itself instead of the file
3046 the link points to.
3047
3048Change the owner and group id of path to the numeric uid and gid.\
3049
3050path may always be specified as a string.
3051On some platforms, path may also be specified as an open file descriptor.
3052 If this functionality is unavailable, using it raises an exception.
3053If dir_fd is not None, it should be a file descriptor open to a directory,
3054 and path should be relative; path will then be relative to that directory.
3055If follow_symlinks is False, and the last element of the path is a symbolic
3056 link, chown will modify the symbolic link itself instead of the file the
3057 link points to.
3058It is an error to use dir_fd or follow_symlinks when specifying path as
3059 an open file descriptor.
3060dir_fd and follow_symlinks may not be implemented on your platform.
3061 If they are unavailable, using them will raise a NotImplementedError.
3062
3063[clinic start generated code]*/
3064
Larry Hastings2f936352014-08-05 14:04:04 +10003065static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003066os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003067 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003068/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003069{
3070 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003071
3072#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3073 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003074 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003075#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003076 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3077 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3078 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003079
3080#ifdef __APPLE__
3081 /*
3082 * This is for Mac OS X 10.3, which doesn't have lchown.
3083 * (But we still have an lchown symbol because of weak-linking.)
3084 * It doesn't have fchownat either. So there's no possibility
3085 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003086 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087 if ((!follow_symlinks) && (lchown == NULL)) {
3088 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003089 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090 }
3091#endif
3092
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003094#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003095 if (path->fd != -1)
3096 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097 else
3098#endif
3099#ifdef HAVE_LCHOWN
3100 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003101 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003102 else
3103#endif
3104#ifdef HAVE_FCHOWNAT
3105 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003106 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003107 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3108 else
3109#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003110 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003111 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003112
Larry Hastings2f936352014-08-05 14:04:04 +10003113 if (result)
3114 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003115
Larry Hastings2f936352014-08-05 14:04:04 +10003116 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003117}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003118#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119
Larry Hastings2f936352014-08-05 14:04:04 +10003120
Christian Heimes4e30a842007-11-30 22:12:06 +00003121#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003122/*[clinic input]
3123os.fchown
3124
3125 fd: int
3126 uid: uid_t
3127 gid: gid_t
3128
3129Change the owner and group id of the file specified by file descriptor.
3130
3131Equivalent to os.chown(fd, uid, gid).
3132
3133[clinic start generated code]*/
3134
Larry Hastings2f936352014-08-05 14:04:04 +10003135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003136os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3137/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003138{
Victor Stinner8c62be82010-05-06 00:08:46 +00003139 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003140 int async_err = 0;
3141
3142 do {
3143 Py_BEGIN_ALLOW_THREADS
3144 res = fchown(fd, uid, gid);
3145 Py_END_ALLOW_THREADS
3146 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3147 if (res != 0)
3148 return (!async_err) ? posix_error() : NULL;
3149
Victor Stinner8c62be82010-05-06 00:08:46 +00003150 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003151}
3152#endif /* HAVE_FCHOWN */
3153
Larry Hastings2f936352014-08-05 14:04:04 +10003154
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003155#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003156/*[clinic input]
3157os.lchown
3158
3159 path : path_t
3160 uid: uid_t
3161 gid: gid_t
3162
3163Change the owner and group id of path to the numeric uid and gid.
3164
3165This function will not follow symbolic links.
3166Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3167[clinic start generated code]*/
3168
Larry Hastings2f936352014-08-05 14:04:04 +10003169static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003170os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3171/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003172{
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003175 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003177 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003178 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003179 }
Larry Hastings2f936352014-08-05 14:04:04 +10003180 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003181}
3182#endif /* HAVE_LCHOWN */
3183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003184
Barry Warsaw53699e91996-12-10 23:23:01 +00003185static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003186posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003187{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003188 char *buf, *tmpbuf;
3189 char *cwd;
3190 const size_t chunk = 1024;
3191 size_t buflen = 0;
3192 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003193
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003194#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003196 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 wchar_t *wbuf2 = wbuf;
3198 PyObject *resobj;
3199 DWORD len;
3200 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003201 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 /* If the buffer is large enough, len does not include the
3203 terminating \0. If the buffer is too small, len includes
3204 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003205 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003206 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003207 if (wbuf2)
3208 len = GetCurrentDirectoryW(len, wbuf2);
3209 }
3210 Py_END_ALLOW_THREADS
3211 if (!wbuf2) {
3212 PyErr_NoMemory();
3213 return NULL;
3214 }
3215 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003216 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003217 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003218 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 }
3220 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003221 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003222 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 return resobj;
3224 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003225
3226 if (win32_warn_bytes_api())
3227 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003228#endif
3229
Victor Stinner4403d7d2015-04-25 00:16:10 +02003230 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003231 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003232 do {
3233 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003234#ifdef MS_WINDOWS
3235 if (buflen > INT_MAX) {
3236 PyErr_NoMemory();
3237 break;
3238 }
3239#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003240 tmpbuf = PyMem_RawRealloc(buf, buflen);
3241 if (tmpbuf == NULL)
3242 break;
3243
3244 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003245#ifdef MS_WINDOWS
3246 cwd = getcwd(buf, (int)buflen);
3247#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003248 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003249#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003250 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003252
3253 if (cwd == NULL) {
3254 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003255 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003256 }
3257
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003259 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3260 else
3261 obj = PyUnicode_DecodeFSDefault(buf);
3262 PyMem_RawFree(buf);
3263
3264 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003265}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003266
Larry Hastings2f936352014-08-05 14:04:04 +10003267
3268/*[clinic input]
3269os.getcwd
3270
3271Return a unicode string representing the current working directory.
3272[clinic start generated code]*/
3273
Larry Hastings2f936352014-08-05 14:04:04 +10003274static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003275os_getcwd_impl(PyObject *module)
3276/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003277{
3278 return posix_getcwd(0);
3279}
3280
Larry Hastings2f936352014-08-05 14:04:04 +10003281
3282/*[clinic input]
3283os.getcwdb
3284
3285Return a bytes string representing the current working directory.
3286[clinic start generated code]*/
3287
Larry Hastings2f936352014-08-05 14:04:04 +10003288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003289os_getcwdb_impl(PyObject *module)
3290/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003291{
3292 return posix_getcwd(1);
3293}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003294
Larry Hastings2f936352014-08-05 14:04:04 +10003295
Larry Hastings9cf065c2012-06-22 16:30:09 -07003296#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3297#define HAVE_LINK 1
3298#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003299
Guido van Rossumb6775db1994-08-01 11:34:53 +00003300#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003301/*[clinic input]
3302
3303os.link
3304
3305 src : path_t
3306 dst : path_t
3307 *
3308 src_dir_fd : dir_fd = None
3309 dst_dir_fd : dir_fd = None
3310 follow_symlinks: bool = True
3311
3312Create a hard link to a file.
3313
3314If either src_dir_fd or dst_dir_fd is not None, it should be a file
3315 descriptor open to a directory, and the respective path string (src or dst)
3316 should be relative; the path will then be relative to that directory.
3317If follow_symlinks is False, and the last element of src is a symbolic
3318 link, link will create a link to the symbolic link itself instead of the
3319 file the link points to.
3320src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3321 platform. If they are unavailable, using them will raise a
3322 NotImplementedError.
3323[clinic start generated code]*/
3324
Larry Hastings2f936352014-08-05 14:04:04 +10003325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003326os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003327 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003328/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003329{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003331 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003332#else
3333 int result;
3334#endif
3335
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336#ifndef HAVE_LINKAT
3337 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3338 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003339 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340 }
3341#endif
3342
Steve Dowercc16be82016-09-08 10:35:16 -07003343#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003344 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003345 PyErr_SetString(PyExc_NotImplementedError,
3346 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003347 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348 }
Steve Dowercc16be82016-09-08 10:35:16 -07003349#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003350
Brian Curtin1b9df392010-11-24 20:24:31 +00003351#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003353 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003354 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003355
Larry Hastings2f936352014-08-05 14:04:04 +10003356 if (!result)
3357 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358#else
3359 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003360#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003361 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3362 (dst_dir_fd != DEFAULT_DIR_FD) ||
3363 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003364 result = linkat(src_dir_fd, src->narrow,
3365 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003366 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3367 else
Steve Dowercc16be82016-09-08 10:35:16 -07003368#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003369 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003370 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003371
Larry Hastings2f936352014-08-05 14:04:04 +10003372 if (result)
3373 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003374#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375
Larry Hastings2f936352014-08-05 14:04:04 +10003376 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003377}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378#endif
3379
Brian Curtin1b9df392010-11-24 20:24:31 +00003380
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003381#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003382static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003383_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003384{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 PyObject *v;
3386 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3387 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003388 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003390 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392
Steve Dowercc16be82016-09-08 10:35:16 -07003393 WIN32_FIND_DATAW wFileData;
3394 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003395
Steve Dowercc16be82016-09-08 10:35:16 -07003396 if (!path->wide) { /* Default arg: "." */
3397 po_wchars = L".";
3398 len = 1;
3399 } else {
3400 po_wchars = path->wide;
3401 len = wcslen(path->wide);
3402 }
3403 /* The +5 is so we can append "\\*.*\0" */
3404 wnamebuf = PyMem_New(wchar_t, len + 5);
3405 if (!wnamebuf) {
3406 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 }
Steve Dowercc16be82016-09-08 10:35:16 -07003409 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003411 wchar_t wch = wnamebuf[len-1];
3412 if (wch != SEP && wch != ALTSEP && wch != L':')
3413 wnamebuf[len++] = SEP;
3414 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 }
Steve Dowercc16be82016-09-08 10:35:16 -07003416 if ((list = PyList_New(0)) == NULL) {
3417 goto exit;
3418 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003419 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003420 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003421 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 if (hFindFile == INVALID_HANDLE_VALUE) {
3423 int error = GetLastError();
3424 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 goto exit;
3426 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003427 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 }
3430 do {
3431 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003432 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3433 wcscmp(wFileData.cFileName, L"..") != 0) {
3434 v = PyUnicode_FromWideChar(wFileData.cFileName,
3435 wcslen(wFileData.cFileName));
3436 if (path->narrow && v) {
3437 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3438 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 Py_DECREF(list);
3441 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 break;
3443 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 Py_DECREF(list);
3447 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 break;
3449 }
3450 Py_DECREF(v);
3451 }
3452 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003453 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 Py_END_ALLOW_THREADS
3455 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3456 it got to the end of the directory. */
3457 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003459 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 }
3462 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003463
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464exit:
3465 if (hFindFile != INVALID_HANDLE_VALUE) {
3466 if (FindClose(hFindFile) == FALSE) {
3467 if (list != NULL) {
3468 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003469 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 }
3471 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003473 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003474
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003476} /* end of _listdir_windows_no_opendir */
3477
3478#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3479
3480static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003481_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003482{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003483 PyObject *v;
3484 DIR *dirp = NULL;
3485 struct dirent *ep;
3486 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003487#ifdef HAVE_FDOPENDIR
3488 int fd = -1;
3489#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003490
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003493 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003495 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003496 if (fd == -1)
3497 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498
Larry Hastingsfdaea062012-06-25 04:42:23 -07003499 return_str = 1;
3500
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 Py_BEGIN_ALLOW_THREADS
3502 dirp = fdopendir(fd);
3503 Py_END_ALLOW_THREADS
3504 }
3505 else
3506#endif
3507 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003508 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003509 if (path->narrow) {
3510 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003511 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003512 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003513 }
3514 else {
3515 name = ".";
3516 return_str = 1;
3517 }
3518
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_BEGIN_ALLOW_THREADS
3520 dirp = opendir(name);
3521 Py_END_ALLOW_THREADS
3522 }
3523
3524 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003525 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003526#ifdef HAVE_FDOPENDIR
3527 if (fd != -1) {
3528 Py_BEGIN_ALLOW_THREADS
3529 close(fd);
3530 Py_END_ALLOW_THREADS
3531 }
3532#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 goto exit;
3534 }
3535 if ((list = PyList_New(0)) == NULL) {
3536 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003537 }
3538 for (;;) {
3539 errno = 0;
3540 Py_BEGIN_ALLOW_THREADS
3541 ep = readdir(dirp);
3542 Py_END_ALLOW_THREADS
3543 if (ep == NULL) {
3544 if (errno == 0) {
3545 break;
3546 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003548 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 }
3551 }
3552 if (ep->d_name[0] == '.' &&
3553 (NAMLEN(ep) == 1 ||
3554 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3555 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003556 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003557 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3558 else
3559 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 break;
3563 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 break;
3568 }
3569 Py_DECREF(v);
3570 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003571
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572exit:
3573 if (dirp != NULL) {
3574 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003575#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 if (fd > -1)
3577 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003578#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 closedir(dirp);
3580 Py_END_ALLOW_THREADS
3581 }
3582
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003584} /* end of _posix_listdir */
3585#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003586
Larry Hastings2f936352014-08-05 14:04:04 +10003587
3588/*[clinic input]
3589os.listdir
3590
3591 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3592
3593Return a list containing the names of the files in the directory.
3594
3595path can be specified as either str or bytes. If path is bytes,
3596 the filenames returned will also be bytes; in all other circumstances
3597 the filenames returned will be str.
3598If path is None, uses the path='.'.
3599On some platforms, path may also be specified as an open file descriptor;\
3600 the file descriptor must refer to a directory.
3601 If this functionality is unavailable, using it raises NotImplementedError.
3602
3603The list is in arbitrary order. It does not include the special
3604entries '.' and '..' even if they are present in the directory.
3605
3606
3607[clinic start generated code]*/
3608
Larry Hastings2f936352014-08-05 14:04:04 +10003609static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003610os_listdir_impl(PyObject *module, path_t *path)
3611/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003612{
3613#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3614 return _listdir_windows_no_opendir(path, NULL);
3615#else
3616 return _posix_listdir(path, NULL);
3617#endif
3618}
3619
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003620#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003621/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003622/*[clinic input]
3623os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003624
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003625 path: path_t
3626 /
3627
3628[clinic start generated code]*/
3629
3630static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003631os__getfullpathname_impl(PyObject *module, path_t *path)
3632/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003633{
Steve Dowercc16be82016-09-08 10:35:16 -07003634 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3635 wchar_t *wtemp;
3636 DWORD result;
3637 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003638
Steve Dowercc16be82016-09-08 10:35:16 -07003639 result = GetFullPathNameW(path->wide,
3640 Py_ARRAY_LENGTH(woutbuf),
3641 woutbuf, &wtemp);
3642 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3643 woutbufp = PyMem_New(wchar_t, result);
3644 if (!woutbufp)
3645 return PyErr_NoMemory();
3646 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 }
Steve Dowercc16be82016-09-08 10:35:16 -07003648 if (result) {
3649 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3650 if (path->narrow)
3651 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3652 } else
3653 v = win32_error_object("GetFullPathNameW", path->object);
3654 if (woutbufp != woutbuf)
3655 PyMem_Free(woutbufp);
3656 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003657}
Brian Curtind40e6f72010-07-08 21:39:08 +00003658
Brian Curtind25aef52011-06-13 15:16:04 -05003659
Larry Hastings2f936352014-08-05 14:04:04 +10003660/*[clinic input]
3661os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003662
Larry Hastings2f936352014-08-05 14:04:04 +10003663 path: unicode
3664 /
3665
3666A helper function for samepath on windows.
3667[clinic start generated code]*/
3668
Larry Hastings2f936352014-08-05 14:04:04 +10003669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003670os__getfinalpathname_impl(PyObject *module, PyObject *path)
3671/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003672{
3673 HANDLE hFile;
3674 int buf_size;
3675 wchar_t *target_path;
3676 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003677 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003678 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003679
Larry Hastings2f936352014-08-05 14:04:04 +10003680 path_wchar = PyUnicode_AsUnicode(path);
3681 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003682 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003683
Brian Curtind40e6f72010-07-08 21:39:08 +00003684 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003685 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003686 0, /* desired access */
3687 0, /* share mode */
3688 NULL, /* security attributes */
3689 OPEN_EXISTING,
3690 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3691 FILE_FLAG_BACKUP_SEMANTICS,
3692 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003693
Victor Stinnereb5657a2011-09-30 01:44:27 +02003694 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003695 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003696
3697 /* We have a good handle to the target, use it to determine the
3698 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003699 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003700
3701 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003702 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003703
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003704 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003705 if(!target_path)
3706 return PyErr_NoMemory();
3707
Steve Dower2ea51c92015-03-20 21:49:12 -07003708 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3709 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003710 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003711 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003712
3713 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003714 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003715
3716 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003717 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003718 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003719 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003720}
Brian Curtin62857742010-09-06 17:07:27 +00003721
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003722/*[clinic input]
3723os._isdir
3724
3725 path: path_t
3726 /
3727
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003728Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003729[clinic start generated code]*/
3730
Brian Curtin9c669cc2011-06-08 18:17:18 -05003731static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003732os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003733/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003734{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003735 DWORD attributes;
3736
Steve Dowerb22a6772016-07-17 20:49:38 -07003737 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003738 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003739 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003740
Brian Curtin9c669cc2011-06-08 18:17:18 -05003741 if (attributes == INVALID_FILE_ATTRIBUTES)
3742 Py_RETURN_FALSE;
3743
Brian Curtin9c669cc2011-06-08 18:17:18 -05003744 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3745 Py_RETURN_TRUE;
3746 else
3747 Py_RETURN_FALSE;
3748}
Tim Golden6b528062013-08-01 12:44:00 +01003749
Tim Golden6b528062013-08-01 12:44:00 +01003750
Larry Hastings2f936352014-08-05 14:04:04 +10003751/*[clinic input]
3752os._getvolumepathname
3753
3754 path: unicode
3755
3756A helper function for ismount on Win32.
3757[clinic start generated code]*/
3758
Larry Hastings2f936352014-08-05 14:04:04 +10003759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003760os__getvolumepathname_impl(PyObject *module, PyObject *path)
3761/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003762{
3763 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003764 const wchar_t *path_wchar;
3765 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003766 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003767 BOOL ret;
3768
Larry Hastings2f936352014-08-05 14:04:04 +10003769 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3770 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003771 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003772 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003773
3774 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003775 buflen = Py_MAX(buflen, MAX_PATH);
3776
3777 if (buflen > DWORD_MAX) {
3778 PyErr_SetString(PyExc_OverflowError, "path too long");
3779 return NULL;
3780 }
3781
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003782 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003783 if (mountpath == NULL)
3784 return PyErr_NoMemory();
3785
3786 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003787 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003788 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003789 Py_END_ALLOW_THREADS
3790
3791 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003792 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003793 goto exit;
3794 }
3795 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3796
3797exit:
3798 PyMem_Free(mountpath);
3799 return result;
3800}
Tim Golden6b528062013-08-01 12:44:00 +01003801
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003802#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003803
Larry Hastings2f936352014-08-05 14:04:04 +10003804
3805/*[clinic input]
3806os.mkdir
3807
3808 path : path_t
3809
3810 mode: int = 0o777
3811
3812 *
3813
3814 dir_fd : dir_fd(requires='mkdirat') = None
3815
3816# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3817
3818Create a directory.
3819
3820If dir_fd is not None, it should be a file descriptor open to a directory,
3821 and path should be relative; path will then be relative to that directory.
3822dir_fd may not be implemented on your platform.
3823 If it is unavailable, using it will raise a NotImplementedError.
3824
3825The mode argument is ignored on Windows.
3826[clinic start generated code]*/
3827
Larry Hastings2f936352014-08-05 14:04:04 +10003828static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003829os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3830/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003831{
3832 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003833
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003834#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003835 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003836 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003837 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003838
Larry Hastings2f936352014-08-05 14:04:04 +10003839 if (!result)
3840 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003841#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003842 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003843#if HAVE_MKDIRAT
3844 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003845 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003846 else
3847#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003848#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003849 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003850#else
Larry Hastings2f936352014-08-05 14:04:04 +10003851 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003852#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003854 if (result < 0)
3855 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003856#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003857 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003858}
3859
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003860
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003861/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3862#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003863#include <sys/resource.h>
3864#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003865
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003866
3867#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003868/*[clinic input]
3869os.nice
3870
3871 increment: int
3872 /
3873
3874Add increment to the priority of process and return the new priority.
3875[clinic start generated code]*/
3876
Larry Hastings2f936352014-08-05 14:04:04 +10003877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003878os_nice_impl(PyObject *module, int increment)
3879/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003880{
3881 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003882
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 /* There are two flavours of 'nice': one that returns the new
3884 priority (as required by almost all standards out there) and the
3885 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3886 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003887
Victor Stinner8c62be82010-05-06 00:08:46 +00003888 If we are of the nice family that returns the new priority, we
3889 need to clear errno before the call, and check if errno is filled
3890 before calling posix_error() on a returnvalue of -1, because the
3891 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003892
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 errno = 0;
3894 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003895#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 if (value == 0)
3897 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003898#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003899 if (value == -1 && errno != 0)
3900 /* either nice() or getpriority() returned an error */
3901 return posix_error();
3902 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003903}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003904#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003905
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003906
3907#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003908/*[clinic input]
3909os.getpriority
3910
3911 which: int
3912 who: int
3913
3914Return program scheduling priority.
3915[clinic start generated code]*/
3916
Larry Hastings2f936352014-08-05 14:04:04 +10003917static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003918os_getpriority_impl(PyObject *module, int which, int who)
3919/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003920{
3921 int retval;
3922
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003923 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003924 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003925 if (errno != 0)
3926 return posix_error();
3927 return PyLong_FromLong((long)retval);
3928}
3929#endif /* HAVE_GETPRIORITY */
3930
3931
3932#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003933/*[clinic input]
3934os.setpriority
3935
3936 which: int
3937 who: int
3938 priority: int
3939
3940Set program scheduling priority.
3941[clinic start generated code]*/
3942
Larry Hastings2f936352014-08-05 14:04:04 +10003943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003944os_setpriority_impl(PyObject *module, int which, int who, int priority)
3945/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003946{
3947 int retval;
3948
3949 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003950 if (retval == -1)
3951 return posix_error();
3952 Py_RETURN_NONE;
3953}
3954#endif /* HAVE_SETPRIORITY */
3955
3956
Barry Warsaw53699e91996-12-10 23:23:01 +00003957static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003958internal_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 +00003959{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003960 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003961 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003962
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003963#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003964 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003965 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003966#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003968#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003969
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3971 (dst_dir_fd != DEFAULT_DIR_FD);
3972#ifndef HAVE_RENAMEAT
3973 if (dir_fd_specified) {
3974 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003975 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003976 }
3977#endif
3978
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979#ifdef MS_WINDOWS
3980 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003981 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003982 Py_END_ALLOW_THREADS
3983
Larry Hastings2f936352014-08-05 14:04:04 +10003984 if (!result)
3985 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986
3987#else
Steve Dowercc16be82016-09-08 10:35:16 -07003988 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3989 PyErr_Format(PyExc_ValueError,
3990 "%s: src and dst must be the same type", function_name);
3991 return NULL;
3992 }
3993
Larry Hastings9cf065c2012-06-22 16:30:09 -07003994 Py_BEGIN_ALLOW_THREADS
3995#ifdef HAVE_RENAMEAT
3996 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10003997 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 else
3999#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004000 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001 Py_END_ALLOW_THREADS
4002
Larry Hastings2f936352014-08-05 14:04:04 +10004003 if (result)
4004 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004006 Py_RETURN_NONE;
4007}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004008
Larry Hastings2f936352014-08-05 14:04:04 +10004009
4010/*[clinic input]
4011os.rename
4012
4013 src : path_t
4014 dst : path_t
4015 *
4016 src_dir_fd : dir_fd = None
4017 dst_dir_fd : dir_fd = None
4018
4019Rename a file or directory.
4020
4021If either src_dir_fd or dst_dir_fd is not None, it should be a file
4022 descriptor open to a directory, and the respective path string (src or dst)
4023 should be relative; the path will then be relative to that directory.
4024src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4025 If they are unavailable, using them will raise a NotImplementedError.
4026[clinic start generated code]*/
4027
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004029os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004030 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004031/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004032{
Larry Hastings2f936352014-08-05 14:04:04 +10004033 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004034}
4035
Larry Hastings2f936352014-08-05 14:04:04 +10004036
4037/*[clinic input]
4038os.replace = os.rename
4039
4040Rename a file or directory, overwriting the destination.
4041
4042If either src_dir_fd or dst_dir_fd is not None, it should be a file
4043 descriptor open to a directory, and the respective path string (src or dst)
4044 should be relative; the path will then be relative to that directory.
4045src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4046 If they are unavailable, using them will raise a NotImplementedError."
4047[clinic start generated code]*/
4048
Larry Hastings2f936352014-08-05 14:04:04 +10004049static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004050os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4051 int dst_dir_fd)
4052/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004053{
4054 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4055}
4056
4057
4058/*[clinic input]
4059os.rmdir
4060
4061 path: path_t
4062 *
4063 dir_fd: dir_fd(requires='unlinkat') = None
4064
4065Remove a directory.
4066
4067If dir_fd is not None, it should be a file descriptor open to a directory,
4068 and path should be relative; path will then be relative to that directory.
4069dir_fd may not be implemented on your platform.
4070 If it is unavailable, using it will raise a NotImplementedError.
4071[clinic start generated code]*/
4072
Larry Hastings2f936352014-08-05 14:04:04 +10004073static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004074os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4075/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004076{
4077 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004078
4079 Py_BEGIN_ALLOW_THREADS
4080#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004081 /* Windows, success=1, UNIX, success=0 */
4082 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004083#else
4084#ifdef HAVE_UNLINKAT
4085 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004086 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004087 else
4088#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004089 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004090#endif
4091 Py_END_ALLOW_THREADS
4092
Larry Hastings2f936352014-08-05 14:04:04 +10004093 if (result)
4094 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004095
Larry Hastings2f936352014-08-05 14:04:04 +10004096 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004097}
4098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004099
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004100#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004101#ifdef MS_WINDOWS
4102/*[clinic input]
4103os.system -> long
4104
4105 command: Py_UNICODE
4106
4107Execute the command in a subshell.
4108[clinic start generated code]*/
4109
Larry Hastings2f936352014-08-05 14:04:04 +10004110static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004111os_system_impl(PyObject *module, Py_UNICODE *command)
4112/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004113{
4114 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004115 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004116 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004117 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004118 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004119 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004120 return result;
4121}
4122#else /* MS_WINDOWS */
4123/*[clinic input]
4124os.system -> long
4125
4126 command: FSConverter
4127
4128Execute the command in a subshell.
4129[clinic start generated code]*/
4130
Larry Hastings2f936352014-08-05 14:04:04 +10004131static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004132os_system_impl(PyObject *module, PyObject *command)
4133/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004134{
4135 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004136 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004137 Py_BEGIN_ALLOW_THREADS
4138 result = system(bytes);
4139 Py_END_ALLOW_THREADS
4140 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004141}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004142#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004143#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Larry Hastings2f936352014-08-05 14:04:04 +10004146/*[clinic input]
4147os.umask
4148
4149 mask: int
4150 /
4151
4152Set the current numeric umask and return the previous umask.
4153[clinic start generated code]*/
4154
Larry Hastings2f936352014-08-05 14:04:04 +10004155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004156os_umask_impl(PyObject *module, int mask)
4157/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004158{
4159 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 if (i < 0)
4161 return posix_error();
4162 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004163}
4164
Brian Curtind40e6f72010-07-08 21:39:08 +00004165#ifdef MS_WINDOWS
4166
4167/* override the default DeleteFileW behavior so that directory
4168symlinks can be removed with this function, the same as with
4169Unix symlinks */
4170BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4171{
4172 WIN32_FILE_ATTRIBUTE_DATA info;
4173 WIN32_FIND_DATAW find_data;
4174 HANDLE find_data_handle;
4175 int is_directory = 0;
4176 int is_link = 0;
4177
4178 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4179 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004180
Brian Curtind40e6f72010-07-08 21:39:08 +00004181 /* Get WIN32_FIND_DATA structure for the path to determine if
4182 it is a symlink */
4183 if(is_directory &&
4184 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4185 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4186
4187 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004188 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4189 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4190 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4191 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004192 FindClose(find_data_handle);
4193 }
4194 }
4195 }
4196
4197 if (is_directory && is_link)
4198 return RemoveDirectoryW(lpFileName);
4199
4200 return DeleteFileW(lpFileName);
4201}
4202#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004204
Larry Hastings2f936352014-08-05 14:04:04 +10004205/*[clinic input]
4206os.unlink
4207
4208 path: path_t
4209 *
4210 dir_fd: dir_fd(requires='unlinkat')=None
4211
4212Remove a file (same as remove()).
4213
4214If dir_fd is not None, it should be a file descriptor open to a directory,
4215 and path should be relative; path will then be relative to that directory.
4216dir_fd may not be implemented on your platform.
4217 If it is unavailable, using it will raise a NotImplementedError.
4218
4219[clinic start generated code]*/
4220
Larry Hastings2f936352014-08-05 14:04:04 +10004221static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004222os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4223/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004224{
4225 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004226
4227 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004228 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004229#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004230 /* Windows, success=1, UNIX, success=0 */
4231 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004232#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233#ifdef HAVE_UNLINKAT
4234 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004235 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004236 else
4237#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004239#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004240 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004241 Py_END_ALLOW_THREADS
4242
Larry Hastings2f936352014-08-05 14:04:04 +10004243 if (result)
4244 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004245
Larry Hastings2f936352014-08-05 14:04:04 +10004246 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004247}
4248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004249
Larry Hastings2f936352014-08-05 14:04:04 +10004250/*[clinic input]
4251os.remove = os.unlink
4252
4253Remove a file (same as unlink()).
4254
4255If dir_fd is not None, it should be a file descriptor open to a directory,
4256 and path should be relative; path will then be relative to that directory.
4257dir_fd may not be implemented on your platform.
4258 If it is unavailable, using it will raise a NotImplementedError.
4259[clinic start generated code]*/
4260
Larry Hastings2f936352014-08-05 14:04:04 +10004261static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004262os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4263/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004264{
4265 return os_unlink_impl(module, path, dir_fd);
4266}
4267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Larry Hastings605a62d2012-06-24 04:33:36 -07004269static PyStructSequence_Field uname_result_fields[] = {
4270 {"sysname", "operating system name"},
4271 {"nodename", "name of machine on network (implementation-defined)"},
4272 {"release", "operating system release"},
4273 {"version", "operating system version"},
4274 {"machine", "hardware identifier"},
4275 {NULL}
4276};
4277
4278PyDoc_STRVAR(uname_result__doc__,
4279"uname_result: Result from os.uname().\n\n\
4280This object may be accessed either as a tuple of\n\
4281 (sysname, nodename, release, version, machine),\n\
4282or via the attributes sysname, nodename, release, version, and machine.\n\
4283\n\
4284See os.uname for more information.");
4285
4286static PyStructSequence_Desc uname_result_desc = {
4287 "uname_result", /* name */
4288 uname_result__doc__, /* doc */
4289 uname_result_fields,
4290 5
4291};
4292
4293static PyTypeObject UnameResultType;
4294
4295
4296#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004297/*[clinic input]
4298os.uname
4299
4300Return an object identifying the current operating system.
4301
4302The object behaves like a named tuple with the following fields:
4303 (sysname, nodename, release, version, machine)
4304
4305[clinic start generated code]*/
4306
Larry Hastings2f936352014-08-05 14:04:04 +10004307static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004308os_uname_impl(PyObject *module)
4309/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004310{
Victor Stinner8c62be82010-05-06 00:08:46 +00004311 struct utsname u;
4312 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004313 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004314
Victor Stinner8c62be82010-05-06 00:08:46 +00004315 Py_BEGIN_ALLOW_THREADS
4316 res = uname(&u);
4317 Py_END_ALLOW_THREADS
4318 if (res < 0)
4319 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004320
4321 value = PyStructSequence_New(&UnameResultType);
4322 if (value == NULL)
4323 return NULL;
4324
4325#define SET(i, field) \
4326 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004327 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004328 if (!o) { \
4329 Py_DECREF(value); \
4330 return NULL; \
4331 } \
4332 PyStructSequence_SET_ITEM(value, i, o); \
4333 } \
4334
4335 SET(0, u.sysname);
4336 SET(1, u.nodename);
4337 SET(2, u.release);
4338 SET(3, u.version);
4339 SET(4, u.machine);
4340
4341#undef SET
4342
4343 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004344}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004345#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004346
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004347
Larry Hastings9cf065c2012-06-22 16:30:09 -07004348
4349typedef struct {
4350 int now;
4351 time_t atime_s;
4352 long atime_ns;
4353 time_t mtime_s;
4354 long mtime_ns;
4355} utime_t;
4356
4357/*
Victor Stinner484df002014-10-09 13:52:31 +02004358 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004359 * they also intentionally leak the declaration of a pointer named "time"
4360 */
4361#define UTIME_TO_TIMESPEC \
4362 struct timespec ts[2]; \
4363 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004364 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365 time = NULL; \
4366 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004367 ts[0].tv_sec = ut->atime_s; \
4368 ts[0].tv_nsec = ut->atime_ns; \
4369 ts[1].tv_sec = ut->mtime_s; \
4370 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004371 time = ts; \
4372 } \
4373
4374#define UTIME_TO_TIMEVAL \
4375 struct timeval tv[2]; \
4376 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004377 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004378 time = NULL; \
4379 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004380 tv[0].tv_sec = ut->atime_s; \
4381 tv[0].tv_usec = ut->atime_ns / 1000; \
4382 tv[1].tv_sec = ut->mtime_s; \
4383 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384 time = tv; \
4385 } \
4386
4387#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004388 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004390 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391 time = NULL; \
4392 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004393 u.actime = ut->atime_s; \
4394 u.modtime = ut->mtime_s; \
4395 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396 }
4397
4398#define UTIME_TO_TIME_T \
4399 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004400 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004401 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402 time = NULL; \
4403 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004404 timet[0] = ut->atime_s; \
4405 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004406 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004407 } \
4408
4409
Victor Stinner528a9ab2015-09-03 21:30:26 +02004410#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004411
4412static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004413utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004414{
4415#ifdef HAVE_UTIMENSAT
4416 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4417 UTIME_TO_TIMESPEC;
4418 return utimensat(dir_fd, path, time, flags);
4419#elif defined(HAVE_FUTIMESAT)
4420 UTIME_TO_TIMEVAL;
4421 /*
4422 * follow_symlinks will never be false here;
4423 * we only allow !follow_symlinks and dir_fd together
4424 * if we have utimensat()
4425 */
4426 assert(follow_symlinks);
4427 return futimesat(dir_fd, path, time);
4428#endif
4429}
4430
Larry Hastings2f936352014-08-05 14:04:04 +10004431 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4432#else
4433 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004434#endif
4435
Victor Stinner528a9ab2015-09-03 21:30:26 +02004436#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004437
4438static int
Victor Stinner484df002014-10-09 13:52:31 +02004439utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004440{
4441#ifdef HAVE_FUTIMENS
4442 UTIME_TO_TIMESPEC;
4443 return futimens(fd, time);
4444#else
4445 UTIME_TO_TIMEVAL;
4446 return futimes(fd, time);
4447#endif
4448}
4449
Larry Hastings2f936352014-08-05 14:04:04 +10004450 #define PATH_UTIME_HAVE_FD 1
4451#else
4452 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004453#endif
4454
Victor Stinner5ebae872015-09-22 01:29:33 +02004455#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4456# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4457#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004458
Victor Stinner4552ced2015-09-21 22:37:15 +02004459#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004460
4461static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004462utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463{
4464#ifdef HAVE_UTIMENSAT
4465 UTIME_TO_TIMESPEC;
4466 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4467#else
4468 UTIME_TO_TIMEVAL;
4469 return lutimes(path, time);
4470#endif
4471}
4472
4473#endif
4474
4475#ifndef MS_WINDOWS
4476
4477static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004478utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004479{
4480#ifdef HAVE_UTIMENSAT
4481 UTIME_TO_TIMESPEC;
4482 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4483#elif defined(HAVE_UTIMES)
4484 UTIME_TO_TIMEVAL;
4485 return utimes(path, time);
4486#elif defined(HAVE_UTIME_H)
4487 UTIME_TO_UTIMBUF;
4488 return utime(path, time);
4489#else
4490 UTIME_TO_TIME_T;
4491 return utime(path, time);
4492#endif
4493}
4494
4495#endif
4496
Larry Hastings76ad59b2012-05-03 00:30:07 -07004497static int
4498split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4499{
4500 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004501 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004502 divmod = PyNumber_Divmod(py_long, billion);
4503 if (!divmod)
4504 goto exit;
4505 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4506 if ((*s == -1) && PyErr_Occurred())
4507 goto exit;
4508 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004509 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004510 goto exit;
4511
4512 result = 1;
4513exit:
4514 Py_XDECREF(divmod);
4515 return result;
4516}
4517
Larry Hastings2f936352014-08-05 14:04:04 +10004518
4519/*[clinic input]
4520os.utime
4521
4522 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4523 times: object = NULL
4524 *
4525 ns: object = NULL
4526 dir_fd: dir_fd(requires='futimensat') = None
4527 follow_symlinks: bool=True
4528
Martin Panter0ff89092015-09-09 01:56:53 +00004529# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004530
4531Set the access and modified time of path.
4532
4533path may always be specified as a string.
4534On some platforms, path may also be specified as an open file descriptor.
4535 If this functionality is unavailable, using it raises an exception.
4536
4537If times is not None, it must be a tuple (atime, mtime);
4538 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004539If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004540 atime_ns and mtime_ns should be expressed as integer nanoseconds
4541 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004542If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004543Specifying tuples for both times and ns is an error.
4544
4545If dir_fd is not None, it should be a file descriptor open to a directory,
4546 and path should be relative; path will then be relative to that directory.
4547If follow_symlinks is False, and the last element of the path is a symbolic
4548 link, utime will modify the symbolic link itself instead of the file the
4549 link points to.
4550It is an error to use dir_fd or follow_symlinks when specifying path
4551 as an open file descriptor.
4552dir_fd and follow_symlinks may not be available on your platform.
4553 If they are unavailable, using them will raise a NotImplementedError.
4554
4555[clinic start generated code]*/
4556
Larry Hastings2f936352014-08-05 14:04:04 +10004557static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004558os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4559 int dir_fd, int follow_symlinks)
4560/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004561{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562#ifdef MS_WINDOWS
4563 HANDLE hFile;
4564 FILETIME atime, mtime;
4565#else
4566 int result;
4567#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004568
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004570 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004571
Christian Heimesb3c87242013-08-01 00:08:16 +02004572 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004573
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 if (times && (times != Py_None) && ns) {
4575 PyErr_SetString(PyExc_ValueError,
4576 "utime: you may specify either 'times'"
4577 " or 'ns' but not both");
4578 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004579 }
4580
4581 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004582 time_t a_sec, m_sec;
4583 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004584 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585 PyErr_SetString(PyExc_TypeError,
4586 "utime: 'times' must be either"
4587 " a tuple of two ints or None");
4588 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004589 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004591 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004592 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004593 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004594 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004596 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004597 utime.atime_s = a_sec;
4598 utime.atime_ns = a_nsec;
4599 utime.mtime_s = m_sec;
4600 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004601 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004602 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004603 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004604 PyErr_SetString(PyExc_TypeError,
4605 "utime: 'ns' must be a tuple of two ints");
4606 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004607 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004609 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004611 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612 &utime.mtime_s, &utime.mtime_ns)) {
4613 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004614 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615 }
4616 else {
4617 /* times and ns are both None/unspecified. use "now". */
4618 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004619 }
4620
Victor Stinner4552ced2015-09-21 22:37:15 +02004621#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004622 if (follow_symlinks_specified("utime", follow_symlinks))
4623 goto exit;
4624#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004625
Larry Hastings2f936352014-08-05 14:04:04 +10004626 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4627 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4628 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004630
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631#if !defined(HAVE_UTIMENSAT)
4632 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004633 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634 "utime: cannot use dir_fd and follow_symlinks "
4635 "together on this platform");
4636 goto exit;
4637 }
4638#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004639
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004640#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004642 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4643 NULL, OPEN_EXISTING,
4644 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 Py_END_ALLOW_THREADS
4646 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004647 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004649 }
4650
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004652 GetSystemTimeAsFileTime(&mtime);
4653 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004654 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004655 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004656 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4657 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004658 }
4659 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4660 /* Avoid putting the file name into the error here,
4661 as that may confuse the user into believing that
4662 something is wrong with the file, when it also
4663 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004664 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004666 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004667#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004669
Victor Stinner4552ced2015-09-21 22:37:15 +02004670#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004672 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004674#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675
Victor Stinner528a9ab2015-09-03 21:30:26 +02004676#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004677 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004678 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004679 else
4680#endif
4681
Victor Stinner528a9ab2015-09-03 21:30:26 +02004682#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004683 if (path->fd != -1)
4684 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685 else
4686#endif
4687
Larry Hastings2f936352014-08-05 14:04:04 +10004688 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689
4690 Py_END_ALLOW_THREADS
4691
4692 if (result < 0) {
4693 /* see previous comment about not putting filename in error here */
4694 return_value = posix_error();
4695 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004696 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004698#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699
4700 Py_INCREF(Py_None);
4701 return_value = Py_None;
4702
4703exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004704#ifdef MS_WINDOWS
4705 if (hFile != INVALID_HANDLE_VALUE)
4706 CloseHandle(hFile);
4707#endif
4708 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004709}
4710
Guido van Rossum3b066191991-06-04 19:40:25 +00004711/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004712
Larry Hastings2f936352014-08-05 14:04:04 +10004713
4714/*[clinic input]
4715os._exit
4716
4717 status: int
4718
4719Exit to the system with specified status, without normal exit processing.
4720[clinic start generated code]*/
4721
Larry Hastings2f936352014-08-05 14:04:04 +10004722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004723os__exit_impl(PyObject *module, int status)
4724/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004725{
4726 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004727 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004728}
4729
Steve Dowercc16be82016-09-08 10:35:16 -07004730#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4731#define EXECV_CHAR wchar_t
4732#else
4733#define EXECV_CHAR char
4734#endif
4735
Martin v. Löwis114619e2002-10-07 06:44:21 +00004736#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4737static void
Steve Dowercc16be82016-09-08 10:35:16 -07004738free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004739{
Victor Stinner8c62be82010-05-06 00:08:46 +00004740 Py_ssize_t i;
4741 for (i = 0; i < count; i++)
4742 PyMem_Free(array[i]);
4743 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004744}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004745
Berker Peksag81816462016-09-15 20:19:47 +03004746static int
4747fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004748{
Victor Stinner8c62be82010-05-06 00:08:46 +00004749 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004750 PyObject *ub;
4751 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004752#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004753 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004754 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004755 *out = PyUnicode_AsWideCharString(ub, &size);
4756 if (*out)
4757 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004758#else
Berker Peksag81816462016-09-15 20:19:47 +03004759 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004760 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004761 size = PyBytes_GET_SIZE(ub);
4762 *out = PyMem_Malloc(size + 1);
4763 if (*out) {
4764 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4765 result = 1;
4766 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004767 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004768#endif
Berker Peksag81816462016-09-15 20:19:47 +03004769 Py_DECREF(ub);
4770 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004771}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004772#endif
4773
Ross Lagerwall7807c352011-03-17 20:20:30 +02004774#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004775static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004776parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4777{
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 Py_ssize_t i, pos, envc;
4779 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004780 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004781 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004782
Victor Stinner8c62be82010-05-06 00:08:46 +00004783 i = PyMapping_Size(env);
4784 if (i < 0)
4785 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004786 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004787 if (envlist == NULL) {
4788 PyErr_NoMemory();
4789 return NULL;
4790 }
4791 envc = 0;
4792 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004793 if (!keys)
4794 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004796 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 goto error;
4798 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4799 PyErr_Format(PyExc_TypeError,
4800 "env.keys() or env.values() is not a list");
4801 goto error;
4802 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004803
Victor Stinner8c62be82010-05-06 00:08:46 +00004804 for (pos = 0; pos < i; pos++) {
4805 key = PyList_GetItem(keys, pos);
4806 val = PyList_GetItem(vals, pos);
4807 if (!key || !val)
4808 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004809
Berker Peksag81816462016-09-15 20:19:47 +03004810#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4811 if (!PyUnicode_FSDecoder(key, &key2))
4812 goto error;
4813 if (!PyUnicode_FSDecoder(val, &val2)) {
4814 Py_DECREF(key2);
4815 goto error;
4816 }
4817 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4818#else
4819 if (!PyUnicode_FSConverter(key, &key2))
4820 goto error;
4821 if (!PyUnicode_FSConverter(val, &val2)) {
4822 Py_DECREF(key2);
4823 goto error;
4824 }
4825 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4826 PyBytes_AS_STRING(val2));
4827#endif
4828 Py_DECREF(key2);
4829 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004830 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004832
4833 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4834 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 goto error;
4836 }
Berker Peksag81816462016-09-15 20:19:47 +03004837
Steve Dowercc16be82016-09-08 10:35:16 -07004838 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 }
4840 Py_DECREF(vals);
4841 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004842
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 envlist[envc] = 0;
4844 *envc_ptr = envc;
4845 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004846
4847error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 Py_XDECREF(keys);
4849 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004850 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004852}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004853
Steve Dowercc16be82016-09-08 10:35:16 -07004854static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004855parse_arglist(PyObject* argv, Py_ssize_t *argc)
4856{
4857 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004858 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004859 if (argvlist == NULL) {
4860 PyErr_NoMemory();
4861 return NULL;
4862 }
4863 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004864 PyObject* item = PySequence_ITEM(argv, i);
4865 if (item == NULL)
4866 goto fail;
4867 if (!fsconvert_strdup(item, &argvlist[i])) {
4868 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004869 goto fail;
4870 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004871 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004872 }
4873 argvlist[*argc] = NULL;
4874 return argvlist;
4875fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004876 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004877 free_string_array(argvlist, *argc);
4878 return NULL;
4879}
Steve Dowercc16be82016-09-08 10:35:16 -07004880
Ross Lagerwall7807c352011-03-17 20:20:30 +02004881#endif
4882
Larry Hastings2f936352014-08-05 14:04:04 +10004883
Ross Lagerwall7807c352011-03-17 20:20:30 +02004884#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004885/*[clinic input]
4886os.execv
4887
Steve Dowercc16be82016-09-08 10:35:16 -07004888 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004889 Path of executable file.
4890 argv: object
4891 Tuple or list of strings.
4892 /
4893
4894Execute an executable path with arguments, replacing current process.
4895[clinic start generated code]*/
4896
Larry Hastings2f936352014-08-05 14:04:04 +10004897static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004898os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4899/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004900{
Steve Dowercc16be82016-09-08 10:35:16 -07004901 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004902 Py_ssize_t argc;
4903
4904 /* execv has two arguments: (path, argv), where
4905 argv is a list or tuple of strings. */
4906
Ross Lagerwall7807c352011-03-17 20:20:30 +02004907 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4908 PyErr_SetString(PyExc_TypeError,
4909 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004910 return NULL;
4911 }
4912 argc = PySequence_Size(argv);
4913 if (argc < 1) {
4914 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004915 return NULL;
4916 }
4917
4918 argvlist = parse_arglist(argv, &argc);
4919 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004920 return NULL;
4921 }
Steve Dowerbce26262016-11-19 19:17:26 -08004922 if (!argvlist[0][0]) {
4923 PyErr_SetString(PyExc_ValueError,
4924 "execv() arg 2 first element cannot be empty");
4925 free_string_array(argvlist, argc);
4926 return NULL;
4927 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004928
Steve Dowerbce26262016-11-19 19:17:26 -08004929 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004930#ifdef HAVE_WEXECV
4931 _wexecv(path->wide, argvlist);
4932#else
4933 execv(path->narrow, argvlist);
4934#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004935 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004936
4937 /* If we get here it's definitely an error */
4938
4939 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004940 return posix_error();
4941}
4942
Larry Hastings2f936352014-08-05 14:04:04 +10004943
4944/*[clinic input]
4945os.execve
4946
4947 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4948 Path of executable file.
4949 argv: object
4950 Tuple or list of strings.
4951 env: object
4952 Dictionary of strings mapping to strings.
4953
4954Execute an executable path with arguments, replacing current process.
4955[clinic start generated code]*/
4956
Larry Hastings2f936352014-08-05 14:04:04 +10004957static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004958os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4959/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004960{
Steve Dowercc16be82016-09-08 10:35:16 -07004961 EXECV_CHAR **argvlist = NULL;
4962 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004964
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 /* execve has three arguments: (path, argv, env), where
4966 argv is a list or tuple of strings and env is a dictionary
4967 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004968
Ross Lagerwall7807c352011-03-17 20:20:30 +02004969 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 "execve: argv must be a tuple or list");
4972 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004974 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08004975 if (argc < 1) {
4976 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
4977 return NULL;
4978 }
4979
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 if (!PyMapping_Check(env)) {
4981 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004982 "execve: environment must be a mapping object");
4983 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004985
Ross Lagerwall7807c352011-03-17 20:20:30 +02004986 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004988 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 }
Steve Dowerbce26262016-11-19 19:17:26 -08004990 if (!argvlist[0][0]) {
4991 PyErr_SetString(PyExc_ValueError,
4992 "execve: argv first element cannot be empty");
4993 goto fail;
4994 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004995
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 envlist = parse_envlist(env, &envc);
4997 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004998 goto fail;
4999
Steve Dowerbce26262016-11-19 19:17:26 -08005000 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005001#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005002 if (path->fd > -1)
5003 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005004 else
5005#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005006#ifdef HAVE_WEXECV
5007 _wexecve(path->wide, argvlist, envlist);
5008#else
Larry Hastings2f936352014-08-05 14:04:04 +10005009 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005010#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005011 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005012
5013 /* If we get here it's definitely an error */
5014
Larry Hastings2f936352014-08-05 14:04:04 +10005015 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016
Steve Dowercc16be82016-09-08 10:35:16 -07005017 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005019 if (argvlist)
5020 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005021 return NULL;
5022}
Steve Dowercc16be82016-09-08 10:35:16 -07005023
Larry Hastings9cf065c2012-06-22 16:30:09 -07005024#endif /* HAVE_EXECV */
5025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005026
Steve Dowercc16be82016-09-08 10:35:16 -07005027#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005028/*[clinic input]
5029os.spawnv
5030
5031 mode: int
5032 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005033 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005034 Path of executable file.
5035 argv: object
5036 Tuple or list of strings.
5037 /
5038
5039Execute the program specified by path in a new process.
5040[clinic start generated code]*/
5041
Larry Hastings2f936352014-08-05 14:04:04 +10005042static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005043os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5044/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005045{
Steve Dowercc16be82016-09-08 10:35:16 -07005046 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005047 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005048 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005049 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005051
Victor Stinner8c62be82010-05-06 00:08:46 +00005052 /* spawnv has three arguments: (mode, path, argv), where
5053 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005054
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 if (PyList_Check(argv)) {
5056 argc = PyList_Size(argv);
5057 getitem = PyList_GetItem;
5058 }
5059 else if (PyTuple_Check(argv)) {
5060 argc = PyTuple_Size(argv);
5061 getitem = PyTuple_GetItem;
5062 }
5063 else {
5064 PyErr_SetString(PyExc_TypeError,
5065 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 return NULL;
5067 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005068 if (argc == 0) {
5069 PyErr_SetString(PyExc_ValueError,
5070 "spawnv() arg 2 cannot be empty");
5071 return NULL;
5072 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005073
Steve Dowercc16be82016-09-08 10:35:16 -07005074 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 return PyErr_NoMemory();
5077 }
5078 for (i = 0; i < argc; i++) {
5079 if (!fsconvert_strdup((*getitem)(argv, i),
5080 &argvlist[i])) {
5081 free_string_array(argvlist, i);
5082 PyErr_SetString(
5083 PyExc_TypeError,
5084 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 return NULL;
5086 }
Steve Dower93ff8722016-11-19 19:03:54 -08005087 if (i == 0 && !argvlist[0][0]) {
5088 free_string_array(argvlist, i);
5089 PyErr_SetString(
5090 PyExc_ValueError,
5091 "spawnv() arg 2 first element cannot be empty");
5092 return NULL;
5093 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 }
5095 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005096
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 if (mode == _OLD_P_OVERLAY)
5098 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005099
Victor Stinner8c62be82010-05-06 00:08:46 +00005100 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005101 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005102#ifdef HAVE_WSPAWNV
5103 spawnval = _wspawnv(mode, path->wide, argvlist);
5104#else
5105 spawnval = _spawnv(mode, path->narrow, argvlist);
5106#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005107 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005109
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005111
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 if (spawnval == -1)
5113 return posix_error();
5114 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005115 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005116}
5117
5118
Larry Hastings2f936352014-08-05 14:04:04 +10005119/*[clinic input]
5120os.spawnve
5121
5122 mode: int
5123 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005124 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005125 Path of executable file.
5126 argv: object
5127 Tuple or list of strings.
5128 env: object
5129 Dictionary of strings mapping to strings.
5130 /
5131
5132Execute the program specified by path in a new process.
5133[clinic start generated code]*/
5134
Larry Hastings2f936352014-08-05 14:04:04 +10005135static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005136os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005137 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005138/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005139{
Steve Dowercc16be82016-09-08 10:35:16 -07005140 EXECV_CHAR **argvlist;
5141 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005143 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005144 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5146 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 /* spawnve has four arguments: (mode, path, argv, env), where
5149 argv is a list or tuple of strings and env is a dictionary
5150 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005151
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 if (PyList_Check(argv)) {
5153 argc = PyList_Size(argv);
5154 getitem = PyList_GetItem;
5155 }
5156 else if (PyTuple_Check(argv)) {
5157 argc = PyTuple_Size(argv);
5158 getitem = PyTuple_GetItem;
5159 }
5160 else {
5161 PyErr_SetString(PyExc_TypeError,
5162 "spawnve() arg 2 must be a tuple or list");
5163 goto fail_0;
5164 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005165 if (argc == 0) {
5166 PyErr_SetString(PyExc_ValueError,
5167 "spawnve() arg 2 cannot be empty");
5168 goto fail_0;
5169 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 if (!PyMapping_Check(env)) {
5171 PyErr_SetString(PyExc_TypeError,
5172 "spawnve() arg 3 must be a mapping object");
5173 goto fail_0;
5174 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005175
Steve Dowercc16be82016-09-08 10:35:16 -07005176 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 if (argvlist == NULL) {
5178 PyErr_NoMemory();
5179 goto fail_0;
5180 }
5181 for (i = 0; i < argc; i++) {
5182 if (!fsconvert_strdup((*getitem)(argv, i),
5183 &argvlist[i]))
5184 {
5185 lastarg = i;
5186 goto fail_1;
5187 }
Steve Dowerbce26262016-11-19 19:17:26 -08005188 if (i == 0 && !argvlist[0][0]) {
5189 lastarg = i;
5190 PyErr_SetString(
5191 PyExc_ValueError,
5192 "spawnv() arg 2 first element cannot be empty");
5193 goto fail_1;
5194 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 }
5196 lastarg = argc;
5197 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005198
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 envlist = parse_envlist(env, &envc);
5200 if (envlist == NULL)
5201 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 if (mode == _OLD_P_OVERLAY)
5204 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005207 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005208#ifdef HAVE_WSPAWNV
5209 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5210#else
5211 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5212#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005213 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005215
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 if (spawnval == -1)
5217 (void) posix_error();
5218 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005219 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005220
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 while (--envc >= 0)
5222 PyMem_DEL(envlist[envc]);
5223 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005224 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005226 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005227 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005228}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005229
Guido van Rossuma1065681999-01-25 23:20:23 +00005230#endif /* HAVE_SPAWNV */
5231
5232
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005233#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005234/*[clinic input]
5235os.fork1
5236
5237Fork a child process with a single multiplexed (i.e., not bound) thread.
5238
5239Return 0 to child process and PID of child to parent process.
5240[clinic start generated code]*/
5241
Larry Hastings2f936352014-08-05 14:04:04 +10005242static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005243os_fork1_impl(PyObject *module)
5244/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005245{
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 pid_t pid;
5247 int result = 0;
5248 _PyImport_AcquireLock();
5249 pid = fork1();
5250 if (pid == 0) {
5251 /* child: this clobbers and resets the import lock. */
5252 PyOS_AfterFork();
5253 } else {
5254 /* parent: release the import lock. */
5255 result = _PyImport_ReleaseLock();
5256 }
5257 if (pid == -1)
5258 return posix_error();
5259 if (result < 0) {
5260 /* Don't clobber the OSError if the fork failed. */
5261 PyErr_SetString(PyExc_RuntimeError,
5262 "not holding the import lock");
5263 return NULL;
5264 }
5265 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005266}
Larry Hastings2f936352014-08-05 14:04:04 +10005267#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005268
5269
Guido van Rossumad0ee831995-03-01 10:34:45 +00005270#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005271/*[clinic input]
5272os.fork
5273
5274Fork a child process.
5275
5276Return 0 to child process and PID of child to parent process.
5277[clinic start generated code]*/
5278
Larry Hastings2f936352014-08-05 14:04:04 +10005279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005280os_fork_impl(PyObject *module)
5281/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005282{
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 pid_t pid;
5284 int result = 0;
5285 _PyImport_AcquireLock();
5286 pid = fork();
5287 if (pid == 0) {
5288 /* child: this clobbers and resets the import lock. */
5289 PyOS_AfterFork();
5290 } else {
5291 /* parent: release the import lock. */
5292 result = _PyImport_ReleaseLock();
5293 }
5294 if (pid == -1)
5295 return posix_error();
5296 if (result < 0) {
5297 /* Don't clobber the OSError if the fork failed. */
5298 PyErr_SetString(PyExc_RuntimeError,
5299 "not holding the import lock");
5300 return NULL;
5301 }
5302 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005303}
Larry Hastings2f936352014-08-05 14:04:04 +10005304#endif /* HAVE_FORK */
5305
Guido van Rossum85e3b011991-06-03 12:42:10 +00005306
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005307#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005308#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005309/*[clinic input]
5310os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005311
Larry Hastings2f936352014-08-05 14:04:04 +10005312 policy: int
5313
5314Get the maximum scheduling priority for policy.
5315[clinic start generated code]*/
5316
Larry Hastings2f936352014-08-05 14:04:04 +10005317static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005318os_sched_get_priority_max_impl(PyObject *module, int policy)
5319/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005320{
5321 int max;
5322
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005323 max = sched_get_priority_max(policy);
5324 if (max < 0)
5325 return posix_error();
5326 return PyLong_FromLong(max);
5327}
5328
Larry Hastings2f936352014-08-05 14:04:04 +10005329
5330/*[clinic input]
5331os.sched_get_priority_min
5332
5333 policy: int
5334
5335Get the minimum scheduling priority for policy.
5336[clinic start generated code]*/
5337
Larry Hastings2f936352014-08-05 14:04:04 +10005338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005339os_sched_get_priority_min_impl(PyObject *module, int policy)
5340/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005341{
5342 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005343 if (min < 0)
5344 return posix_error();
5345 return PyLong_FromLong(min);
5346}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005347#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5348
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005349
Larry Hastings2f936352014-08-05 14:04:04 +10005350#ifdef HAVE_SCHED_SETSCHEDULER
5351/*[clinic input]
5352os.sched_getscheduler
5353 pid: pid_t
5354 /
5355
5356Get the scheduling policy for the process identifiedy by pid.
5357
5358Passing 0 for pid returns the scheduling policy for the calling process.
5359[clinic start generated code]*/
5360
Larry Hastings2f936352014-08-05 14:04:04 +10005361static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005362os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5363/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005364{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005365 int policy;
5366
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005367 policy = sched_getscheduler(pid);
5368 if (policy < 0)
5369 return posix_error();
5370 return PyLong_FromLong(policy);
5371}
Larry Hastings2f936352014-08-05 14:04:04 +10005372#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005373
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005374
5375#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005376/*[clinic input]
5377class os.sched_param "PyObject *" "&SchedParamType"
5378
5379@classmethod
5380os.sched_param.__new__
5381
5382 sched_priority: object
5383 A scheduling parameter.
5384
5385Current has only one field: sched_priority");
5386[clinic start generated code]*/
5387
Larry Hastings2f936352014-08-05 14:04:04 +10005388static PyObject *
5389os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005390/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005391{
5392 PyObject *res;
5393
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005394 res = PyStructSequence_New(type);
5395 if (!res)
5396 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005397 Py_INCREF(sched_priority);
5398 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005399 return res;
5400}
5401
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005402
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005403PyDoc_VAR(os_sched_param__doc__);
5404
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005405static PyStructSequence_Field sched_param_fields[] = {
5406 {"sched_priority", "the scheduling priority"},
5407 {0}
5408};
5409
5410static PyStructSequence_Desc sched_param_desc = {
5411 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005412 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005413 sched_param_fields,
5414 1
5415};
5416
5417static int
5418convert_sched_param(PyObject *param, struct sched_param *res)
5419{
5420 long priority;
5421
5422 if (Py_TYPE(param) != &SchedParamType) {
5423 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5424 return 0;
5425 }
5426 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5427 if (priority == -1 && PyErr_Occurred())
5428 return 0;
5429 if (priority > INT_MAX || priority < INT_MIN) {
5430 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5431 return 0;
5432 }
5433 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5434 return 1;
5435}
Larry Hastings2f936352014-08-05 14:04:04 +10005436#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005437
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005438
5439#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005440/*[clinic input]
5441os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005442
Larry Hastings2f936352014-08-05 14:04:04 +10005443 pid: pid_t
5444 policy: int
5445 param: sched_param
5446 /
5447
5448Set the scheduling policy for the process identified by pid.
5449
5450If pid is 0, the calling process is changed.
5451param is an instance of sched_param.
5452[clinic start generated code]*/
5453
Larry Hastings2f936352014-08-05 14:04:04 +10005454static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005455os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005456 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005457/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005458{
Jesus Cea9c822272011-09-10 01:40:52 +02005459 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005460 ** sched_setscheduler() returns 0 in Linux, but the previous
5461 ** scheduling policy under Solaris/Illumos, and others.
5462 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005463 */
Larry Hastings2f936352014-08-05 14:04:04 +10005464 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005465 return posix_error();
5466 Py_RETURN_NONE;
5467}
Larry Hastings2f936352014-08-05 14:04:04 +10005468#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005469
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005470
5471#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005472/*[clinic input]
5473os.sched_getparam
5474 pid: pid_t
5475 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005476
Larry Hastings2f936352014-08-05 14:04:04 +10005477Returns scheduling parameters for the process identified by pid.
5478
5479If pid is 0, returns parameters for the calling process.
5480Return value is an instance of sched_param.
5481[clinic start generated code]*/
5482
Larry Hastings2f936352014-08-05 14:04:04 +10005483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005484os_sched_getparam_impl(PyObject *module, pid_t pid)
5485/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005486{
5487 struct sched_param param;
5488 PyObject *result;
5489 PyObject *priority;
5490
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005491 if (sched_getparam(pid, &param))
5492 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005493 result = PyStructSequence_New(&SchedParamType);
5494 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005495 return NULL;
5496 priority = PyLong_FromLong(param.sched_priority);
5497 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005498 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005499 return NULL;
5500 }
Larry Hastings2f936352014-08-05 14:04:04 +10005501 PyStructSequence_SET_ITEM(result, 0, priority);
5502 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005503}
5504
Larry Hastings2f936352014-08-05 14:04:04 +10005505
5506/*[clinic input]
5507os.sched_setparam
5508 pid: pid_t
5509 param: sched_param
5510 /
5511
5512Set scheduling parameters for the process identified by pid.
5513
5514If pid is 0, sets parameters for the calling process.
5515param should be an instance of sched_param.
5516[clinic start generated code]*/
5517
Larry Hastings2f936352014-08-05 14:04:04 +10005518static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005519os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005520 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005521/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005522{
5523 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005524 return posix_error();
5525 Py_RETURN_NONE;
5526}
Larry Hastings2f936352014-08-05 14:04:04 +10005527#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005528
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005529
5530#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005531/*[clinic input]
5532os.sched_rr_get_interval -> double
5533 pid: pid_t
5534 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005535
Larry Hastings2f936352014-08-05 14:04:04 +10005536Return the round-robin quantum for the process identified by pid, in seconds.
5537
5538Value returned is a float.
5539[clinic start generated code]*/
5540
Larry Hastings2f936352014-08-05 14:04:04 +10005541static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005542os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5543/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005544{
5545 struct timespec interval;
5546 if (sched_rr_get_interval(pid, &interval)) {
5547 posix_error();
5548 return -1.0;
5549 }
5550 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5551}
5552#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005553
Larry Hastings2f936352014-08-05 14:04:04 +10005554
5555/*[clinic input]
5556os.sched_yield
5557
5558Voluntarily relinquish the CPU.
5559[clinic start generated code]*/
5560
Larry Hastings2f936352014-08-05 14:04:04 +10005561static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005562os_sched_yield_impl(PyObject *module)
5563/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005564{
5565 if (sched_yield())
5566 return posix_error();
5567 Py_RETURN_NONE;
5568}
5569
Benjamin Peterson2740af82011-08-02 17:41:34 -05005570#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005571/* The minimum number of CPUs allocated in a cpu_set_t */
5572static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005573
Larry Hastings2f936352014-08-05 14:04:04 +10005574/*[clinic input]
5575os.sched_setaffinity
5576 pid: pid_t
5577 mask : object
5578 /
5579
5580Set the CPU affinity of the process identified by pid to mask.
5581
5582mask should be an iterable of integers identifying CPUs.
5583[clinic start generated code]*/
5584
Larry Hastings2f936352014-08-05 14:04:04 +10005585static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005586os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5587/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005588{
Antoine Pitrou84869872012-08-04 16:16:35 +02005589 int ncpus;
5590 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005591 cpu_set_t *cpu_set = NULL;
5592 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005593
Larry Hastings2f936352014-08-05 14:04:04 +10005594 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005595 if (iterator == NULL)
5596 return NULL;
5597
5598 ncpus = NCPUS_START;
5599 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005600 cpu_set = CPU_ALLOC(ncpus);
5601 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005602 PyErr_NoMemory();
5603 goto error;
5604 }
Larry Hastings2f936352014-08-05 14:04:04 +10005605 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005606
5607 while ((item = PyIter_Next(iterator))) {
5608 long cpu;
5609 if (!PyLong_Check(item)) {
5610 PyErr_Format(PyExc_TypeError,
5611 "expected an iterator of ints, "
5612 "but iterator yielded %R",
5613 Py_TYPE(item));
5614 Py_DECREF(item);
5615 goto error;
5616 }
5617 cpu = PyLong_AsLong(item);
5618 Py_DECREF(item);
5619 if (cpu < 0) {
5620 if (!PyErr_Occurred())
5621 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5622 goto error;
5623 }
5624 if (cpu > INT_MAX - 1) {
5625 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5626 goto error;
5627 }
5628 if (cpu >= ncpus) {
5629 /* Grow CPU mask to fit the CPU number */
5630 int newncpus = ncpus;
5631 cpu_set_t *newmask;
5632 size_t newsetsize;
5633 while (newncpus <= cpu) {
5634 if (newncpus > INT_MAX / 2)
5635 newncpus = cpu + 1;
5636 else
5637 newncpus = newncpus * 2;
5638 }
5639 newmask = CPU_ALLOC(newncpus);
5640 if (newmask == NULL) {
5641 PyErr_NoMemory();
5642 goto error;
5643 }
5644 newsetsize = CPU_ALLOC_SIZE(newncpus);
5645 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005646 memcpy(newmask, cpu_set, setsize);
5647 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005648 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005649 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005650 ncpus = newncpus;
5651 }
Larry Hastings2f936352014-08-05 14:04:04 +10005652 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005653 }
5654 Py_CLEAR(iterator);
5655
Larry Hastings2f936352014-08-05 14:04:04 +10005656 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005657 posix_error();
5658 goto error;
5659 }
Larry Hastings2f936352014-08-05 14:04:04 +10005660 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005661 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005662
5663error:
Larry Hastings2f936352014-08-05 14:04:04 +10005664 if (cpu_set)
5665 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005666 Py_XDECREF(iterator);
5667 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005668}
5669
Larry Hastings2f936352014-08-05 14:04:04 +10005670
5671/*[clinic input]
5672os.sched_getaffinity
5673 pid: pid_t
5674 /
5675
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005676Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005677
5678The affinity is returned as a set of CPU identifiers.
5679[clinic start generated code]*/
5680
Larry Hastings2f936352014-08-05 14:04:04 +10005681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005682os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005683/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005684{
Antoine Pitrou84869872012-08-04 16:16:35 +02005685 int cpu, ncpus, count;
5686 size_t setsize;
5687 cpu_set_t *mask = NULL;
5688 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005689
Antoine Pitrou84869872012-08-04 16:16:35 +02005690 ncpus = NCPUS_START;
5691 while (1) {
5692 setsize = CPU_ALLOC_SIZE(ncpus);
5693 mask = CPU_ALLOC(ncpus);
5694 if (mask == NULL)
5695 return PyErr_NoMemory();
5696 if (sched_getaffinity(pid, setsize, mask) == 0)
5697 break;
5698 CPU_FREE(mask);
5699 if (errno != EINVAL)
5700 return posix_error();
5701 if (ncpus > INT_MAX / 2) {
5702 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5703 "a large enough CPU set");
5704 return NULL;
5705 }
5706 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005707 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005708
5709 res = PySet_New(NULL);
5710 if (res == NULL)
5711 goto error;
5712 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5713 if (CPU_ISSET_S(cpu, setsize, mask)) {
5714 PyObject *cpu_num = PyLong_FromLong(cpu);
5715 --count;
5716 if (cpu_num == NULL)
5717 goto error;
5718 if (PySet_Add(res, cpu_num)) {
5719 Py_DECREF(cpu_num);
5720 goto error;
5721 }
5722 Py_DECREF(cpu_num);
5723 }
5724 }
5725 CPU_FREE(mask);
5726 return res;
5727
5728error:
5729 if (mask)
5730 CPU_FREE(mask);
5731 Py_XDECREF(res);
5732 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005733}
5734
Benjamin Peterson2740af82011-08-02 17:41:34 -05005735#endif /* HAVE_SCHED_SETAFFINITY */
5736
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005737#endif /* HAVE_SCHED_H */
5738
Larry Hastings2f936352014-08-05 14:04:04 +10005739
Neal Norwitzb59798b2003-03-21 01:43:31 +00005740/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005741/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5742#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005743#define DEV_PTY_FILE "/dev/ptc"
5744#define HAVE_DEV_PTMX
5745#else
5746#define DEV_PTY_FILE "/dev/ptmx"
5747#endif
5748
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005749#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005750#ifdef HAVE_PTY_H
5751#include <pty.h>
5752#else
5753#ifdef HAVE_LIBUTIL_H
5754#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005755#else
5756#ifdef HAVE_UTIL_H
5757#include <util.h>
5758#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005759#endif /* HAVE_LIBUTIL_H */
5760#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005761#ifdef HAVE_STROPTS_H
5762#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005763#endif
5764#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005765
Larry Hastings2f936352014-08-05 14:04:04 +10005766
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005767#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005768/*[clinic input]
5769os.openpty
5770
5771Open a pseudo-terminal.
5772
5773Return a tuple of (master_fd, slave_fd) containing open file descriptors
5774for both the master and slave ends.
5775[clinic start generated code]*/
5776
Larry Hastings2f936352014-08-05 14:04:04 +10005777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005778os_openpty_impl(PyObject *module)
5779/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005780{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005781 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005782#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005783 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005784#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005785#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005787#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005788 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005789#endif
5790#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005791
Thomas Wouters70c21a12000-07-14 14:28:33 +00005792#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005793 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005794 goto posix_error;
5795
5796 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5797 goto error;
5798 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5799 goto error;
5800
Neal Norwitzb59798b2003-03-21 01:43:31 +00005801#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5803 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005804 goto posix_error;
5805 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5806 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005807
Victor Stinnerdaf45552013-08-28 00:53:59 +02005808 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005809 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005810 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005811
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005812#else
Victor Stinner000de532013-11-25 23:19:58 +01005813 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005815 goto posix_error;
5816
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005818
Victor Stinner8c62be82010-05-06 00:08:46 +00005819 /* change permission of slave */
5820 if (grantpt(master_fd) < 0) {
5821 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005822 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005824
Victor Stinner8c62be82010-05-06 00:08:46 +00005825 /* unlock slave */
5826 if (unlockpt(master_fd) < 0) {
5827 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005828 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005829 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005830
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005832
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 slave_name = ptsname(master_fd); /* get name of slave */
5834 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005835 goto posix_error;
5836
5837 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005838 if (slave_fd == -1)
5839 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005840
5841 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5842 goto posix_error;
5843
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005844#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005845 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5846 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005847#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005849#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005850#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005851#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005852
Victor Stinner8c62be82010-05-06 00:08:46 +00005853 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005854
Victor Stinnerdaf45552013-08-28 00:53:59 +02005855posix_error:
5856 posix_error();
5857error:
5858 if (master_fd != -1)
5859 close(master_fd);
5860 if (slave_fd != -1)
5861 close(slave_fd);
5862 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005863}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005864#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005865
Larry Hastings2f936352014-08-05 14:04:04 +10005866
Fred Drake8cef4cf2000-06-28 16:40:38 +00005867#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005868/*[clinic input]
5869os.forkpty
5870
5871Fork a new process with a new pseudo-terminal as controlling tty.
5872
5873Returns a tuple of (pid, master_fd).
5874Like fork(), return pid of 0 to the child process,
5875and pid of child to the parent process.
5876To both, return fd of newly opened pseudo-terminal.
5877[clinic start generated code]*/
5878
Larry Hastings2f936352014-08-05 14:04:04 +10005879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005880os_forkpty_impl(PyObject *module)
5881/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005882{
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 int master_fd = -1, result = 0;
5884 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005885
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 _PyImport_AcquireLock();
5887 pid = forkpty(&master_fd, NULL, NULL, NULL);
5888 if (pid == 0) {
5889 /* child: this clobbers and resets the import lock. */
5890 PyOS_AfterFork();
5891 } else {
5892 /* parent: release the import lock. */
5893 result = _PyImport_ReleaseLock();
5894 }
5895 if (pid == -1)
5896 return posix_error();
5897 if (result < 0) {
5898 /* Don't clobber the OSError if the fork failed. */
5899 PyErr_SetString(PyExc_RuntimeError,
5900 "not holding the import lock");
5901 return NULL;
5902 }
5903 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005904}
Larry Hastings2f936352014-08-05 14:04:04 +10005905#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005906
Ross Lagerwall7807c352011-03-17 20:20:30 +02005907
Guido van Rossumad0ee831995-03-01 10:34:45 +00005908#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005909/*[clinic input]
5910os.getegid
5911
5912Return the current process's effective group id.
5913[clinic start generated code]*/
5914
Larry Hastings2f936352014-08-05 14:04:04 +10005915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005916os_getegid_impl(PyObject *module)
5917/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005918{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005919 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005920}
Larry Hastings2f936352014-08-05 14:04:04 +10005921#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005922
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005923
Guido van Rossumad0ee831995-03-01 10:34:45 +00005924#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005925/*[clinic input]
5926os.geteuid
5927
5928Return the current process's effective user id.
5929[clinic start generated code]*/
5930
Larry Hastings2f936352014-08-05 14:04:04 +10005931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005932os_geteuid_impl(PyObject *module)
5933/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005934{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005935 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005936}
Larry Hastings2f936352014-08-05 14:04:04 +10005937#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005939
Guido van Rossumad0ee831995-03-01 10:34:45 +00005940#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005941/*[clinic input]
5942os.getgid
5943
5944Return the current process's group id.
5945[clinic start generated code]*/
5946
Larry Hastings2f936352014-08-05 14:04:04 +10005947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005948os_getgid_impl(PyObject *module)
5949/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005950{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005951 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005952}
Larry Hastings2f936352014-08-05 14:04:04 +10005953#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005955
Berker Peksag39404992016-09-15 20:45:16 +03005956#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10005957/*[clinic input]
5958os.getpid
5959
5960Return the current process id.
5961[clinic start generated code]*/
5962
Larry Hastings2f936352014-08-05 14:04:04 +10005963static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005964os_getpid_impl(PyObject *module)
5965/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005966{
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005968}
Berker Peksag39404992016-09-15 20:45:16 +03005969#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005970
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005971#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005972
5973/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005974PyDoc_STRVAR(posix_getgrouplist__doc__,
5975"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5976Returns a list of groups to which a user belongs.\n\n\
5977 user: username to lookup\n\
5978 group: base group id of the user");
5979
5980static PyObject *
5981posix_getgrouplist(PyObject *self, PyObject *args)
5982{
5983#ifdef NGROUPS_MAX
5984#define MAX_GROUPS NGROUPS_MAX
5985#else
5986 /* defined to be 16 on Solaris7, so this should be a small number */
5987#define MAX_GROUPS 64
5988#endif
5989
5990 const char *user;
5991 int i, ngroups;
5992 PyObject *list;
5993#ifdef __APPLE__
5994 int *groups, basegid;
5995#else
5996 gid_t *groups, basegid;
5997#endif
5998 ngroups = MAX_GROUPS;
5999
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006000#ifdef __APPLE__
6001 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006002 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006003#else
6004 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6005 _Py_Gid_Converter, &basegid))
6006 return NULL;
6007#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006008
6009#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006010 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006011#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006012 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006013#endif
6014 if (groups == NULL)
6015 return PyErr_NoMemory();
6016
6017 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6018 PyMem_Del(groups);
6019 return posix_error();
6020 }
6021
6022 list = PyList_New(ngroups);
6023 if (list == NULL) {
6024 PyMem_Del(groups);
6025 return NULL;
6026 }
6027
6028 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006029#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006030 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006031#else
6032 PyObject *o = _PyLong_FromGid(groups[i]);
6033#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006034 if (o == NULL) {
6035 Py_DECREF(list);
6036 PyMem_Del(groups);
6037 return NULL;
6038 }
6039 PyList_SET_ITEM(list, i, o);
6040 }
6041
6042 PyMem_Del(groups);
6043
6044 return list;
6045}
Larry Hastings2f936352014-08-05 14:04:04 +10006046#endif /* HAVE_GETGROUPLIST */
6047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006048
Fred Drakec9680921999-12-13 16:37:25 +00006049#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006050/*[clinic input]
6051os.getgroups
6052
6053Return list of supplemental group IDs for the process.
6054[clinic start generated code]*/
6055
Larry Hastings2f936352014-08-05 14:04:04 +10006056static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006057os_getgroups_impl(PyObject *module)
6058/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006059{
6060 PyObject *result = NULL;
6061
Fred Drakec9680921999-12-13 16:37:25 +00006062#ifdef NGROUPS_MAX
6063#define MAX_GROUPS NGROUPS_MAX
6064#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006066#define MAX_GROUPS 64
6067#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006069
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006070 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006071 * This is a helper variable to store the intermediate result when
6072 * that happens.
6073 *
6074 * To keep the code readable the OSX behaviour is unconditional,
6075 * according to the POSIX spec this should be safe on all unix-y
6076 * systems.
6077 */
6078 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006080
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006081#ifdef __APPLE__
6082 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6083 * there are more groups than can fit in grouplist. Therefore, on OS X
6084 * always first call getgroups with length 0 to get the actual number
6085 * of groups.
6086 */
6087 n = getgroups(0, NULL);
6088 if (n < 0) {
6089 return posix_error();
6090 } else if (n <= MAX_GROUPS) {
6091 /* groups will fit in existing array */
6092 alt_grouplist = grouplist;
6093 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006094 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006095 if (alt_grouplist == NULL) {
6096 errno = EINVAL;
6097 return posix_error();
6098 }
6099 }
6100
6101 n = getgroups(n, alt_grouplist);
6102 if (n == -1) {
6103 if (alt_grouplist != grouplist) {
6104 PyMem_Free(alt_grouplist);
6105 }
6106 return posix_error();
6107 }
6108#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006110 if (n < 0) {
6111 if (errno == EINVAL) {
6112 n = getgroups(0, NULL);
6113 if (n == -1) {
6114 return posix_error();
6115 }
6116 if (n == 0) {
6117 /* Avoid malloc(0) */
6118 alt_grouplist = grouplist;
6119 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006120 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006121 if (alt_grouplist == NULL) {
6122 errno = EINVAL;
6123 return posix_error();
6124 }
6125 n = getgroups(n, alt_grouplist);
6126 if (n == -1) {
6127 PyMem_Free(alt_grouplist);
6128 return posix_error();
6129 }
6130 }
6131 } else {
6132 return posix_error();
6133 }
6134 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006135#endif
6136
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006137 result = PyList_New(n);
6138 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 int i;
6140 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006141 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006142 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006143 Py_DECREF(result);
6144 result = NULL;
6145 break;
Fred Drakec9680921999-12-13 16:37:25 +00006146 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006148 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006149 }
6150
6151 if (alt_grouplist != grouplist) {
6152 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006154
Fred Drakec9680921999-12-13 16:37:25 +00006155 return result;
6156}
Larry Hastings2f936352014-08-05 14:04:04 +10006157#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006158
Antoine Pitroub7572f02009-12-02 20:46:48 +00006159#ifdef HAVE_INITGROUPS
6160PyDoc_STRVAR(posix_initgroups__doc__,
6161"initgroups(username, gid) -> None\n\n\
6162Call the system initgroups() to initialize the group access list with all of\n\
6163the groups of which the specified username is a member, plus the specified\n\
6164group id.");
6165
Larry Hastings2f936352014-08-05 14:04:04 +10006166/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006167static PyObject *
6168posix_initgroups(PyObject *self, PyObject *args)
6169{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006170 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006171 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006172 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006173#ifdef __APPLE__
6174 int gid;
6175#else
6176 gid_t gid;
6177#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006178
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006179#ifdef __APPLE__
6180 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6181 PyUnicode_FSConverter, &oname,
6182 &gid))
6183#else
6184 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6185 PyUnicode_FSConverter, &oname,
6186 _Py_Gid_Converter, &gid))
6187#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006189 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006190
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006191 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006192 Py_DECREF(oname);
6193 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006194 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006195
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 Py_INCREF(Py_None);
6197 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006198}
Larry Hastings2f936352014-08-05 14:04:04 +10006199#endif /* HAVE_INITGROUPS */
6200
Antoine Pitroub7572f02009-12-02 20:46:48 +00006201
Martin v. Löwis606edc12002-06-13 21:09:11 +00006202#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006203/*[clinic input]
6204os.getpgid
6205
6206 pid: pid_t
6207
6208Call the system call getpgid(), and return the result.
6209[clinic start generated code]*/
6210
Larry Hastings2f936352014-08-05 14:04:04 +10006211static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006212os_getpgid_impl(PyObject *module, pid_t pid)
6213/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006214{
6215 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006216 if (pgid < 0)
6217 return posix_error();
6218 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006219}
6220#endif /* HAVE_GETPGID */
6221
6222
Guido van Rossumb6775db1994-08-01 11:34:53 +00006223#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006224/*[clinic input]
6225os.getpgrp
6226
6227Return the current process group id.
6228[clinic start generated code]*/
6229
Larry Hastings2f936352014-08-05 14:04:04 +10006230static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006231os_getpgrp_impl(PyObject *module)
6232/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006233{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006234#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006236#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006238#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006239}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006240#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006242
Guido van Rossumb6775db1994-08-01 11:34:53 +00006243#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006244/*[clinic input]
6245os.setpgrp
6246
6247Make the current process the leader of its process group.
6248[clinic start generated code]*/
6249
Larry Hastings2f936352014-08-05 14:04:04 +10006250static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006251os_setpgrp_impl(PyObject *module)
6252/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006253{
Guido van Rossum64933891994-10-20 21:56:42 +00006254#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006255 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006256#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006258#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 return posix_error();
6260 Py_INCREF(Py_None);
6261 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006262}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006263#endif /* HAVE_SETPGRP */
6264
Guido van Rossumad0ee831995-03-01 10:34:45 +00006265#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006266
6267#ifdef MS_WINDOWS
6268#include <tlhelp32.h>
6269
6270static PyObject*
6271win32_getppid()
6272{
6273 HANDLE snapshot;
6274 pid_t mypid;
6275 PyObject* result = NULL;
6276 BOOL have_record;
6277 PROCESSENTRY32 pe;
6278
6279 mypid = getpid(); /* This function never fails */
6280
6281 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6282 if (snapshot == INVALID_HANDLE_VALUE)
6283 return PyErr_SetFromWindowsErr(GetLastError());
6284
6285 pe.dwSize = sizeof(pe);
6286 have_record = Process32First(snapshot, &pe);
6287 while (have_record) {
6288 if (mypid == (pid_t)pe.th32ProcessID) {
6289 /* We could cache the ulong value in a static variable. */
6290 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6291 break;
6292 }
6293
6294 have_record = Process32Next(snapshot, &pe);
6295 }
6296
6297 /* If our loop exits and our pid was not found (result will be NULL)
6298 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6299 * error anyway, so let's raise it. */
6300 if (!result)
6301 result = PyErr_SetFromWindowsErr(GetLastError());
6302
6303 CloseHandle(snapshot);
6304
6305 return result;
6306}
6307#endif /*MS_WINDOWS*/
6308
Larry Hastings2f936352014-08-05 14:04:04 +10006309
6310/*[clinic input]
6311os.getppid
6312
6313Return the parent's process id.
6314
6315If the parent process has already exited, Windows machines will still
6316return its id; others systems will return the id of the 'init' process (1).
6317[clinic start generated code]*/
6318
Larry Hastings2f936352014-08-05 14:04:04 +10006319static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006320os_getppid_impl(PyObject *module)
6321/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006322{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006323#ifdef MS_WINDOWS
6324 return win32_getppid();
6325#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006327#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006328}
6329#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006331
Fred Drake12c6e2d1999-12-14 21:25:03 +00006332#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006333/*[clinic input]
6334os.getlogin
6335
6336Return the actual login name.
6337[clinic start generated code]*/
6338
Larry Hastings2f936352014-08-05 14:04:04 +10006339static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006340os_getlogin_impl(PyObject *module)
6341/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006342{
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006344#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006345 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006346 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006347
6348 if (GetUserNameW(user_name, &num_chars)) {
6349 /* num_chars is the number of unicode chars plus null terminator */
6350 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006351 }
6352 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006353 result = PyErr_SetFromWindowsErr(GetLastError());
6354#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 char *name;
6356 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006357
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 errno = 0;
6359 name = getlogin();
6360 if (name == NULL) {
6361 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006362 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006363 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006364 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 }
6366 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006367 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006369#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006370 return result;
6371}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006372#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006373
Larry Hastings2f936352014-08-05 14:04:04 +10006374
Guido van Rossumad0ee831995-03-01 10:34:45 +00006375#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006376/*[clinic input]
6377os.getuid
6378
6379Return the current process's user id.
6380[clinic start generated code]*/
6381
Larry Hastings2f936352014-08-05 14:04:04 +10006382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006383os_getuid_impl(PyObject *module)
6384/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006385{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006386 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006387}
Larry Hastings2f936352014-08-05 14:04:04 +10006388#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006389
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006390
Brian Curtineb24d742010-04-12 17:16:38 +00006391#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006392#define HAVE_KILL
6393#endif /* MS_WINDOWS */
6394
6395#ifdef HAVE_KILL
6396/*[clinic input]
6397os.kill
6398
6399 pid: pid_t
6400 signal: Py_ssize_t
6401 /
6402
6403Kill a process with a signal.
6404[clinic start generated code]*/
6405
Larry Hastings2f936352014-08-05 14:04:04 +10006406static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006407os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6408/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006409#ifndef MS_WINDOWS
6410{
6411 if (kill(pid, (int)signal) == -1)
6412 return posix_error();
6413 Py_RETURN_NONE;
6414}
6415#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006416{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006417 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006418 DWORD sig = (DWORD)signal;
6419 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006421
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 /* Console processes which share a common console can be sent CTRL+C or
6423 CTRL+BREAK events, provided they handle said events. */
6424 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006425 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 err = GetLastError();
6427 PyErr_SetFromWindowsErr(err);
6428 }
6429 else
6430 Py_RETURN_NONE;
6431 }
Brian Curtineb24d742010-04-12 17:16:38 +00006432
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6434 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006435 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 if (handle == NULL) {
6437 err = GetLastError();
6438 return PyErr_SetFromWindowsErr(err);
6439 }
Brian Curtineb24d742010-04-12 17:16:38 +00006440
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 if (TerminateProcess(handle, sig) == 0) {
6442 err = GetLastError();
6443 result = PyErr_SetFromWindowsErr(err);
6444 } else {
6445 Py_INCREF(Py_None);
6446 result = Py_None;
6447 }
Brian Curtineb24d742010-04-12 17:16:38 +00006448
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 CloseHandle(handle);
6450 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006451}
Larry Hastings2f936352014-08-05 14:04:04 +10006452#endif /* !MS_WINDOWS */
6453#endif /* HAVE_KILL */
6454
6455
6456#ifdef HAVE_KILLPG
6457/*[clinic input]
6458os.killpg
6459
6460 pgid: pid_t
6461 signal: int
6462 /
6463
6464Kill a process group with a signal.
6465[clinic start generated code]*/
6466
Larry Hastings2f936352014-08-05 14:04:04 +10006467static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006468os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6469/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006470{
6471 /* XXX some man pages make the `pgid` parameter an int, others
6472 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6473 take the same type. Moreover, pid_t is always at least as wide as
6474 int (else compilation of this module fails), which is safe. */
6475 if (killpg(pgid, signal) == -1)
6476 return posix_error();
6477 Py_RETURN_NONE;
6478}
6479#endif /* HAVE_KILLPG */
6480
Brian Curtineb24d742010-04-12 17:16:38 +00006481
Guido van Rossumc0125471996-06-28 18:55:32 +00006482#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006483#ifdef HAVE_SYS_LOCK_H
6484#include <sys/lock.h>
6485#endif
6486
Larry Hastings2f936352014-08-05 14:04:04 +10006487/*[clinic input]
6488os.plock
6489 op: int
6490 /
6491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006492Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006493[clinic start generated code]*/
6494
Larry Hastings2f936352014-08-05 14:04:04 +10006495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006496os_plock_impl(PyObject *module, int op)
6497/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006498{
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 if (plock(op) == -1)
6500 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006501 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006502}
Larry Hastings2f936352014-08-05 14:04:04 +10006503#endif /* HAVE_PLOCK */
6504
Guido van Rossumc0125471996-06-28 18:55:32 +00006505
Guido van Rossumb6775db1994-08-01 11:34:53 +00006506#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006507/*[clinic input]
6508os.setuid
6509
6510 uid: uid_t
6511 /
6512
6513Set the current process's user id.
6514[clinic start generated code]*/
6515
Larry Hastings2f936352014-08-05 14:04:04 +10006516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006517os_setuid_impl(PyObject *module, uid_t uid)
6518/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006519{
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 if (setuid(uid) < 0)
6521 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006522 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006523}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006524#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006525
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006526
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006527#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006528/*[clinic input]
6529os.seteuid
6530
6531 euid: uid_t
6532 /
6533
6534Set the current process's effective user id.
6535[clinic start generated code]*/
6536
Larry Hastings2f936352014-08-05 14:04:04 +10006537static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006538os_seteuid_impl(PyObject *module, uid_t euid)
6539/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006540{
6541 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006543 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006544}
6545#endif /* HAVE_SETEUID */
6546
Larry Hastings2f936352014-08-05 14:04:04 +10006547
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006548#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006549/*[clinic input]
6550os.setegid
6551
6552 egid: gid_t
6553 /
6554
6555Set the current process's effective group id.
6556[clinic start generated code]*/
6557
Larry Hastings2f936352014-08-05 14:04:04 +10006558static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006559os_setegid_impl(PyObject *module, gid_t egid)
6560/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006561{
6562 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006564 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006565}
6566#endif /* HAVE_SETEGID */
6567
Larry Hastings2f936352014-08-05 14:04:04 +10006568
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006569#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006570/*[clinic input]
6571os.setreuid
6572
6573 ruid: uid_t
6574 euid: uid_t
6575 /
6576
6577Set the current process's real and effective user ids.
6578[clinic start generated code]*/
6579
Larry Hastings2f936352014-08-05 14:04:04 +10006580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006581os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6582/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006583{
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 if (setreuid(ruid, euid) < 0) {
6585 return posix_error();
6586 } else {
6587 Py_INCREF(Py_None);
6588 return Py_None;
6589 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006590}
6591#endif /* HAVE_SETREUID */
6592
Larry Hastings2f936352014-08-05 14:04:04 +10006593
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006594#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006595/*[clinic input]
6596os.setregid
6597
6598 rgid: gid_t
6599 egid: gid_t
6600 /
6601
6602Set the current process's real and effective group ids.
6603[clinic start generated code]*/
6604
Larry Hastings2f936352014-08-05 14:04:04 +10006605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006606os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6607/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006608{
6609 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006611 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006612}
6613#endif /* HAVE_SETREGID */
6614
Larry Hastings2f936352014-08-05 14:04:04 +10006615
Guido van Rossumb6775db1994-08-01 11:34:53 +00006616#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006617/*[clinic input]
6618os.setgid
6619 gid: gid_t
6620 /
6621
6622Set the current process's group id.
6623[clinic start generated code]*/
6624
Larry Hastings2f936352014-08-05 14:04:04 +10006625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006626os_setgid_impl(PyObject *module, gid_t gid)
6627/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006628{
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 if (setgid(gid) < 0)
6630 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006631 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006632}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006633#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006634
Larry Hastings2f936352014-08-05 14:04:04 +10006635
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006636#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006637/*[clinic input]
6638os.setgroups
6639
6640 groups: object
6641 /
6642
6643Set the groups of the current process to list.
6644[clinic start generated code]*/
6645
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006646static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006647os_setgroups(PyObject *module, PyObject *groups)
6648/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006649{
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 int i, len;
6651 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006652
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 if (!PySequence_Check(groups)) {
6654 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6655 return NULL;
6656 }
6657 len = PySequence_Size(groups);
6658 if (len > MAX_GROUPS) {
6659 PyErr_SetString(PyExc_ValueError, "too many groups");
6660 return NULL;
6661 }
6662 for(i = 0; i < len; i++) {
6663 PyObject *elem;
6664 elem = PySequence_GetItem(groups, i);
6665 if (!elem)
6666 return NULL;
6667 if (!PyLong_Check(elem)) {
6668 PyErr_SetString(PyExc_TypeError,
6669 "groups must be integers");
6670 Py_DECREF(elem);
6671 return NULL;
6672 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006673 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 Py_DECREF(elem);
6675 return NULL;
6676 }
6677 }
6678 Py_DECREF(elem);
6679 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006680
Victor Stinner8c62be82010-05-06 00:08:46 +00006681 if (setgroups(len, grouplist) < 0)
6682 return posix_error();
6683 Py_INCREF(Py_None);
6684 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006685}
6686#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006687
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006688#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6689static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006690wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006691{
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 PyObject *result;
6693 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006694 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006695
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 if (pid == -1)
6697 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006698
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 if (struct_rusage == NULL) {
6700 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6701 if (m == NULL)
6702 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006703 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 Py_DECREF(m);
6705 if (struct_rusage == NULL)
6706 return NULL;
6707 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006708
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6710 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6711 if (!result)
6712 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006713
6714#ifndef doubletime
6715#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6716#endif
6717
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006719 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006721 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006722#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006723 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6724 SET_INT(result, 2, ru->ru_maxrss);
6725 SET_INT(result, 3, ru->ru_ixrss);
6726 SET_INT(result, 4, ru->ru_idrss);
6727 SET_INT(result, 5, ru->ru_isrss);
6728 SET_INT(result, 6, ru->ru_minflt);
6729 SET_INT(result, 7, ru->ru_majflt);
6730 SET_INT(result, 8, ru->ru_nswap);
6731 SET_INT(result, 9, ru->ru_inblock);
6732 SET_INT(result, 10, ru->ru_oublock);
6733 SET_INT(result, 11, ru->ru_msgsnd);
6734 SET_INT(result, 12, ru->ru_msgrcv);
6735 SET_INT(result, 13, ru->ru_nsignals);
6736 SET_INT(result, 14, ru->ru_nvcsw);
6737 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006738#undef SET_INT
6739
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 if (PyErr_Occurred()) {
6741 Py_DECREF(result);
6742 return NULL;
6743 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006744
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006746}
6747#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6748
Larry Hastings2f936352014-08-05 14:04:04 +10006749
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006750#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006751/*[clinic input]
6752os.wait3
6753
6754 options: int
6755Wait for completion of a child process.
6756
6757Returns a tuple of information about the child process:
6758 (pid, status, rusage)
6759[clinic start generated code]*/
6760
Larry Hastings2f936352014-08-05 14:04:04 +10006761static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006762os_wait3_impl(PyObject *module, int options)
6763/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006764{
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006767 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006768 WAIT_TYPE status;
6769 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006770
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006771 do {
6772 Py_BEGIN_ALLOW_THREADS
6773 pid = wait3(&status, options, &ru);
6774 Py_END_ALLOW_THREADS
6775 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6776 if (pid < 0)
6777 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006778
Victor Stinner4195b5c2012-02-08 23:03:19 +01006779 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006780}
6781#endif /* HAVE_WAIT3 */
6782
Larry Hastings2f936352014-08-05 14:04:04 +10006783
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006784#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006785/*[clinic input]
6786
6787os.wait4
6788
6789 pid: pid_t
6790 options: int
6791
6792Wait for completion of a specific child process.
6793
6794Returns a tuple of information about the child process:
6795 (pid, status, rusage)
6796[clinic start generated code]*/
6797
Larry Hastings2f936352014-08-05 14:04:04 +10006798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006799os_wait4_impl(PyObject *module, pid_t pid, int options)
6800/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006801{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006802 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006804 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 WAIT_TYPE status;
6806 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006807
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006808 do {
6809 Py_BEGIN_ALLOW_THREADS
6810 res = wait4(pid, &status, options, &ru);
6811 Py_END_ALLOW_THREADS
6812 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6813 if (res < 0)
6814 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006816 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006817}
6818#endif /* HAVE_WAIT4 */
6819
Larry Hastings2f936352014-08-05 14:04:04 +10006820
Ross Lagerwall7807c352011-03-17 20:20:30 +02006821#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006822/*[clinic input]
6823os.waitid
6824
6825 idtype: idtype_t
6826 Must be one of be P_PID, P_PGID or P_ALL.
6827 id: id_t
6828 The id to wait on.
6829 options: int
6830 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6831 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6832 /
6833
6834Returns the result of waiting for a process or processes.
6835
6836Returns either waitid_result or None if WNOHANG is specified and there are
6837no children in a waitable state.
6838[clinic start generated code]*/
6839
Larry Hastings2f936352014-08-05 14:04:04 +10006840static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006841os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6842/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006843{
6844 PyObject *result;
6845 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006846 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006847 siginfo_t si;
6848 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006849
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006850 do {
6851 Py_BEGIN_ALLOW_THREADS
6852 res = waitid(idtype, id, &si, options);
6853 Py_END_ALLOW_THREADS
6854 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6855 if (res < 0)
6856 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006857
6858 if (si.si_pid == 0)
6859 Py_RETURN_NONE;
6860
6861 result = PyStructSequence_New(&WaitidResultType);
6862 if (!result)
6863 return NULL;
6864
6865 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006866 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006867 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6868 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6869 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6870 if (PyErr_Occurred()) {
6871 Py_DECREF(result);
6872 return NULL;
6873 }
6874
6875 return result;
6876}
Larry Hastings2f936352014-08-05 14:04:04 +10006877#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006878
Larry Hastings2f936352014-08-05 14:04:04 +10006879
6880#if defined(HAVE_WAITPID)
6881/*[clinic input]
6882os.waitpid
6883 pid: pid_t
6884 options: int
6885 /
6886
6887Wait for completion of a given child process.
6888
6889Returns a tuple of information regarding the child process:
6890 (pid, status)
6891
6892The options argument is ignored on Windows.
6893[clinic start generated code]*/
6894
Larry Hastings2f936352014-08-05 14:04:04 +10006895static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006896os_waitpid_impl(PyObject *module, pid_t pid, int options)
6897/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006898{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006899 pid_t res;
6900 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 WAIT_TYPE status;
6902 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006903
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006904 do {
6905 Py_BEGIN_ALLOW_THREADS
6906 res = waitpid(pid, &status, options);
6907 Py_END_ALLOW_THREADS
6908 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6909 if (res < 0)
6910 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006912 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006913}
Tim Petersab034fa2002-02-01 11:27:43 +00006914#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006915/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006916/*[clinic input]
6917os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006918 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006919 options: int
6920 /
6921
6922Wait for completion of a given process.
6923
6924Returns a tuple of information regarding the process:
6925 (pid, status << 8)
6926
6927The options argument is ignored on Windows.
6928[clinic start generated code]*/
6929
Larry Hastings2f936352014-08-05 14:04:04 +10006930static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006931os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006932/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006933{
6934 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006935 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006936 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006937
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006938 do {
6939 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006940 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006941 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006942 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006943 Py_END_ALLOW_THREADS
6944 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006945 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006947
Victor Stinner8c62be82010-05-06 00:08:46 +00006948 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006949 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006950}
Larry Hastings2f936352014-08-05 14:04:04 +10006951#endif
6952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006953
Guido van Rossumad0ee831995-03-01 10:34:45 +00006954#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006955/*[clinic input]
6956os.wait
6957
6958Wait for completion of a child process.
6959
6960Returns a tuple of information about the child process:
6961 (pid, status)
6962[clinic start generated code]*/
6963
Larry Hastings2f936352014-08-05 14:04:04 +10006964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006965os_wait_impl(PyObject *module)
6966/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006967{
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006969 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 WAIT_TYPE status;
6971 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006972
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006973 do {
6974 Py_BEGIN_ALLOW_THREADS
6975 pid = wait(&status);
6976 Py_END_ALLOW_THREADS
6977 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6978 if (pid < 0)
6979 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006980
Victor Stinner8c62be82010-05-06 00:08:46 +00006981 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006982}
Larry Hastings2f936352014-08-05 14:04:04 +10006983#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006985
Larry Hastings9cf065c2012-06-22 16:30:09 -07006986#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6987PyDoc_STRVAR(readlink__doc__,
6988"readlink(path, *, dir_fd=None) -> path\n\n\
6989Return a string representing the path to which the symbolic link points.\n\
6990\n\
6991If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6992 and path should be relative; path will then be relative to that directory.\n\
6993dir_fd may not be implemented on your platform.\n\
6994 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006995#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006996
Guido van Rossumb6775db1994-08-01 11:34:53 +00006997#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006998
Larry Hastings2f936352014-08-05 14:04:04 +10006999/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007000static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007001posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007002{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007003 path_t path;
7004 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007005 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007006 ssize_t length;
7007 PyObject *return_value = NULL;
7008 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007009
Larry Hastings9cf065c2012-06-22 16:30:09 -07007010 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007011 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007012 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7013 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007014 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007016
Victor Stinner8c62be82010-05-06 00:08:46 +00007017 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007018#ifdef HAVE_READLINKAT
7019 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007020 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007021 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007022#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007023 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007024 Py_END_ALLOW_THREADS
7025
7026 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007027 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007028 goto exit;
7029 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007030 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007031
7032 if (PyUnicode_Check(path.object))
7033 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7034 else
7035 return_value = PyBytes_FromStringAndSize(buffer, length);
7036exit:
7037 path_cleanup(&path);
7038 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007039}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007040
Guido van Rossumb6775db1994-08-01 11:34:53 +00007041#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007042
Larry Hastings2f936352014-08-05 14:04:04 +10007043#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7044
7045static PyObject *
7046win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7047{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007048 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007049 DWORD n_bytes_returned;
7050 DWORD io_result;
7051 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007052 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007053 HANDLE reparse_point_handle;
7054
Martin Panter70214ad2016-08-04 02:38:59 +00007055 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7056 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007057 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007058
7059 static char *keywords[] = {"path", "dir_fd", NULL};
7060
7061 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7062 &po,
7063 dir_fd_unavailable, &dir_fd
7064 ))
7065 return NULL;
7066
7067 path = PyUnicode_AsUnicode(po);
7068 if (path == NULL)
7069 return NULL;
7070
7071 /* First get a handle to the reparse point */
7072 Py_BEGIN_ALLOW_THREADS
7073 reparse_point_handle = CreateFileW(
7074 path,
7075 0,
7076 0,
7077 0,
7078 OPEN_EXISTING,
7079 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7080 0);
7081 Py_END_ALLOW_THREADS
7082
7083 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7084 return win32_error_object("readlink", po);
7085
7086 Py_BEGIN_ALLOW_THREADS
7087 /* New call DeviceIoControl to read the reparse point */
7088 io_result = DeviceIoControl(
7089 reparse_point_handle,
7090 FSCTL_GET_REPARSE_POINT,
7091 0, 0, /* in buffer */
7092 target_buffer, sizeof(target_buffer),
7093 &n_bytes_returned,
7094 0 /* we're not using OVERLAPPED_IO */
7095 );
7096 CloseHandle(reparse_point_handle);
7097 Py_END_ALLOW_THREADS
7098
7099 if (io_result==0)
7100 return win32_error_object("readlink", po);
7101
7102 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7103 {
7104 PyErr_SetString(PyExc_ValueError,
7105 "not a symbolic link");
7106 return NULL;
7107 }
7108 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7109 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7110
7111 result = PyUnicode_FromWideChar(print_name,
7112 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7113 return result;
7114}
7115
7116#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7117
7118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007119
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121
7122#if defined(MS_WINDOWS)
7123
7124/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007125static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007126
Larry Hastings9cf065c2012-06-22 16:30:09 -07007127static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007128check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129{
7130 HINSTANCE hKernel32;
7131 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007132 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133 return 1;
7134 hKernel32 = GetModuleHandleW(L"KERNEL32");
7135 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7136 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007137 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138}
7139
Victor Stinner31b3b922013-06-05 01:49:17 +02007140/* Remove the last portion of the path */
7141static void
7142_dirnameW(WCHAR *path)
7143{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007144 WCHAR *ptr;
7145
7146 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007147 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007148 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007149 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007150 }
7151 *ptr = 0;
7152}
7153
Victor Stinner31b3b922013-06-05 01:49:17 +02007154/* Is this path absolute? */
7155static int
7156_is_absW(const WCHAR *path)
7157{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007158 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7159
7160}
7161
Victor Stinner31b3b922013-06-05 01:49:17 +02007162/* join root and rest with a backslash */
7163static void
7164_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7165{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007166 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007167
Victor Stinner31b3b922013-06-05 01:49:17 +02007168 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007169 wcscpy(dest_path, rest);
7170 return;
7171 }
7172
7173 root_len = wcslen(root);
7174
7175 wcscpy(dest_path, root);
7176 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007177 dest_path[root_len] = L'\\';
7178 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007179 }
7180 wcscpy(dest_path+root_len, rest);
7181}
7182
Victor Stinner31b3b922013-06-05 01:49:17 +02007183/* Return True if the path at src relative to dest is a directory */
7184static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007185_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007186{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007187 WIN32_FILE_ATTRIBUTE_DATA src_info;
7188 WCHAR dest_parent[MAX_PATH];
7189 WCHAR src_resolved[MAX_PATH] = L"";
7190
7191 /* dest_parent = os.path.dirname(dest) */
7192 wcscpy(dest_parent, dest);
7193 _dirnameW(dest_parent);
7194 /* src_resolved = os.path.join(dest_parent, src) */
7195 _joinW(src_resolved, dest_parent, src);
7196 return (
7197 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7198 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7199 );
7200}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007201#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007202
Larry Hastings2f936352014-08-05 14:04:04 +10007203
7204/*[clinic input]
7205os.symlink
7206 src: path_t
7207 dst: path_t
7208 target_is_directory: bool = False
7209 *
7210 dir_fd: dir_fd(requires='symlinkat')=None
7211
7212# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7213
7214Create a symbolic link pointing to src named dst.
7215
7216target_is_directory is required on Windows if the target is to be
7217 interpreted as a directory. (On Windows, symlink requires
7218 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7219 target_is_directory is ignored on non-Windows platforms.
7220
7221If dir_fd is not None, it should be a file descriptor open to a directory,
7222 and path should be relative; path will then be relative to that directory.
7223dir_fd may not be implemented on your platform.
7224 If it is unavailable, using it will raise a NotImplementedError.
7225
7226[clinic start generated code]*/
7227
Larry Hastings2f936352014-08-05 14:04:04 +10007228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007229os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007230 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007231/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007232{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007233#ifdef MS_WINDOWS
7234 DWORD result;
7235#else
7236 int result;
7237#endif
7238
Larry Hastings9cf065c2012-06-22 16:30:09 -07007239#ifdef MS_WINDOWS
7240 if (!check_CreateSymbolicLink()) {
7241 PyErr_SetString(PyExc_NotImplementedError,
7242 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007243 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007244 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007245 if (!win32_can_symlink) {
7246 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007247 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007248 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007249#endif
7250
Larry Hastings2f936352014-08-05 14:04:04 +10007251 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007252 PyErr_SetString(PyExc_ValueError,
7253 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007254 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007255 }
7256
7257#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007258
Larry Hastings9cf065c2012-06-22 16:30:09 -07007259 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007260 /* if src is a directory, ensure target_is_directory==1 */
7261 target_is_directory |= _check_dirW(src->wide, dst->wide);
7262 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7263 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007264 Py_END_ALLOW_THREADS
7265
Larry Hastings2f936352014-08-05 14:04:04 +10007266 if (!result)
7267 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007268
7269#else
7270
7271 Py_BEGIN_ALLOW_THREADS
7272#if HAVE_SYMLINKAT
7273 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007274 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275 else
7276#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007277 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007278 Py_END_ALLOW_THREADS
7279
Larry Hastings2f936352014-08-05 14:04:04 +10007280 if (result)
7281 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007282#endif
7283
Larry Hastings2f936352014-08-05 14:04:04 +10007284 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007285}
7286#endif /* HAVE_SYMLINK */
7287
Larry Hastings9cf065c2012-06-22 16:30:09 -07007288
Brian Curtind40e6f72010-07-08 21:39:08 +00007289
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007290
Larry Hastings605a62d2012-06-24 04:33:36 -07007291static PyStructSequence_Field times_result_fields[] = {
7292 {"user", "user time"},
7293 {"system", "system time"},
7294 {"children_user", "user time of children"},
7295 {"children_system", "system time of children"},
7296 {"elapsed", "elapsed time since an arbitrary point in the past"},
7297 {NULL}
7298};
7299
7300PyDoc_STRVAR(times_result__doc__,
7301"times_result: Result from os.times().\n\n\
7302This object may be accessed either as a tuple of\n\
7303 (user, system, children_user, children_system, elapsed),\n\
7304or via the attributes user, system, children_user, children_system,\n\
7305and elapsed.\n\
7306\n\
7307See os.times for more information.");
7308
7309static PyStructSequence_Desc times_result_desc = {
7310 "times_result", /* name */
7311 times_result__doc__, /* doc */
7312 times_result_fields,
7313 5
7314};
7315
7316static PyTypeObject TimesResultType;
7317
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007318#ifdef MS_WINDOWS
7319#define HAVE_TIMES /* mandatory, for the method table */
7320#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007321
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007322#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007323
7324static PyObject *
7325build_times_result(double user, double system,
7326 double children_user, double children_system,
7327 double elapsed)
7328{
7329 PyObject *value = PyStructSequence_New(&TimesResultType);
7330 if (value == NULL)
7331 return NULL;
7332
7333#define SET(i, field) \
7334 { \
7335 PyObject *o = PyFloat_FromDouble(field); \
7336 if (!o) { \
7337 Py_DECREF(value); \
7338 return NULL; \
7339 } \
7340 PyStructSequence_SET_ITEM(value, i, o); \
7341 } \
7342
7343 SET(0, user);
7344 SET(1, system);
7345 SET(2, children_user);
7346 SET(3, children_system);
7347 SET(4, elapsed);
7348
7349#undef SET
7350
7351 return value;
7352}
7353
Larry Hastings605a62d2012-06-24 04:33:36 -07007354
Larry Hastings2f936352014-08-05 14:04:04 +10007355#ifndef MS_WINDOWS
7356#define NEED_TICKS_PER_SECOND
7357static long ticks_per_second = -1;
7358#endif /* MS_WINDOWS */
7359
7360/*[clinic input]
7361os.times
7362
7363Return a collection containing process timing information.
7364
7365The object returned behaves like a named tuple with these fields:
7366 (utime, stime, cutime, cstime, elapsed_time)
7367All fields are floating point numbers.
7368[clinic start generated code]*/
7369
Larry Hastings2f936352014-08-05 14:04:04 +10007370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007371os_times_impl(PyObject *module)
7372/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007373#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007374{
Victor Stinner8c62be82010-05-06 00:08:46 +00007375 FILETIME create, exit, kernel, user;
7376 HANDLE hProc;
7377 hProc = GetCurrentProcess();
7378 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7379 /* The fields of a FILETIME structure are the hi and lo part
7380 of a 64-bit value expressed in 100 nanosecond units.
7381 1e7 is one second in such units; 1e-7 the inverse.
7382 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7383 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007384 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007385 (double)(user.dwHighDateTime*429.4967296 +
7386 user.dwLowDateTime*1e-7),
7387 (double)(kernel.dwHighDateTime*429.4967296 +
7388 kernel.dwLowDateTime*1e-7),
7389 (double)0,
7390 (double)0,
7391 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007392}
Larry Hastings2f936352014-08-05 14:04:04 +10007393#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007394{
Larry Hastings2f936352014-08-05 14:04:04 +10007395
7396
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007397 struct tms t;
7398 clock_t c;
7399 errno = 0;
7400 c = times(&t);
7401 if (c == (clock_t) -1)
7402 return posix_error();
7403 return build_times_result(
7404 (double)t.tms_utime / ticks_per_second,
7405 (double)t.tms_stime / ticks_per_second,
7406 (double)t.tms_cutime / ticks_per_second,
7407 (double)t.tms_cstime / ticks_per_second,
7408 (double)c / ticks_per_second);
7409}
Larry Hastings2f936352014-08-05 14:04:04 +10007410#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007411#endif /* HAVE_TIMES */
7412
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007413
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007414#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007415/*[clinic input]
7416os.getsid
7417
7418 pid: pid_t
7419 /
7420
7421Call the system call getsid(pid) and return the result.
7422[clinic start generated code]*/
7423
Larry Hastings2f936352014-08-05 14:04:04 +10007424static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007425os_getsid_impl(PyObject *module, pid_t pid)
7426/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007427{
Victor Stinner8c62be82010-05-06 00:08:46 +00007428 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 sid = getsid(pid);
7430 if (sid < 0)
7431 return posix_error();
7432 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007433}
7434#endif /* HAVE_GETSID */
7435
7436
Guido van Rossumb6775db1994-08-01 11:34:53 +00007437#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007438/*[clinic input]
7439os.setsid
7440
7441Call the system call setsid().
7442[clinic start generated code]*/
7443
Larry Hastings2f936352014-08-05 14:04:04 +10007444static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007445os_setsid_impl(PyObject *module)
7446/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007447{
Victor Stinner8c62be82010-05-06 00:08:46 +00007448 if (setsid() < 0)
7449 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007450 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007451}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007452#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007453
Larry Hastings2f936352014-08-05 14:04:04 +10007454
Guido van Rossumb6775db1994-08-01 11:34:53 +00007455#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007456/*[clinic input]
7457os.setpgid
7458
7459 pid: pid_t
7460 pgrp: pid_t
7461 /
7462
7463Call the system call setpgid(pid, pgrp).
7464[clinic start generated code]*/
7465
Larry Hastings2f936352014-08-05 14:04:04 +10007466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007467os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7468/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007469{
Victor Stinner8c62be82010-05-06 00:08:46 +00007470 if (setpgid(pid, pgrp) < 0)
7471 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007472 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007473}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007474#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007476
Guido van Rossumb6775db1994-08-01 11:34:53 +00007477#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007478/*[clinic input]
7479os.tcgetpgrp
7480
7481 fd: int
7482 /
7483
7484Return the process group associated with the terminal specified by fd.
7485[clinic start generated code]*/
7486
Larry Hastings2f936352014-08-05 14:04:04 +10007487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007488os_tcgetpgrp_impl(PyObject *module, int fd)
7489/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007490{
7491 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007492 if (pgid < 0)
7493 return posix_error();
7494 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007495}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007496#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007498
Guido van Rossumb6775db1994-08-01 11:34:53 +00007499#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007500/*[clinic input]
7501os.tcsetpgrp
7502
7503 fd: int
7504 pgid: pid_t
7505 /
7506
7507Set the process group associated with the terminal specified by fd.
7508[clinic start generated code]*/
7509
Larry Hastings2f936352014-08-05 14:04:04 +10007510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007511os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7512/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007513{
Victor Stinner8c62be82010-05-06 00:08:46 +00007514 if (tcsetpgrp(fd, pgid) < 0)
7515 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007516 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007517}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007518#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007519
Guido van Rossum687dd131993-05-17 08:34:16 +00007520/* Functions acting on file descriptors */
7521
Victor Stinnerdaf45552013-08-28 00:53:59 +02007522#ifdef O_CLOEXEC
7523extern int _Py_open_cloexec_works;
7524#endif
7525
Larry Hastings2f936352014-08-05 14:04:04 +10007526
7527/*[clinic input]
7528os.open -> int
7529 path: path_t
7530 flags: int
7531 mode: int = 0o777
7532 *
7533 dir_fd: dir_fd(requires='openat') = None
7534
7535# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7536
7537Open a file for low level IO. Returns a file descriptor (integer).
7538
7539If dir_fd is not None, it should be a file descriptor open to a directory,
7540 and path should be relative; path will then be relative to that directory.
7541dir_fd may not be implemented on your platform.
7542 If it is unavailable, using it will raise a NotImplementedError.
7543[clinic start generated code]*/
7544
Larry Hastings2f936352014-08-05 14:04:04 +10007545static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007546os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7547/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007548{
7549 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007550 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007551
Victor Stinnerdaf45552013-08-28 00:53:59 +02007552#ifdef O_CLOEXEC
7553 int *atomic_flag_works = &_Py_open_cloexec_works;
7554#elif !defined(MS_WINDOWS)
7555 int *atomic_flag_works = NULL;
7556#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007557
Victor Stinnerdaf45552013-08-28 00:53:59 +02007558#ifdef MS_WINDOWS
7559 flags |= O_NOINHERIT;
7560#elif defined(O_CLOEXEC)
7561 flags |= O_CLOEXEC;
7562#endif
7563
Steve Dower8fc89802015-04-12 00:26:27 -04007564 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007565 do {
7566 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007567#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007568 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007569#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007570#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007571 if (dir_fd != DEFAULT_DIR_FD)
7572 fd = openat(dir_fd, path->narrow, flags, mode);
7573 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007574#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007575 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007576#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007577 Py_END_ALLOW_THREADS
7578 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007579 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007580
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007581 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007582 if (!async_err)
7583 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007584 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007585 }
7586
Victor Stinnerdaf45552013-08-28 00:53:59 +02007587#ifndef MS_WINDOWS
7588 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7589 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007590 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007591 }
7592#endif
7593
Larry Hastings2f936352014-08-05 14:04:04 +10007594 return fd;
7595}
7596
7597
7598/*[clinic input]
7599os.close
7600
7601 fd: int
7602
7603Close a file descriptor.
7604[clinic start generated code]*/
7605
Barry Warsaw53699e91996-12-10 23:23:01 +00007606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007607os_close_impl(PyObject *module, int fd)
7608/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007609{
Larry Hastings2f936352014-08-05 14:04:04 +10007610 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007611 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7612 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7613 * for more details.
7614 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007616 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007618 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 Py_END_ALLOW_THREADS
7620 if (res < 0)
7621 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007622 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007623}
7624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Larry Hastings2f936352014-08-05 14:04:04 +10007626/*[clinic input]
7627os.closerange
7628
7629 fd_low: int
7630 fd_high: int
7631 /
7632
7633Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7634[clinic start generated code]*/
7635
Larry Hastings2f936352014-08-05 14:04:04 +10007636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007637os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7638/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007639{
7640 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007642 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007643 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007644 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007645 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007646 Py_END_ALLOW_THREADS
7647 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007648}
7649
7650
Larry Hastings2f936352014-08-05 14:04:04 +10007651/*[clinic input]
7652os.dup -> int
7653
7654 fd: int
7655 /
7656
7657Return a duplicate of a file descriptor.
7658[clinic start generated code]*/
7659
Larry Hastings2f936352014-08-05 14:04:04 +10007660static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007661os_dup_impl(PyObject *module, int fd)
7662/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007663{
7664 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007665}
7666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007667
Larry Hastings2f936352014-08-05 14:04:04 +10007668/*[clinic input]
7669os.dup2
7670 fd: int
7671 fd2: int
7672 inheritable: bool=True
7673
7674Duplicate file descriptor.
7675[clinic start generated code]*/
7676
Larry Hastings2f936352014-08-05 14:04:04 +10007677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007678os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7679/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007680{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007681 int res;
7682#if defined(HAVE_DUP3) && \
7683 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7684 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7685 int dup3_works = -1;
7686#endif
7687
Steve Dower940f33a2016-09-08 11:21:54 -07007688 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007690
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007691 /* dup2() can fail with EINTR if the target FD is already open, because it
7692 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7693 * upon close(), and therefore below.
7694 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007695#ifdef MS_WINDOWS
7696 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007697 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007699 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007700 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 if (res < 0)
7702 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007703
7704 /* Character files like console cannot be make non-inheritable */
7705 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7706 close(fd2);
7707 return NULL;
7708 }
7709
7710#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7711 Py_BEGIN_ALLOW_THREADS
7712 if (!inheritable)
7713 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7714 else
7715 res = dup2(fd, fd2);
7716 Py_END_ALLOW_THREADS
7717 if (res < 0)
7718 return posix_error();
7719
7720#else
7721
7722#ifdef HAVE_DUP3
7723 if (!inheritable && dup3_works != 0) {
7724 Py_BEGIN_ALLOW_THREADS
7725 res = dup3(fd, fd2, O_CLOEXEC);
7726 Py_END_ALLOW_THREADS
7727 if (res < 0) {
7728 if (dup3_works == -1)
7729 dup3_works = (errno != ENOSYS);
7730 if (dup3_works)
7731 return posix_error();
7732 }
7733 }
7734
7735 if (inheritable || dup3_works == 0)
7736 {
7737#endif
7738 Py_BEGIN_ALLOW_THREADS
7739 res = dup2(fd, fd2);
7740 Py_END_ALLOW_THREADS
7741 if (res < 0)
7742 return posix_error();
7743
7744 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7745 close(fd2);
7746 return NULL;
7747 }
7748#ifdef HAVE_DUP3
7749 }
7750#endif
7751
7752#endif
7753
Larry Hastings2f936352014-08-05 14:04:04 +10007754 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007755}
7756
Larry Hastings2f936352014-08-05 14:04:04 +10007757
Ross Lagerwall7807c352011-03-17 20:20:30 +02007758#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007759/*[clinic input]
7760os.lockf
7761
7762 fd: int
7763 An open file descriptor.
7764 command: int
7765 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7766 length: Py_off_t
7767 The number of bytes to lock, starting at the current position.
7768 /
7769
7770Apply, test or remove a POSIX lock on an open file descriptor.
7771
7772[clinic start generated code]*/
7773
Larry Hastings2f936352014-08-05 14:04:04 +10007774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007775os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7776/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007777{
7778 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007779
7780 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007781 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007782 Py_END_ALLOW_THREADS
7783
7784 if (res < 0)
7785 return posix_error();
7786
7787 Py_RETURN_NONE;
7788}
Larry Hastings2f936352014-08-05 14:04:04 +10007789#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007791
Larry Hastings2f936352014-08-05 14:04:04 +10007792/*[clinic input]
7793os.lseek -> Py_off_t
7794
7795 fd: int
7796 position: Py_off_t
7797 how: int
7798 /
7799
7800Set the position of a file descriptor. Return the new position.
7801
7802Return the new cursor position in number of bytes
7803relative to the beginning of the file.
7804[clinic start generated code]*/
7805
Larry Hastings2f936352014-08-05 14:04:04 +10007806static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007807os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7808/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007809{
7810 Py_off_t result;
7811
Guido van Rossum687dd131993-05-17 08:34:16 +00007812#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7814 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007815 case 0: how = SEEK_SET; break;
7816 case 1: how = SEEK_CUR; break;
7817 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007819#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007820
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007822 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007823
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007825 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007826#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007827 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007828#else
Larry Hastings2f936352014-08-05 14:04:04 +10007829 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007830#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007831 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007833 if (result < 0)
7834 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007835
Larry Hastings2f936352014-08-05 14:04:04 +10007836 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007837}
7838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007839
Larry Hastings2f936352014-08-05 14:04:04 +10007840/*[clinic input]
7841os.read
7842 fd: int
7843 length: Py_ssize_t
7844 /
7845
7846Read from a file descriptor. Returns a bytes object.
7847[clinic start generated code]*/
7848
Larry Hastings2f936352014-08-05 14:04:04 +10007849static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007850os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7851/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007852{
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 Py_ssize_t n;
7854 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007855
7856 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 errno = EINVAL;
7858 return posix_error();
7859 }
Larry Hastings2f936352014-08-05 14:04:04 +10007860
7861#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007862 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007863 if (length > INT_MAX)
7864 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007865#endif
7866
7867 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 if (buffer == NULL)
7869 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007870
Victor Stinner66aab0c2015-03-19 22:53:20 +01007871 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7872 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007874 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 }
Larry Hastings2f936352014-08-05 14:04:04 +10007876
7877 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007879
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007881}
7882
Ross Lagerwall7807c352011-03-17 20:20:30 +02007883#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7884 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007885static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007886iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7887{
7888 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007889 Py_ssize_t blen, total = 0;
7890
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007891 *iov = PyMem_New(struct iovec, cnt);
7892 if (*iov == NULL) {
7893 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007894 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007895 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007896
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007897 *buf = PyMem_New(Py_buffer, cnt);
7898 if (*buf == NULL) {
7899 PyMem_Del(*iov);
7900 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007901 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007902 }
7903
7904 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007905 PyObject *item = PySequence_GetItem(seq, i);
7906 if (item == NULL)
7907 goto fail;
7908 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7909 Py_DECREF(item);
7910 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007911 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007912 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007913 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007914 blen = (*buf)[i].len;
7915 (*iov)[i].iov_len = blen;
7916 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007917 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007918 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007919
7920fail:
7921 PyMem_Del(*iov);
7922 for (j = 0; j < i; j++) {
7923 PyBuffer_Release(&(*buf)[j]);
7924 }
7925 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007926 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007927}
7928
7929static void
7930iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7931{
7932 int i;
7933 PyMem_Del(iov);
7934 for (i = 0; i < cnt; i++) {
7935 PyBuffer_Release(&buf[i]);
7936 }
7937 PyMem_Del(buf);
7938}
7939#endif
7940
Larry Hastings2f936352014-08-05 14:04:04 +10007941
Ross Lagerwall7807c352011-03-17 20:20:30 +02007942#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007943/*[clinic input]
7944os.readv -> Py_ssize_t
7945
7946 fd: int
7947 buffers: object
7948 /
7949
7950Read from a file descriptor fd into an iterable of buffers.
7951
7952The buffers should be mutable buffers accepting bytes.
7953readv will transfer data into each buffer until it is full
7954and then move on to the next buffer in the sequence to hold
7955the rest of the data.
7956
7957readv returns the total number of bytes read,
7958which may be less than the total capacity of all the buffers.
7959[clinic start generated code]*/
7960
Larry Hastings2f936352014-08-05 14:04:04 +10007961static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007962os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7963/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007964{
7965 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007966 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007967 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007968 struct iovec *iov;
7969 Py_buffer *buf;
7970
Larry Hastings2f936352014-08-05 14:04:04 +10007971 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972 PyErr_SetString(PyExc_TypeError,
7973 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007974 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007975 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007976
Larry Hastings2f936352014-08-05 14:04:04 +10007977 cnt = PySequence_Size(buffers);
7978
7979 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7980 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007981
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007982 do {
7983 Py_BEGIN_ALLOW_THREADS
7984 n = readv(fd, iov, cnt);
7985 Py_END_ALLOW_THREADS
7986 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007987
7988 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007989 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007990 if (!async_err)
7991 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007992 return -1;
7993 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007994
Larry Hastings2f936352014-08-05 14:04:04 +10007995 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007996}
Larry Hastings2f936352014-08-05 14:04:04 +10007997#endif /* HAVE_READV */
7998
Ross Lagerwall7807c352011-03-17 20:20:30 +02007999
8000#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008001/*[clinic input]
8002# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8003os.pread
8004
8005 fd: int
8006 length: int
8007 offset: Py_off_t
8008 /
8009
8010Read a number of bytes from a file descriptor starting at a particular offset.
8011
8012Read length bytes from file descriptor fd, starting at offset bytes from
8013the beginning of the file. The file offset remains unchanged.
8014[clinic start generated code]*/
8015
Larry Hastings2f936352014-08-05 14:04:04 +10008016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008017os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8018/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008019{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008020 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008021 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008022 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023
Larry Hastings2f936352014-08-05 14:04:04 +10008024 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008025 errno = EINVAL;
8026 return posix_error();
8027 }
Larry Hastings2f936352014-08-05 14:04:04 +10008028 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008029 if (buffer == NULL)
8030 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008031
8032 do {
8033 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008034 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008035 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008036 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008037 Py_END_ALLOW_THREADS
8038 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8039
Ross Lagerwall7807c352011-03-17 20:20:30 +02008040 if (n < 0) {
8041 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008042 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008043 }
Larry Hastings2f936352014-08-05 14:04:04 +10008044 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008045 _PyBytes_Resize(&buffer, n);
8046 return buffer;
8047}
Larry Hastings2f936352014-08-05 14:04:04 +10008048#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008049
Larry Hastings2f936352014-08-05 14:04:04 +10008050
8051/*[clinic input]
8052os.write -> Py_ssize_t
8053
8054 fd: int
8055 data: Py_buffer
8056 /
8057
8058Write a bytes object to a file descriptor.
8059[clinic start generated code]*/
8060
Larry Hastings2f936352014-08-05 14:04:04 +10008061static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008062os_write_impl(PyObject *module, int fd, Py_buffer *data)
8063/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008064{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008065 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008066}
8067
8068#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008069PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008070"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008071sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008073Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074
Larry Hastings2f936352014-08-05 14:04:04 +10008075/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008076static PyObject *
8077posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8078{
8079 int in, out;
8080 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008081 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008082 off_t offset;
8083
8084#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8085#ifndef __APPLE__
8086 Py_ssize_t len;
8087#endif
8088 PyObject *headers = NULL, *trailers = NULL;
8089 Py_buffer *hbuf, *tbuf;
8090 off_t sbytes;
8091 struct sf_hdtr sf;
8092 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008093 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008094 static char *keywords[] = {"out", "in",
8095 "offset", "count",
8096 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008097
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008098 sf.headers = NULL;
8099 sf.trailers = NULL;
8100
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008101#ifdef __APPLE__
8102 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008103 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104#else
8105 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008106 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008107#endif
8108 &headers, &trailers, &flags))
8109 return NULL;
8110 if (headers != NULL) {
8111 if (!PySequence_Check(headers)) {
8112 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008113 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008114 return NULL;
8115 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008116 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008117 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008118 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008119 (i = iov_setup(&(sf.headers), &hbuf,
8120 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008121 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008122#ifdef __APPLE__
8123 sbytes += i;
8124#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008125 }
8126 }
8127 if (trailers != NULL) {
8128 if (!PySequence_Check(trailers)) {
8129 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008130 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008131 return NULL;
8132 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008133 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008134 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008135 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008136 (i = iov_setup(&(sf.trailers), &tbuf,
8137 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008138 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008139#ifdef __APPLE__
8140 sbytes += i;
8141#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008142 }
8143 }
8144
Steve Dower8fc89802015-04-12 00:26:27 -04008145 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008146 do {
8147 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008148#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008150#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008151 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008152#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008153 Py_END_ALLOW_THREADS
8154 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008155 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008156
8157 if (sf.headers != NULL)
8158 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8159 if (sf.trailers != NULL)
8160 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8161
8162 if (ret < 0) {
8163 if ((errno == EAGAIN) || (errno == EBUSY)) {
8164 if (sbytes != 0) {
8165 // some data has been sent
8166 goto done;
8167 }
8168 else {
8169 // no data has been sent; upper application is supposed
8170 // to retry on EAGAIN or EBUSY
8171 return posix_error();
8172 }
8173 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008174 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008175 }
8176 goto done;
8177
8178done:
8179 #if !defined(HAVE_LARGEFILE_SUPPORT)
8180 return Py_BuildValue("l", sbytes);
8181 #else
8182 return Py_BuildValue("L", sbytes);
8183 #endif
8184
8185#else
8186 Py_ssize_t count;
8187 PyObject *offobj;
8188 static char *keywords[] = {"out", "in",
8189 "offset", "count", NULL};
8190 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8191 keywords, &out, &in, &offobj, &count))
8192 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008193#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008194 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008195 do {
8196 Py_BEGIN_ALLOW_THREADS
8197 ret = sendfile(out, in, NULL, count);
8198 Py_END_ALLOW_THREADS
8199 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008200 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008201 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008202 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008203 }
8204#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008205 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008206 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008207
8208 do {
8209 Py_BEGIN_ALLOW_THREADS
8210 ret = sendfile(out, in, &offset, count);
8211 Py_END_ALLOW_THREADS
8212 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008213 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008214 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008215 return Py_BuildValue("n", ret);
8216#endif
8217}
Larry Hastings2f936352014-08-05 14:04:04 +10008218#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008219
Larry Hastings2f936352014-08-05 14:04:04 +10008220
8221/*[clinic input]
8222os.fstat
8223
8224 fd : int
8225
8226Perform a stat system call on the given file descriptor.
8227
8228Like stat(), but for an open file descriptor.
8229Equivalent to os.stat(fd).
8230[clinic start generated code]*/
8231
Larry Hastings2f936352014-08-05 14:04:04 +10008232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008233os_fstat_impl(PyObject *module, int fd)
8234/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008235{
Victor Stinner8c62be82010-05-06 00:08:46 +00008236 STRUCT_STAT st;
8237 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008238 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008239
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008240 do {
8241 Py_BEGIN_ALLOW_THREADS
8242 res = FSTAT(fd, &st);
8243 Py_END_ALLOW_THREADS
8244 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008246#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008247 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008248#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008249 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008250#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008251 }
Tim Peters5aa91602002-01-30 05:46:57 +00008252
Victor Stinner4195b5c2012-02-08 23:03:19 +01008253 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008254}
8255
Larry Hastings2f936352014-08-05 14:04:04 +10008256
8257/*[clinic input]
8258os.isatty -> bool
8259 fd: int
8260 /
8261
8262Return True if the fd is connected to a terminal.
8263
8264Return True if the file descriptor is an open file descriptor
8265connected to the slave end of a terminal.
8266[clinic start generated code]*/
8267
Larry Hastings2f936352014-08-05 14:04:04 +10008268static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008269os_isatty_impl(PyObject *module, int fd)
8270/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008271{
Steve Dower8fc89802015-04-12 00:26:27 -04008272 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008273 _Py_BEGIN_SUPPRESS_IPH
8274 return_value = isatty(fd);
8275 _Py_END_SUPPRESS_IPH
8276 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008277}
8278
8279
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008280#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008281/*[clinic input]
8282os.pipe
8283
8284Create a pipe.
8285
8286Returns a tuple of two file descriptors:
8287 (read_fd, write_fd)
8288[clinic start generated code]*/
8289
Larry Hastings2f936352014-08-05 14:04:04 +10008290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008291os_pipe_impl(PyObject *module)
8292/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008293{
Victor Stinner8c62be82010-05-06 00:08:46 +00008294 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008295#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008297 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008298 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008299#else
8300 int res;
8301#endif
8302
8303#ifdef MS_WINDOWS
8304 attr.nLength = sizeof(attr);
8305 attr.lpSecurityDescriptor = NULL;
8306 attr.bInheritHandle = FALSE;
8307
8308 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008309 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008310 ok = CreatePipe(&read, &write, &attr, 0);
8311 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008312 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8313 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008314 if (fds[0] == -1 || fds[1] == -1) {
8315 CloseHandle(read);
8316 CloseHandle(write);
8317 ok = 0;
8318 }
8319 }
Steve Dowerc3630612016-11-19 18:41:16 -08008320 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008321 Py_END_ALLOW_THREADS
8322
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008324 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008325#else
8326
8327#ifdef HAVE_PIPE2
8328 Py_BEGIN_ALLOW_THREADS
8329 res = pipe2(fds, O_CLOEXEC);
8330 Py_END_ALLOW_THREADS
8331
8332 if (res != 0 && errno == ENOSYS)
8333 {
8334#endif
8335 Py_BEGIN_ALLOW_THREADS
8336 res = pipe(fds);
8337 Py_END_ALLOW_THREADS
8338
8339 if (res == 0) {
8340 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8341 close(fds[0]);
8342 close(fds[1]);
8343 return NULL;
8344 }
8345 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8346 close(fds[0]);
8347 close(fds[1]);
8348 return NULL;
8349 }
8350 }
8351#ifdef HAVE_PIPE2
8352 }
8353#endif
8354
8355 if (res != 0)
8356 return PyErr_SetFromErrno(PyExc_OSError);
8357#endif /* !MS_WINDOWS */
8358 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008359}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008360#endif /* HAVE_PIPE */
8361
Larry Hastings2f936352014-08-05 14:04:04 +10008362
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008363#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008364/*[clinic input]
8365os.pipe2
8366
8367 flags: int
8368 /
8369
8370Create a pipe with flags set atomically.
8371
8372Returns a tuple of two file descriptors:
8373 (read_fd, write_fd)
8374
8375flags can be constructed by ORing together one or more of these values:
8376O_NONBLOCK, O_CLOEXEC.
8377[clinic start generated code]*/
8378
Larry Hastings2f936352014-08-05 14:04:04 +10008379static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008380os_pipe2_impl(PyObject *module, int flags)
8381/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008382{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008383 int fds[2];
8384 int res;
8385
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008386 res = pipe2(fds, flags);
8387 if (res != 0)
8388 return posix_error();
8389 return Py_BuildValue("(ii)", fds[0], fds[1]);
8390}
8391#endif /* HAVE_PIPE2 */
8392
Larry Hastings2f936352014-08-05 14:04:04 +10008393
Ross Lagerwall7807c352011-03-17 20:20:30 +02008394#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008395/*[clinic input]
8396os.writev -> Py_ssize_t
8397 fd: int
8398 buffers: object
8399 /
8400
8401Iterate over buffers, and write the contents of each to a file descriptor.
8402
8403Returns the total number of bytes written.
8404buffers must be a sequence of bytes-like objects.
8405[clinic start generated code]*/
8406
Larry Hastings2f936352014-08-05 14:04:04 +10008407static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008408os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8409/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008410{
8411 int cnt;
8412 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008413 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008414 struct iovec *iov;
8415 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008416
8417 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008418 PyErr_SetString(PyExc_TypeError,
8419 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008420 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008421 }
Larry Hastings2f936352014-08-05 14:04:04 +10008422 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008423
Larry Hastings2f936352014-08-05 14:04:04 +10008424 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8425 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008426 }
8427
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008428 do {
8429 Py_BEGIN_ALLOW_THREADS
8430 result = writev(fd, iov, cnt);
8431 Py_END_ALLOW_THREADS
8432 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008433
8434 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008435 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008436 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008437
Georg Brandl306336b2012-06-24 12:55:33 +02008438 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008439}
Larry Hastings2f936352014-08-05 14:04:04 +10008440#endif /* HAVE_WRITEV */
8441
8442
8443#ifdef HAVE_PWRITE
8444/*[clinic input]
8445os.pwrite -> Py_ssize_t
8446
8447 fd: int
8448 buffer: Py_buffer
8449 offset: Py_off_t
8450 /
8451
8452Write bytes to a file descriptor starting at a particular offset.
8453
8454Write buffer to fd, starting at offset bytes from the beginning of
8455the file. Returns the number of bytes writte. Does not change the
8456current file offset.
8457[clinic start generated code]*/
8458
Larry Hastings2f936352014-08-05 14:04:04 +10008459static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008460os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8461/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008462{
8463 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008464 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008465
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008466 do {
8467 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008468 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008469 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008470 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008471 Py_END_ALLOW_THREADS
8472 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008473
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008474 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008475 posix_error();
8476 return size;
8477}
8478#endif /* HAVE_PWRITE */
8479
8480
8481#ifdef HAVE_MKFIFO
8482/*[clinic input]
8483os.mkfifo
8484
8485 path: path_t
8486 mode: int=0o666
8487 *
8488 dir_fd: dir_fd(requires='mkfifoat')=None
8489
8490Create a "fifo" (a POSIX named pipe).
8491
8492If dir_fd is not None, it should be a file descriptor open to a directory,
8493 and path should be relative; path will then be relative to that directory.
8494dir_fd may not be implemented on your platform.
8495 If it is unavailable, using it will raise a NotImplementedError.
8496[clinic start generated code]*/
8497
Larry Hastings2f936352014-08-05 14:04:04 +10008498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008499os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8500/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008501{
8502 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008503 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008504
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008505 do {
8506 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008507#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008508 if (dir_fd != DEFAULT_DIR_FD)
8509 result = mkfifoat(dir_fd, path->narrow, mode);
8510 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008511#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008512 result = mkfifo(path->narrow, mode);
8513 Py_END_ALLOW_THREADS
8514 } while (result != 0 && errno == EINTR &&
8515 !(async_err = PyErr_CheckSignals()));
8516 if (result != 0)
8517 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008518
8519 Py_RETURN_NONE;
8520}
8521#endif /* HAVE_MKFIFO */
8522
8523
8524#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8525/*[clinic input]
8526os.mknod
8527
8528 path: path_t
8529 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008530 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008531 *
8532 dir_fd: dir_fd(requires='mknodat')=None
8533
8534Create a node in the file system.
8535
8536Create a node in the file system (file, device special file or named pipe)
8537at path. mode specifies both the permissions to use and the
8538type of node to be created, being combined (bitwise OR) with one of
8539S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8540device defines the newly created device special file (probably using
8541os.makedev()). Otherwise device is ignored.
8542
8543If dir_fd is not None, it should be a file descriptor open to a directory,
8544 and path should be relative; path will then be relative to that directory.
8545dir_fd may not be implemented on your platform.
8546 If it is unavailable, using it will raise a NotImplementedError.
8547[clinic start generated code]*/
8548
Larry Hastings2f936352014-08-05 14:04:04 +10008549static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008550os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008551 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008552/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008553{
8554 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008555 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008556
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008557 do {
8558 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008559#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008560 if (dir_fd != DEFAULT_DIR_FD)
8561 result = mknodat(dir_fd, path->narrow, mode, device);
8562 else
Larry Hastings2f936352014-08-05 14:04:04 +10008563#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008564 result = mknod(path->narrow, mode, device);
8565 Py_END_ALLOW_THREADS
8566 } while (result != 0 && errno == EINTR &&
8567 !(async_err = PyErr_CheckSignals()));
8568 if (result != 0)
8569 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008570
8571 Py_RETURN_NONE;
8572}
8573#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8574
8575
8576#ifdef HAVE_DEVICE_MACROS
8577/*[clinic input]
8578os.major -> unsigned_int
8579
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008580 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008581 /
8582
8583Extracts a device major number from a raw device number.
8584[clinic start generated code]*/
8585
Larry Hastings2f936352014-08-05 14:04:04 +10008586static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008587os_major_impl(PyObject *module, dev_t device)
8588/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008589{
8590 return major(device);
8591}
8592
8593
8594/*[clinic input]
8595os.minor -> unsigned_int
8596
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008597 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008598 /
8599
8600Extracts a device minor number from a raw device number.
8601[clinic start generated code]*/
8602
Larry Hastings2f936352014-08-05 14:04:04 +10008603static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008604os_minor_impl(PyObject *module, dev_t device)
8605/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008606{
8607 return minor(device);
8608}
8609
8610
8611/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008612os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008613
8614 major: int
8615 minor: int
8616 /
8617
8618Composes a raw device number from the major and minor device numbers.
8619[clinic start generated code]*/
8620
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008621static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008622os_makedev_impl(PyObject *module, int major, int minor)
8623/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008624{
8625 return makedev(major, minor);
8626}
8627#endif /* HAVE_DEVICE_MACROS */
8628
8629
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008630#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008631/*[clinic input]
8632os.ftruncate
8633
8634 fd: int
8635 length: Py_off_t
8636 /
8637
8638Truncate a file, specified by file descriptor, to a specific length.
8639[clinic start generated code]*/
8640
Larry Hastings2f936352014-08-05 14:04:04 +10008641static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008642os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8643/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008644{
8645 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008646 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008647
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 do {
8649 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008650 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008651#ifdef MS_WINDOWS
8652 result = _chsize_s(fd, length);
8653#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008654 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008655#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008656 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008657 Py_END_ALLOW_THREADS
8658 } while (result != 0 && errno == EINTR &&
8659 !(async_err = PyErr_CheckSignals()));
8660 if (result != 0)
8661 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008662 Py_RETURN_NONE;
8663}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008664#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008665
8666
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008667#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008668/*[clinic input]
8669os.truncate
8670 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8671 length: Py_off_t
8672
8673Truncate a file, specified by path, to a specific length.
8674
8675On some platforms, path may also be specified as an open file descriptor.
8676 If this functionality is unavailable, using it raises an exception.
8677[clinic start generated code]*/
8678
Larry Hastings2f936352014-08-05 14:04:04 +10008679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008680os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8681/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008682{
8683 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008684#ifdef MS_WINDOWS
8685 int fd;
8686#endif
8687
8688 if (path->fd != -1)
8689 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008690
8691 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008692 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008693#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008694 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008695 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008696 result = -1;
8697 else {
8698 result = _chsize_s(fd, length);
8699 close(fd);
8700 if (result < 0)
8701 errno = result;
8702 }
8703#else
8704 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008705#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008706 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008707 Py_END_ALLOW_THREADS
8708 if (result < 0)
8709 return path_error(path);
8710
8711 Py_RETURN_NONE;
8712}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008713#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008714
Ross Lagerwall7807c352011-03-17 20:20:30 +02008715
Victor Stinnerd6b17692014-09-30 12:20:05 +02008716/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8717 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8718 defined, which is the case in Python on AIX. AIX bug report:
8719 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8720#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8721# define POSIX_FADVISE_AIX_BUG
8722#endif
8723
Victor Stinnerec39e262014-09-30 12:35:58 +02008724
Victor Stinnerd6b17692014-09-30 12:20:05 +02008725#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008726/*[clinic input]
8727os.posix_fallocate
8728
8729 fd: int
8730 offset: Py_off_t
8731 length: Py_off_t
8732 /
8733
8734Ensure a file has allocated at least a particular number of bytes on disk.
8735
8736Ensure that the file specified by fd encompasses a range of bytes
8737starting at offset bytes from the beginning and continuing for length bytes.
8738[clinic start generated code]*/
8739
Larry Hastings2f936352014-08-05 14:04:04 +10008740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008741os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008742 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008743/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008744{
8745 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008746 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008747
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008748 do {
8749 Py_BEGIN_ALLOW_THREADS
8750 result = posix_fallocate(fd, offset, length);
8751 Py_END_ALLOW_THREADS
8752 } while (result != 0 && errno == EINTR &&
8753 !(async_err = PyErr_CheckSignals()));
8754 if (result != 0)
8755 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008756 Py_RETURN_NONE;
8757}
Victor Stinnerec39e262014-09-30 12:35:58 +02008758#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008759
Ross Lagerwall7807c352011-03-17 20:20:30 +02008760
Victor Stinnerd6b17692014-09-30 12:20:05 +02008761#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008762/*[clinic input]
8763os.posix_fadvise
8764
8765 fd: int
8766 offset: Py_off_t
8767 length: Py_off_t
8768 advice: int
8769 /
8770
8771Announce an intention to access data in a specific pattern.
8772
8773Announce an intention to access data in a specific pattern, thus allowing
8774the kernel to make optimizations.
8775The advice applies to the region of the file specified by fd starting at
8776offset and continuing for length bytes.
8777advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8778POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8779POSIX_FADV_DONTNEED.
8780[clinic start generated code]*/
8781
Larry Hastings2f936352014-08-05 14:04:04 +10008782static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008783os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008784 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008785/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008786{
8787 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008788 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008789
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008790 do {
8791 Py_BEGIN_ALLOW_THREADS
8792 result = posix_fadvise(fd, offset, length, advice);
8793 Py_END_ALLOW_THREADS
8794 } while (result != 0 && errno == EINTR &&
8795 !(async_err = PyErr_CheckSignals()));
8796 if (result != 0)
8797 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008798 Py_RETURN_NONE;
8799}
Victor Stinnerec39e262014-09-30 12:35:58 +02008800#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008801
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008802#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008803
Fred Drake762e2061999-08-26 17:23:54 +00008804/* Save putenv() parameters as values here, so we can collect them when they
8805 * get re-set with another call for the same key. */
8806static PyObject *posix_putenv_garbage;
8807
Larry Hastings2f936352014-08-05 14:04:04 +10008808static void
8809posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008810{
Larry Hastings2f936352014-08-05 14:04:04 +10008811 /* Install the first arg and newstr in posix_putenv_garbage;
8812 * this will cause previous value to be collected. This has to
8813 * happen after the real putenv() call because the old value
8814 * was still accessible until then. */
8815 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8816 /* really not much we can do; just leak */
8817 PyErr_Clear();
8818 else
8819 Py_DECREF(value);
8820}
8821
8822
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008823#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008824/*[clinic input]
8825os.putenv
8826
8827 name: unicode
8828 value: unicode
8829 /
8830
8831Change or add an environment variable.
8832[clinic start generated code]*/
8833
Larry Hastings2f936352014-08-05 14:04:04 +10008834static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008835os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8836/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008837{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008838 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008839
8840 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8841 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008842 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008843 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008844 }
Larry Hastings2f936352014-08-05 14:04:04 +10008845 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008846 PyErr_Format(PyExc_ValueError,
8847 "the environment variable is longer than %u characters",
8848 _MAX_ENV);
8849 goto error;
8850 }
8851
Larry Hastings2f936352014-08-05 14:04:04 +10008852 env = PyUnicode_AsUnicode(unicode);
8853 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008854 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008855 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008857 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008859
Larry Hastings2f936352014-08-05 14:04:04 +10008860 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008861 Py_RETURN_NONE;
8862
8863error:
Larry Hastings2f936352014-08-05 14:04:04 +10008864 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008865 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008866}
Larry Hastings2f936352014-08-05 14:04:04 +10008867#else /* MS_WINDOWS */
8868/*[clinic input]
8869os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008870
Larry Hastings2f936352014-08-05 14:04:04 +10008871 name: FSConverter
8872 value: FSConverter
8873 /
8874
8875Change or add an environment variable.
8876[clinic start generated code]*/
8877
Larry Hastings2f936352014-08-05 14:04:04 +10008878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008879os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8880/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008881{
8882 PyObject *bytes = NULL;
8883 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008884 const char *name_string = PyBytes_AsString(name);
8885 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008886
8887 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8888 if (bytes == NULL) {
8889 PyErr_NoMemory();
8890 return NULL;
8891 }
8892
8893 env = PyBytes_AS_STRING(bytes);
8894 if (putenv(env)) {
8895 Py_DECREF(bytes);
8896 return posix_error();
8897 }
8898
8899 posix_putenv_garbage_setitem(name, bytes);
8900 Py_RETURN_NONE;
8901}
8902#endif /* MS_WINDOWS */
8903#endif /* HAVE_PUTENV */
8904
8905
8906#ifdef HAVE_UNSETENV
8907/*[clinic input]
8908os.unsetenv
8909 name: FSConverter
8910 /
8911
8912Delete an environment variable.
8913[clinic start generated code]*/
8914
Larry Hastings2f936352014-08-05 14:04:04 +10008915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008916os_unsetenv_impl(PyObject *module, PyObject *name)
8917/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008918{
Victor Stinner984890f2011-11-24 13:53:38 +01008919#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008920 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008921#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008922
Victor Stinner984890f2011-11-24 13:53:38 +01008923#ifdef HAVE_BROKEN_UNSETENV
8924 unsetenv(PyBytes_AS_STRING(name));
8925#else
Victor Stinner65170952011-11-22 22:16:17 +01008926 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008927 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008928 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008929#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008930
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 /* Remove the key from posix_putenv_garbage;
8932 * this will cause it to be collected. This has to
8933 * happen after the real unsetenv() call because the
8934 * old value was still accessible until then.
8935 */
Victor Stinner65170952011-11-22 22:16:17 +01008936 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 /* really not much we can do; just leak */
8938 PyErr_Clear();
8939 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008940 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008941}
Larry Hastings2f936352014-08-05 14:04:04 +10008942#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008943
Larry Hastings2f936352014-08-05 14:04:04 +10008944
8945/*[clinic input]
8946os.strerror
8947
8948 code: int
8949 /
8950
8951Translate an error code to a message string.
8952[clinic start generated code]*/
8953
Larry Hastings2f936352014-08-05 14:04:04 +10008954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008955os_strerror_impl(PyObject *module, int code)
8956/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008957{
8958 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 if (message == NULL) {
8960 PyErr_SetString(PyExc_ValueError,
8961 "strerror() argument out of range");
8962 return NULL;
8963 }
Victor Stinner1b579672011-12-17 05:47:23 +01008964 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008965}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008966
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008967
Guido van Rossumc9641791998-08-04 15:26:23 +00008968#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008969#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008970/*[clinic input]
8971os.WCOREDUMP -> bool
8972
8973 status: int
8974 /
8975
8976Return True if the process returning status was dumped to a core file.
8977[clinic start generated code]*/
8978
Larry Hastings2f936352014-08-05 14:04:04 +10008979static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008980os_WCOREDUMP_impl(PyObject *module, int status)
8981/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008982{
8983 WAIT_TYPE wait_status;
8984 WAIT_STATUS_INT(wait_status) = status;
8985 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008986}
8987#endif /* WCOREDUMP */
8988
Larry Hastings2f936352014-08-05 14:04:04 +10008989
Fred Drake106c1a02002-04-23 15:58:02 +00008990#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008991/*[clinic input]
8992os.WIFCONTINUED -> bool
8993
8994 status: int
8995
8996Return True if a particular process was continued from a job control stop.
8997
8998Return True if the process returning status was continued from a
8999job control stop.
9000[clinic start generated code]*/
9001
Larry Hastings2f936352014-08-05 14:04:04 +10009002static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009003os_WIFCONTINUED_impl(PyObject *module, int status)
9004/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009005{
9006 WAIT_TYPE wait_status;
9007 WAIT_STATUS_INT(wait_status) = status;
9008 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009009}
9010#endif /* WIFCONTINUED */
9011
Larry Hastings2f936352014-08-05 14:04:04 +10009012
Guido van Rossumc9641791998-08-04 15:26:23 +00009013#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009014/*[clinic input]
9015os.WIFSTOPPED -> bool
9016
9017 status: int
9018
9019Return True if the process returning status was stopped.
9020[clinic start generated code]*/
9021
Larry Hastings2f936352014-08-05 14:04:04 +10009022static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009023os_WIFSTOPPED_impl(PyObject *module, int status)
9024/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009025{
9026 WAIT_TYPE wait_status;
9027 WAIT_STATUS_INT(wait_status) = status;
9028 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009029}
9030#endif /* WIFSTOPPED */
9031
Larry Hastings2f936352014-08-05 14:04:04 +10009032
Guido van Rossumc9641791998-08-04 15:26:23 +00009033#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009034/*[clinic input]
9035os.WIFSIGNALED -> bool
9036
9037 status: int
9038
9039Return True if the process returning status was terminated by a signal.
9040[clinic start generated code]*/
9041
Larry Hastings2f936352014-08-05 14:04:04 +10009042static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009043os_WIFSIGNALED_impl(PyObject *module, int status)
9044/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009045{
9046 WAIT_TYPE wait_status;
9047 WAIT_STATUS_INT(wait_status) = status;
9048 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009049}
9050#endif /* WIFSIGNALED */
9051
Larry Hastings2f936352014-08-05 14:04:04 +10009052
Guido van Rossumc9641791998-08-04 15:26:23 +00009053#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009054/*[clinic input]
9055os.WIFEXITED -> bool
9056
9057 status: int
9058
9059Return True if the process returning status exited via the exit() system call.
9060[clinic start generated code]*/
9061
Larry Hastings2f936352014-08-05 14:04:04 +10009062static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009063os_WIFEXITED_impl(PyObject *module, int status)
9064/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009065{
9066 WAIT_TYPE wait_status;
9067 WAIT_STATUS_INT(wait_status) = status;
9068 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009069}
9070#endif /* WIFEXITED */
9071
Larry Hastings2f936352014-08-05 14:04:04 +10009072
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009073#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009074/*[clinic input]
9075os.WEXITSTATUS -> int
9076
9077 status: int
9078
9079Return the process return code from status.
9080[clinic start generated code]*/
9081
Larry Hastings2f936352014-08-05 14:04:04 +10009082static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009083os_WEXITSTATUS_impl(PyObject *module, int status)
9084/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009085{
9086 WAIT_TYPE wait_status;
9087 WAIT_STATUS_INT(wait_status) = status;
9088 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009089}
9090#endif /* WEXITSTATUS */
9091
Larry Hastings2f936352014-08-05 14:04:04 +10009092
Guido van Rossumc9641791998-08-04 15:26:23 +00009093#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009094/*[clinic input]
9095os.WTERMSIG -> int
9096
9097 status: int
9098
9099Return the signal that terminated the process that provided the status value.
9100[clinic start generated code]*/
9101
Larry Hastings2f936352014-08-05 14:04:04 +10009102static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009103os_WTERMSIG_impl(PyObject *module, int status)
9104/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009105{
9106 WAIT_TYPE wait_status;
9107 WAIT_STATUS_INT(wait_status) = status;
9108 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009109}
9110#endif /* WTERMSIG */
9111
Larry Hastings2f936352014-08-05 14:04:04 +10009112
Guido van Rossumc9641791998-08-04 15:26:23 +00009113#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009114/*[clinic input]
9115os.WSTOPSIG -> int
9116
9117 status: int
9118
9119Return the signal that stopped the process that provided the status value.
9120[clinic start generated code]*/
9121
Larry Hastings2f936352014-08-05 14:04:04 +10009122static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009123os_WSTOPSIG_impl(PyObject *module, int status)
9124/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009125{
9126 WAIT_TYPE wait_status;
9127 WAIT_STATUS_INT(wait_status) = status;
9128 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009129}
9130#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009131#endif /* HAVE_SYS_WAIT_H */
9132
9133
Thomas Wouters477c8d52006-05-27 19:21:47 +00009134#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009135#ifdef _SCO_DS
9136/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9137 needed definitions in sys/statvfs.h */
9138#define _SVID3
9139#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009140#include <sys/statvfs.h>
9141
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009142static PyObject*
9143_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9145 if (v == NULL)
9146 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009147
9148#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9150 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9151 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9152 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9153 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9154 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9155 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9156 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9157 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9158 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9161 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9162 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009163 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009165 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009167 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009169 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009170 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009171 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009172 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009173 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9175 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009176#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009177 if (PyErr_Occurred()) {
9178 Py_DECREF(v);
9179 return NULL;
9180 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009181
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009183}
9184
Larry Hastings2f936352014-08-05 14:04:04 +10009185
9186/*[clinic input]
9187os.fstatvfs
9188 fd: int
9189 /
9190
9191Perform an fstatvfs system call on the given fd.
9192
9193Equivalent to statvfs(fd).
9194[clinic start generated code]*/
9195
Larry Hastings2f936352014-08-05 14:04:04 +10009196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009197os_fstatvfs_impl(PyObject *module, int fd)
9198/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009199{
9200 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009201 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009203
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009204 do {
9205 Py_BEGIN_ALLOW_THREADS
9206 result = fstatvfs(fd, &st);
9207 Py_END_ALLOW_THREADS
9208 } while (result != 0 && errno == EINTR &&
9209 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009210 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009211 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009212
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009214}
Larry Hastings2f936352014-08-05 14:04:04 +10009215#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009216
9217
Thomas Wouters477c8d52006-05-27 19:21:47 +00009218#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009219#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009220/*[clinic input]
9221os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009222
Larry Hastings2f936352014-08-05 14:04:04 +10009223 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9224
9225Perform a statvfs system call on the given path.
9226
9227path may always be specified as a string.
9228On some platforms, path may also be specified as an open file descriptor.
9229 If this functionality is unavailable, using it raises an exception.
9230[clinic start generated code]*/
9231
Larry Hastings2f936352014-08-05 14:04:04 +10009232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009233os_statvfs_impl(PyObject *module, path_t *path)
9234/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009235{
9236 int result;
9237 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009238
9239 Py_BEGIN_ALLOW_THREADS
9240#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009241 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009242#ifdef __APPLE__
9243 /* handle weak-linking on Mac OS X 10.3 */
9244 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009245 fd_specified("statvfs", path->fd);
9246 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009247 }
9248#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009249 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009250 }
9251 else
9252#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009253 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009254 Py_END_ALLOW_THREADS
9255
9256 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009257 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009258 }
9259
Larry Hastings2f936352014-08-05 14:04:04 +10009260 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009261}
Larry Hastings2f936352014-08-05 14:04:04 +10009262#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9263
Guido van Rossum94f6f721999-01-06 18:42:14 +00009264
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009265#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009266/*[clinic input]
9267os._getdiskusage
9268
9269 path: Py_UNICODE
9270
9271Return disk usage statistics about the given path as a (total, free) tuple.
9272[clinic start generated code]*/
9273
Larry Hastings2f936352014-08-05 14:04:04 +10009274static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009275os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9276/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009277{
9278 BOOL retval;
9279 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009280
9281 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009282 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009283 Py_END_ALLOW_THREADS
9284 if (retval == 0)
9285 return PyErr_SetFromWindowsErr(0);
9286
9287 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9288}
Larry Hastings2f936352014-08-05 14:04:04 +10009289#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009290
9291
Fred Drakec9680921999-12-13 16:37:25 +00009292/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9293 * It maps strings representing configuration variable names to
9294 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009295 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009296 * rarely-used constants. There are three separate tables that use
9297 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009298 *
9299 * This code is always included, even if none of the interfaces that
9300 * need it are included. The #if hackery needed to avoid it would be
9301 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009302 */
9303struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009304 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009305 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009306};
9307
Fred Drake12c6e2d1999-12-14 21:25:03 +00009308static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009309conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009310 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009311{
Christian Heimes217cfd12007-12-02 14:31:20 +00009312 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009313 int value = _PyLong_AsInt(arg);
9314 if (value == -1 && PyErr_Occurred())
9315 return 0;
9316 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009317 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009318 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009319 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009320 /* look up the value in the table using a binary search */
9321 size_t lo = 0;
9322 size_t mid;
9323 size_t hi = tablesize;
9324 int cmp;
9325 const char *confname;
9326 if (!PyUnicode_Check(arg)) {
9327 PyErr_SetString(PyExc_TypeError,
9328 "configuration names must be strings or integers");
9329 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009331 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009332 if (confname == NULL)
9333 return 0;
9334 while (lo < hi) {
9335 mid = (lo + hi) / 2;
9336 cmp = strcmp(confname, table[mid].name);
9337 if (cmp < 0)
9338 hi = mid;
9339 else if (cmp > 0)
9340 lo = mid + 1;
9341 else {
9342 *valuep = table[mid].value;
9343 return 1;
9344 }
9345 }
9346 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9347 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009349}
9350
9351
9352#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9353static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009354#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009356#endif
9357#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009359#endif
Fred Drakec9680921999-12-13 16:37:25 +00009360#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009362#endif
9363#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009405#ifdef _PC_ACL_ENABLED
9406 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9407#endif
9408#ifdef _PC_MIN_HOLE_SIZE
9409 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9410#endif
9411#ifdef _PC_ALLOC_SIZE_MIN
9412 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9413#endif
9414#ifdef _PC_REC_INCR_XFER_SIZE
9415 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9416#endif
9417#ifdef _PC_REC_MAX_XFER_SIZE
9418 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9419#endif
9420#ifdef _PC_REC_MIN_XFER_SIZE
9421 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9422#endif
9423#ifdef _PC_REC_XFER_ALIGN
9424 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9425#endif
9426#ifdef _PC_SYMLINK_MAX
9427 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9428#endif
9429#ifdef _PC_XATTR_ENABLED
9430 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9431#endif
9432#ifdef _PC_XATTR_EXISTS
9433 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9434#endif
9435#ifdef _PC_TIMESTAMP_RESOLUTION
9436 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9437#endif
Fred Drakec9680921999-12-13 16:37:25 +00009438};
9439
Fred Drakec9680921999-12-13 16:37:25 +00009440static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009441conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009442{
9443 return conv_confname(arg, valuep, posix_constants_pathconf,
9444 sizeof(posix_constants_pathconf)
9445 / sizeof(struct constdef));
9446}
9447#endif
9448
Larry Hastings2f936352014-08-05 14:04:04 +10009449
Fred Drakec9680921999-12-13 16:37:25 +00009450#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009451/*[clinic input]
9452os.fpathconf -> long
9453
9454 fd: int
9455 name: path_confname
9456 /
9457
9458Return the configuration limit name for the file descriptor fd.
9459
9460If there is no limit, return -1.
9461[clinic start generated code]*/
9462
Larry Hastings2f936352014-08-05 14:04:04 +10009463static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009464os_fpathconf_impl(PyObject *module, int fd, int name)
9465/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009466{
9467 long limit;
9468
9469 errno = 0;
9470 limit = fpathconf(fd, name);
9471 if (limit == -1 && errno != 0)
9472 posix_error();
9473
9474 return limit;
9475}
9476#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009477
9478
9479#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009480/*[clinic input]
9481os.pathconf -> long
9482 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9483 name: path_confname
9484
9485Return the configuration limit name for the file or directory path.
9486
9487If there is no limit, return -1.
9488On some platforms, path may also be specified as an open file descriptor.
9489 If this functionality is unavailable, using it raises an exception.
9490[clinic start generated code]*/
9491
Larry Hastings2f936352014-08-05 14:04:04 +10009492static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009493os_pathconf_impl(PyObject *module, path_t *path, int name)
9494/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009495{
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009497
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009499#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009500 if (path->fd != -1)
9501 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009502 else
9503#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009504 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 if (limit == -1 && errno != 0) {
9506 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009507 /* could be a path or name problem */
9508 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009509 else
Larry Hastings2f936352014-08-05 14:04:04 +10009510 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 }
Larry Hastings2f936352014-08-05 14:04:04 +10009512
9513 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009514}
Larry Hastings2f936352014-08-05 14:04:04 +10009515#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009516
9517#ifdef HAVE_CONFSTR
9518static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009519#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009521#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009522#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009524#endif
9525#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009527#endif
Fred Draked86ed291999-12-15 15:34:33 +00009528#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009530#endif
9531#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009533#endif
9534#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
9537#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
Fred Drakec9680921999-12-13 16:37:25 +00009540#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
Fred Draked86ed291999-12-15 15:34:33 +00009564#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009566#endif
Fred Drakec9680921999-12-13 16:37:25 +00009567#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
Fred Draked86ed291999-12-15 15:34:33 +00009570#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009572#endif
9573#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009575#endif
9576#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009578#endif
9579#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009581#endif
Fred Drakec9680921999-12-13 16:37:25 +00009582#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
Fred Draked86ed291999-12-15 15:34:33 +00009630#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009632#endif
9633#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009635#endif
9636#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009638#endif
9639#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
9642#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009644#endif
9645#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
9648#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
9654#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
9657#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
9663#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009665#endif
9666#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009668#endif
Fred Drakec9680921999-12-13 16:37:25 +00009669};
9670
9671static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009672conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009673{
9674 return conv_confname(arg, valuep, posix_constants_confstr,
9675 sizeof(posix_constants_confstr)
9676 / sizeof(struct constdef));
9677}
9678
Larry Hastings2f936352014-08-05 14:04:04 +10009679
9680/*[clinic input]
9681os.confstr
9682
9683 name: confstr_confname
9684 /
9685
9686Return a string-valued system configuration variable.
9687[clinic start generated code]*/
9688
Larry Hastings2f936352014-08-05 14:04:04 +10009689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009690os_confstr_impl(PyObject *module, int name)
9691/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009692{
9693 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009694 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009695 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009696
Victor Stinnercb043522010-09-10 23:49:04 +00009697 errno = 0;
9698 len = confstr(name, buffer, sizeof(buffer));
9699 if (len == 0) {
9700 if (errno) {
9701 posix_error();
9702 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009703 }
9704 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009705 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009706 }
9707 }
Victor Stinnercb043522010-09-10 23:49:04 +00009708
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009709 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009710 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009711 char *buf = PyMem_Malloc(len);
9712 if (buf == NULL)
9713 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009714 len2 = confstr(name, buf, len);
9715 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009716 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009717 PyMem_Free(buf);
9718 }
9719 else
9720 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009721 return result;
9722}
Larry Hastings2f936352014-08-05 14:04:04 +10009723#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009724
9725
9726#ifdef HAVE_SYSCONF
9727static struct constdef posix_constants_sysconf[] = {
9728#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
Fred Draked86ed291999-12-15 15:34:33 +00009758#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
9761#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
Fred Drakec9680921999-12-13 16:37:25 +00009767#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
Fred Draked86ed291999-12-15 15:34:33 +00009782#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009784#endif
Fred Drakec9680921999-12-13 16:37:25 +00009785#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
Fred Draked86ed291999-12-15 15:34:33 +00009800#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009802#endif
Fred Drakec9680921999-12-13 16:37:25 +00009803#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
Fred Draked86ed291999-12-15 15:34:33 +00009872#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009874#endif
Fred Drakec9680921999-12-13 16:37:25 +00009875#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
Fred Draked86ed291999-12-15 15:34:33 +00009884#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009886#endif
Fred Drakec9680921999-12-13 16:37:25 +00009887#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
Fred Draked86ed291999-12-15 15:34:33 +00009890#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009892#endif
9893#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009895#endif
Fred Drakec9680921999-12-13 16:37:25 +00009896#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
Fred Draked86ed291999-12-15 15:34:33 +00009908#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009910#endif
Fred Drakec9680921999-12-13 16:37:25 +00009911#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
Fred Draked86ed291999-12-15 15:34:33 +00009932#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009934#endif
Fred Drakec9680921999-12-13 16:37:25 +00009935#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
Fred Draked86ed291999-12-15 15:34:33 +00009941#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009943#endif
Fred Drakec9680921999-12-13 16:37:25 +00009944#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
Fred Draked86ed291999-12-15 15:34:33 +00009971#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
9974#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009976#endif
Fred Drakec9680921999-12-13 16:37:25 +00009977#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
Fred Draked86ed291999-12-15 15:34:33 +000010082#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010084#endif
Fred Drakec9680921999-12-13 16:37:25 +000010085#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220};
10221
10222static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010223conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010224{
10225 return conv_confname(arg, valuep, posix_constants_sysconf,
10226 sizeof(posix_constants_sysconf)
10227 / sizeof(struct constdef));
10228}
10229
Larry Hastings2f936352014-08-05 14:04:04 +100010230
10231/*[clinic input]
10232os.sysconf -> long
10233 name: sysconf_confname
10234 /
10235
10236Return an integer-valued system configuration variable.
10237[clinic start generated code]*/
10238
Larry Hastings2f936352014-08-05 14:04:04 +100010239static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010240os_sysconf_impl(PyObject *module, int name)
10241/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010242{
10243 long value;
10244
10245 errno = 0;
10246 value = sysconf(name);
10247 if (value == -1 && errno != 0)
10248 posix_error();
10249 return value;
10250}
10251#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010252
10253
Fred Drakebec628d1999-12-15 18:31:10 +000010254/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010255 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010256 * the exported dictionaries that are used to publish information about the
10257 * names available on the host platform.
10258 *
10259 * Sorting the table at runtime ensures that the table is properly ordered
10260 * when used, even for platforms we're not able to test on. It also makes
10261 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010262 */
Fred Drakebec628d1999-12-15 18:31:10 +000010263
10264static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010265cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010266{
10267 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010269 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010271
10272 return strcmp(c1->name, c2->name);
10273}
10274
10275static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010276setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010277 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010278{
Fred Drakebec628d1999-12-15 18:31:10 +000010279 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010280 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010281
10282 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10283 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010284 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010286
Barry Warsaw3155db32000-04-13 15:20:40 +000010287 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 PyObject *o = PyLong_FromLong(table[i].value);
10289 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10290 Py_XDECREF(o);
10291 Py_DECREF(d);
10292 return -1;
10293 }
10294 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010295 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010296 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010297}
10298
Fred Drakebec628d1999-12-15 18:31:10 +000010299/* Return -1 on failure, 0 on success. */
10300static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010301setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010302{
10303#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010304 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010305 sizeof(posix_constants_pathconf)
10306 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010307 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010308 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010309#endif
10310#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010311 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010312 sizeof(posix_constants_confstr)
10313 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010314 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010315 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010316#endif
10317#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010318 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010319 sizeof(posix_constants_sysconf)
10320 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010321 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010322 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010323#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010324 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010325}
Fred Draked86ed291999-12-15 15:34:33 +000010326
10327
Larry Hastings2f936352014-08-05 14:04:04 +100010328/*[clinic input]
10329os.abort
10330
10331Abort the interpreter immediately.
10332
10333This function 'dumps core' or otherwise fails in the hardest way possible
10334on the hosting operating system. This function never returns.
10335[clinic start generated code]*/
10336
Larry Hastings2f936352014-08-05 14:04:04 +100010337static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010338os_abort_impl(PyObject *module)
10339/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010340{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010341 abort();
10342 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010343#ifndef __clang__
10344 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10345 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10346 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010347 Py_FatalError("abort() called from Python code didn't abort!");
10348 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010349#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010350}
Fred Drakebec628d1999-12-15 18:31:10 +000010351
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010352#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010353/* Grab ShellExecute dynamically from shell32 */
10354static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010355static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10356 LPCWSTR, INT);
10357static int
10358check_ShellExecute()
10359{
10360 HINSTANCE hShell32;
10361
10362 /* only recheck */
10363 if (-1 == has_ShellExecute) {
10364 Py_BEGIN_ALLOW_THREADS
10365 hShell32 = LoadLibraryW(L"SHELL32");
10366 Py_END_ALLOW_THREADS
10367 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010368 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10369 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010370 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010371 } else {
10372 has_ShellExecute = 0;
10373 }
10374 }
10375 return has_ShellExecute;
10376}
10377
10378
Steve Dowercc16be82016-09-08 10:35:16 -070010379/*[clinic input]
10380os.startfile
10381 filepath: path_t
10382 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010383
Steve Dowercc16be82016-09-08 10:35:16 -070010384startfile(filepath [, operation])
10385
10386Start a file with its associated application.
10387
10388When "operation" is not specified or "open", this acts like
10389double-clicking the file in Explorer, or giving the file name as an
10390argument to the DOS "start" command: the file is opened with whatever
10391application (if any) its extension is associated.
10392When another "operation" is given, it specifies what should be done with
10393the file. A typical operation is "print".
10394
10395startfile returns as soon as the associated application is launched.
10396There is no option to wait for the application to close, and no way
10397to retrieve the application's exit status.
10398
10399The filepath is relative to the current directory. If you want to use
10400an absolute path, make sure the first character is not a slash ("/");
10401the underlying Win32 ShellExecute function doesn't work if it is.
10402[clinic start generated code]*/
10403
10404static PyObject *
10405os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10406/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10407{
10408 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010409
10410 if(!check_ShellExecute()) {
10411 /* If the OS doesn't have ShellExecute, return a
10412 NotImplementedError. */
10413 return PyErr_Format(PyExc_NotImplementedError,
10414 "startfile not available on this platform");
10415 }
10416
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010418 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010419 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 Py_END_ALLOW_THREADS
10421
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010423 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010424 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 }
Steve Dowercc16be82016-09-08 10:35:16 -070010426 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010427}
Larry Hastings2f936352014-08-05 14:04:04 +100010428#endif /* MS_WINDOWS */
10429
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010430
Martin v. Löwis438b5342002-12-27 10:16:42 +000010431#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010432/*[clinic input]
10433os.getloadavg
10434
10435Return average recent system load information.
10436
10437Return the number of processes in the system run queue averaged over
10438the last 1, 5, and 15 minutes as a tuple of three floats.
10439Raises OSError if the load average was unobtainable.
10440[clinic start generated code]*/
10441
Larry Hastings2f936352014-08-05 14:04:04 +100010442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010443os_getloadavg_impl(PyObject *module)
10444/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010445{
10446 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010447 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010448 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10449 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010450 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010451 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010452}
Larry Hastings2f936352014-08-05 14:04:04 +100010453#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010454
Larry Hastings2f936352014-08-05 14:04:04 +100010455
10456/*[clinic input]
10457os.device_encoding
10458 fd: int
10459
10460Return a string describing the encoding of a terminal's file descriptor.
10461
10462The file descriptor must be attached to a terminal.
10463If the device is not a terminal, return None.
10464[clinic start generated code]*/
10465
Larry Hastings2f936352014-08-05 14:04:04 +100010466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010467os_device_encoding_impl(PyObject *module, int fd)
10468/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010469{
Brett Cannonefb00c02012-02-29 18:31:31 -050010470 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010471}
10472
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010473
Larry Hastings2f936352014-08-05 14:04:04 +100010474#ifdef HAVE_SETRESUID
10475/*[clinic input]
10476os.setresuid
10477
10478 ruid: uid_t
10479 euid: uid_t
10480 suid: uid_t
10481 /
10482
10483Set the current process's real, effective, and saved user ids.
10484[clinic start generated code]*/
10485
Larry Hastings2f936352014-08-05 14:04:04 +100010486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010487os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10488/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010489{
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 if (setresuid(ruid, euid, suid) < 0)
10491 return posix_error();
10492 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010493}
Larry Hastings2f936352014-08-05 14:04:04 +100010494#endif /* HAVE_SETRESUID */
10495
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010496
10497#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010498/*[clinic input]
10499os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010500
Larry Hastings2f936352014-08-05 14:04:04 +100010501 rgid: gid_t
10502 egid: gid_t
10503 sgid: gid_t
10504 /
10505
10506Set the current process's real, effective, and saved group ids.
10507[clinic start generated code]*/
10508
Larry Hastings2f936352014-08-05 14:04:04 +100010509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010510os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10511/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010512{
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 if (setresgid(rgid, egid, sgid) < 0)
10514 return posix_error();
10515 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010516}
Larry Hastings2f936352014-08-05 14:04:04 +100010517#endif /* HAVE_SETRESGID */
10518
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010519
10520#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010521/*[clinic input]
10522os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010523
Larry Hastings2f936352014-08-05 14:04:04 +100010524Return a tuple of the current process's real, effective, and saved user ids.
10525[clinic start generated code]*/
10526
Larry Hastings2f936352014-08-05 14:04:04 +100010527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010528os_getresuid_impl(PyObject *module)
10529/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010530{
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 if (getresuid(&ruid, &euid, &suid) < 0)
10533 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010534 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10535 _PyLong_FromUid(euid),
10536 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010537}
Larry Hastings2f936352014-08-05 14:04:04 +100010538#endif /* HAVE_GETRESUID */
10539
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010540
10541#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010542/*[clinic input]
10543os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010544
Larry Hastings2f936352014-08-05 14:04:04 +100010545Return a tuple of the current process's real, effective, and saved group ids.
10546[clinic start generated code]*/
10547
Larry Hastings2f936352014-08-05 14:04:04 +100010548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010549os_getresgid_impl(PyObject *module)
10550/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010551{
10552 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 if (getresgid(&rgid, &egid, &sgid) < 0)
10554 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010555 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10556 _PyLong_FromGid(egid),
10557 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010558}
Larry Hastings2f936352014-08-05 14:04:04 +100010559#endif /* HAVE_GETRESGID */
10560
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010561
Benjamin Peterson9428d532011-09-14 11:45:52 -040010562#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010563/*[clinic input]
10564os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010565
Larry Hastings2f936352014-08-05 14:04:04 +100010566 path: path_t(allow_fd=True)
10567 attribute: path_t
10568 *
10569 follow_symlinks: bool = True
10570
10571Return the value of extended attribute attribute on path.
10572
10573path may be either a string or an open file descriptor.
10574If follow_symlinks is False, and the last element of the path is a symbolic
10575 link, getxattr will examine the symbolic link itself instead of the file
10576 the link points to.
10577
10578[clinic start generated code]*/
10579
Larry Hastings2f936352014-08-05 14:04:04 +100010580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010581os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010582 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010583/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010584{
10585 Py_ssize_t i;
10586 PyObject *buffer = NULL;
10587
10588 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10589 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010590
Larry Hastings9cf065c2012-06-22 16:30:09 -070010591 for (i = 0; ; i++) {
10592 void *ptr;
10593 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010594 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 Py_ssize_t buffer_size = buffer_sizes[i];
10596 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010597 path_error(path);
10598 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 }
10600 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10601 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010602 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010603 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010604
Larry Hastings9cf065c2012-06-22 16:30:09 -070010605 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010606 if (path->fd >= 0)
10607 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010609 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 else
Larry Hastings2f936352014-08-05 14:04:04 +100010611 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010613
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 if (result < 0) {
10615 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 if (errno == ERANGE)
10617 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010618 path_error(path);
10619 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010620 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010621
Larry Hastings9cf065c2012-06-22 16:30:09 -070010622 if (result != buffer_size) {
10623 /* Can only shrink. */
10624 _PyBytes_Resize(&buffer, result);
10625 }
10626 break;
10627 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010628
Larry Hastings9cf065c2012-06-22 16:30:09 -070010629 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010630}
10631
Larry Hastings2f936352014-08-05 14:04:04 +100010632
10633/*[clinic input]
10634os.setxattr
10635
10636 path: path_t(allow_fd=True)
10637 attribute: path_t
10638 value: Py_buffer
10639 flags: int = 0
10640 *
10641 follow_symlinks: bool = True
10642
10643Set extended attribute attribute on path to value.
10644
10645path may be either a string or an open file descriptor.
10646If follow_symlinks is False, and the last element of the path is a symbolic
10647 link, setxattr will modify the symbolic link itself instead of the file
10648 the link points to.
10649
10650[clinic start generated code]*/
10651
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010653os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010654 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010655/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656{
Larry Hastings2f936352014-08-05 14:04:04 +100010657 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010658
Larry Hastings2f936352014-08-05 14:04:04 +100010659 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010660 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661
Benjamin Peterson799bd802011-08-31 22:15:17 -040010662 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010663 if (path->fd > -1)
10664 result = fsetxattr(path->fd, attribute->narrow,
10665 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010667 result = setxattr(path->narrow, attribute->narrow,
10668 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010669 else
Larry Hastings2f936352014-08-05 14:04:04 +100010670 result = lsetxattr(path->narrow, attribute->narrow,
10671 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010672 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010673
Larry Hastings9cf065c2012-06-22 16:30:09 -070010674 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010675 path_error(path);
10676 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010677 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010678
Larry Hastings2f936352014-08-05 14:04:04 +100010679 Py_RETURN_NONE;
10680}
10681
10682
10683/*[clinic input]
10684os.removexattr
10685
10686 path: path_t(allow_fd=True)
10687 attribute: path_t
10688 *
10689 follow_symlinks: bool = True
10690
10691Remove extended attribute attribute on path.
10692
10693path may be either a string or an open file descriptor.
10694If follow_symlinks is False, and the last element of the path is a symbolic
10695 link, removexattr will modify the symbolic link itself instead of the file
10696 the link points to.
10697
10698[clinic start generated code]*/
10699
Larry Hastings2f936352014-08-05 14:04:04 +100010700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010701os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010702 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010703/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010704{
10705 ssize_t result;
10706
10707 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10708 return NULL;
10709
10710 Py_BEGIN_ALLOW_THREADS;
10711 if (path->fd > -1)
10712 result = fremovexattr(path->fd, attribute->narrow);
10713 else if (follow_symlinks)
10714 result = removexattr(path->narrow, attribute->narrow);
10715 else
10716 result = lremovexattr(path->narrow, attribute->narrow);
10717 Py_END_ALLOW_THREADS;
10718
10719 if (result) {
10720 return path_error(path);
10721 }
10722
10723 Py_RETURN_NONE;
10724}
10725
10726
10727/*[clinic input]
10728os.listxattr
10729
10730 path: path_t(allow_fd=True, nullable=True) = None
10731 *
10732 follow_symlinks: bool = True
10733
10734Return a list of extended attributes on path.
10735
10736path may be either None, a string, or an open file descriptor.
10737if path is None, listxattr will examine the current directory.
10738If follow_symlinks is False, and the last element of the path is a symbolic
10739 link, listxattr will examine the symbolic link itself instead of the file
10740 the link points to.
10741[clinic start generated code]*/
10742
Larry Hastings2f936352014-08-05 14:04:04 +100010743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010744os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10745/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010746{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747 Py_ssize_t i;
10748 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010749 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010750 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010751
Larry Hastings2f936352014-08-05 14:04:04 +100010752 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010754
Larry Hastings2f936352014-08-05 14:04:04 +100010755 name = path->narrow ? path->narrow : ".";
10756
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010758 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010759 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010760 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761 Py_ssize_t buffer_size = buffer_sizes[i];
10762 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010763 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010764 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765 break;
10766 }
10767 buffer = PyMem_MALLOC(buffer_size);
10768 if (!buffer) {
10769 PyErr_NoMemory();
10770 break;
10771 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010772
Larry Hastings9cf065c2012-06-22 16:30:09 -070010773 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010774 if (path->fd > -1)
10775 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776 else if (follow_symlinks)
10777 length = listxattr(name, buffer, buffer_size);
10778 else
10779 length = llistxattr(name, buffer, buffer_size);
10780 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010781
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010783 if (errno == ERANGE) {
10784 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010785 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010786 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010787 }
Larry Hastings2f936352014-08-05 14:04:04 +100010788 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010789 break;
10790 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010791
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 result = PyList_New(0);
10793 if (!result) {
10794 goto exit;
10795 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010796
Larry Hastings9cf065c2012-06-22 16:30:09 -070010797 end = buffer + length;
10798 for (trace = start = buffer; trace != end; trace++) {
10799 if (!*trace) {
10800 int error;
10801 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10802 trace - start);
10803 if (!attribute) {
10804 Py_DECREF(result);
10805 result = NULL;
10806 goto exit;
10807 }
10808 error = PyList_Append(result, attribute);
10809 Py_DECREF(attribute);
10810 if (error) {
10811 Py_DECREF(result);
10812 result = NULL;
10813 goto exit;
10814 }
10815 start = trace + 1;
10816 }
10817 }
10818 break;
10819 }
10820exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010821 if (buffer)
10822 PyMem_FREE(buffer);
10823 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010824}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010825#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010826
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010827
Larry Hastings2f936352014-08-05 14:04:04 +100010828/*[clinic input]
10829os.urandom
10830
10831 size: Py_ssize_t
10832 /
10833
10834Return a bytes object containing random bytes suitable for cryptographic use.
10835[clinic start generated code]*/
10836
Larry Hastings2f936352014-08-05 14:04:04 +100010837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010838os_urandom_impl(PyObject *module, Py_ssize_t size)
10839/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010840{
10841 PyObject *bytes;
10842 int result;
10843
Georg Brandl2fb477c2012-02-21 00:33:36 +010010844 if (size < 0)
10845 return PyErr_Format(PyExc_ValueError,
10846 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010847 bytes = PyBytes_FromStringAndSize(NULL, size);
10848 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010849 return NULL;
10850
Victor Stinnere66987e2016-09-06 16:33:52 -070010851 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010852 if (result == -1) {
10853 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010854 return NULL;
10855 }
Larry Hastings2f936352014-08-05 14:04:04 +100010856 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010857}
10858
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010859/* Terminal size querying */
10860
10861static PyTypeObject TerminalSizeType;
10862
10863PyDoc_STRVAR(TerminalSize_docstring,
10864 "A tuple of (columns, lines) for holding terminal window size");
10865
10866static PyStructSequence_Field TerminalSize_fields[] = {
10867 {"columns", "width of the terminal window in characters"},
10868 {"lines", "height of the terminal window in characters"},
10869 {NULL, NULL}
10870};
10871
10872static PyStructSequence_Desc TerminalSize_desc = {
10873 "os.terminal_size",
10874 TerminalSize_docstring,
10875 TerminalSize_fields,
10876 2,
10877};
10878
10879#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010880/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010881PyDoc_STRVAR(termsize__doc__,
10882 "Return the size of the terminal window as (columns, lines).\n" \
10883 "\n" \
10884 "The optional argument fd (default standard output) specifies\n" \
10885 "which file descriptor should be queried.\n" \
10886 "\n" \
10887 "If the file descriptor is not connected to a terminal, an OSError\n" \
10888 "is thrown.\n" \
10889 "\n" \
10890 "This function will only be defined if an implementation is\n" \
10891 "available for this system.\n" \
10892 "\n" \
10893 "shutil.get_terminal_size is the high-level function which should \n" \
10894 "normally be used, os.get_terminal_size is the low-level implementation.");
10895
10896static PyObject*
10897get_terminal_size(PyObject *self, PyObject *args)
10898{
10899 int columns, lines;
10900 PyObject *termsize;
10901
10902 int fd = fileno(stdout);
10903 /* Under some conditions stdout may not be connected and
10904 * fileno(stdout) may point to an invalid file descriptor. For example
10905 * GUI apps don't have valid standard streams by default.
10906 *
10907 * If this happens, and the optional fd argument is not present,
10908 * the ioctl below will fail returning EBADF. This is what we want.
10909 */
10910
10911 if (!PyArg_ParseTuple(args, "|i", &fd))
10912 return NULL;
10913
10914#ifdef TERMSIZE_USE_IOCTL
10915 {
10916 struct winsize w;
10917 if (ioctl(fd, TIOCGWINSZ, &w))
10918 return PyErr_SetFromErrno(PyExc_OSError);
10919 columns = w.ws_col;
10920 lines = w.ws_row;
10921 }
10922#endif /* TERMSIZE_USE_IOCTL */
10923
10924#ifdef TERMSIZE_USE_CONIO
10925 {
10926 DWORD nhandle;
10927 HANDLE handle;
10928 CONSOLE_SCREEN_BUFFER_INFO csbi;
10929 switch (fd) {
10930 case 0: nhandle = STD_INPUT_HANDLE;
10931 break;
10932 case 1: nhandle = STD_OUTPUT_HANDLE;
10933 break;
10934 case 2: nhandle = STD_ERROR_HANDLE;
10935 break;
10936 default:
10937 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10938 }
10939 handle = GetStdHandle(nhandle);
10940 if (handle == NULL)
10941 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10942 if (handle == INVALID_HANDLE_VALUE)
10943 return PyErr_SetFromWindowsErr(0);
10944
10945 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10946 return PyErr_SetFromWindowsErr(0);
10947
10948 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10949 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10950 }
10951#endif /* TERMSIZE_USE_CONIO */
10952
10953 termsize = PyStructSequence_New(&TerminalSizeType);
10954 if (termsize == NULL)
10955 return NULL;
10956 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10957 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10958 if (PyErr_Occurred()) {
10959 Py_DECREF(termsize);
10960 return NULL;
10961 }
10962 return termsize;
10963}
10964#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10965
Larry Hastings2f936352014-08-05 14:04:04 +100010966
10967/*[clinic input]
10968os.cpu_count
10969
Charles-François Natali80d62e62015-08-13 20:37:08 +010010970Return the number of CPUs in the system; return None if indeterminable.
10971
10972This number is not equivalent to the number of CPUs the current process can
10973use. The number of usable CPUs can be obtained with
10974``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010975[clinic start generated code]*/
10976
Larry Hastings2f936352014-08-05 14:04:04 +100010977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010978os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010979/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010980{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010981 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010982#ifdef MS_WINDOWS
10983 SYSTEM_INFO sysinfo;
10984 GetSystemInfo(&sysinfo);
10985 ncpu = sysinfo.dwNumberOfProcessors;
10986#elif defined(__hpux)
10987 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10988#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10989 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010990#elif defined(__DragonFly__) || \
10991 defined(__OpenBSD__) || \
10992 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010993 defined(__NetBSD__) || \
10994 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010995 int mib[2];
10996 size_t len = sizeof(ncpu);
10997 mib[0] = CTL_HW;
10998 mib[1] = HW_NCPU;
10999 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11000 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011001#endif
11002 if (ncpu >= 1)
11003 return PyLong_FromLong(ncpu);
11004 else
11005 Py_RETURN_NONE;
11006}
11007
Victor Stinnerdaf45552013-08-28 00:53:59 +020011008
Larry Hastings2f936352014-08-05 14:04:04 +100011009/*[clinic input]
11010os.get_inheritable -> bool
11011
11012 fd: int
11013 /
11014
11015Get the close-on-exe flag of the specified file descriptor.
11016[clinic start generated code]*/
11017
Larry Hastings2f936352014-08-05 14:04:04 +100011018static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011019os_get_inheritable_impl(PyObject *module, int fd)
11020/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011021{
Steve Dower8fc89802015-04-12 00:26:27 -040011022 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011023 _Py_BEGIN_SUPPRESS_IPH
11024 return_value = _Py_get_inheritable(fd);
11025 _Py_END_SUPPRESS_IPH
11026 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011027}
11028
11029
11030/*[clinic input]
11031os.set_inheritable
11032 fd: int
11033 inheritable: int
11034 /
11035
11036Set the inheritable flag of the specified file descriptor.
11037[clinic start generated code]*/
11038
Larry Hastings2f936352014-08-05 14:04:04 +100011039static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011040os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11041/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011042{
Steve Dower8fc89802015-04-12 00:26:27 -040011043 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011044
Steve Dower8fc89802015-04-12 00:26:27 -040011045 _Py_BEGIN_SUPPRESS_IPH
11046 result = _Py_set_inheritable(fd, inheritable, NULL);
11047 _Py_END_SUPPRESS_IPH
11048 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011049 return NULL;
11050 Py_RETURN_NONE;
11051}
11052
11053
11054#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011055/*[clinic input]
11056os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011057 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011058 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011059
Larry Hastings2f936352014-08-05 14:04:04 +100011060Get the close-on-exe flag of the specified file descriptor.
11061[clinic start generated code]*/
11062
Larry Hastings2f936352014-08-05 14:04:04 +100011063static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011064os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011065/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011066{
11067 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011068
11069 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11070 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011071 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011072 }
11073
Larry Hastings2f936352014-08-05 14:04:04 +100011074 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011075}
11076
Victor Stinnerdaf45552013-08-28 00:53:59 +020011077
Larry Hastings2f936352014-08-05 14:04:04 +100011078/*[clinic input]
11079os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011080 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011081 inheritable: bool
11082 /
11083
11084Set the inheritable flag of the specified handle.
11085[clinic start generated code]*/
11086
Larry Hastings2f936352014-08-05 14:04:04 +100011087static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011088os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011089 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011090/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011091{
11092 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011093 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11094 PyErr_SetFromWindowsErr(0);
11095 return NULL;
11096 }
11097 Py_RETURN_NONE;
11098}
Larry Hastings2f936352014-08-05 14:04:04 +100011099#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011100
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011101#ifndef MS_WINDOWS
11102PyDoc_STRVAR(get_blocking__doc__,
11103 "get_blocking(fd) -> bool\n" \
11104 "\n" \
11105 "Get the blocking mode of the file descriptor:\n" \
11106 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11107
11108static PyObject*
11109posix_get_blocking(PyObject *self, PyObject *args)
11110{
11111 int fd;
11112 int blocking;
11113
11114 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11115 return NULL;
11116
Steve Dower8fc89802015-04-12 00:26:27 -040011117 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011118 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011119 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011120 if (blocking < 0)
11121 return NULL;
11122 return PyBool_FromLong(blocking);
11123}
11124
11125PyDoc_STRVAR(set_blocking__doc__,
11126 "set_blocking(fd, blocking)\n" \
11127 "\n" \
11128 "Set the blocking mode of the specified file descriptor.\n" \
11129 "Set the O_NONBLOCK flag if blocking is False,\n" \
11130 "clear the O_NONBLOCK flag otherwise.");
11131
11132static PyObject*
11133posix_set_blocking(PyObject *self, PyObject *args)
11134{
Steve Dower8fc89802015-04-12 00:26:27 -040011135 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011136
11137 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11138 return NULL;
11139
Steve Dower8fc89802015-04-12 00:26:27 -040011140 _Py_BEGIN_SUPPRESS_IPH
11141 result = _Py_set_blocking(fd, blocking);
11142 _Py_END_SUPPRESS_IPH
11143 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011144 return NULL;
11145 Py_RETURN_NONE;
11146}
11147#endif /* !MS_WINDOWS */
11148
11149
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011150/*[clinic input]
11151class os.DirEntry "DirEntry *" "&DirEntryType"
11152[clinic start generated code]*/
11153/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011154
11155typedef struct {
11156 PyObject_HEAD
11157 PyObject *name;
11158 PyObject *path;
11159 PyObject *stat;
11160 PyObject *lstat;
11161#ifdef MS_WINDOWS
11162 struct _Py_stat_struct win32_lstat;
11163 __int64 win32_file_index;
11164 int got_file_index;
11165#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011166#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011167 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011168#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011169 ino_t d_ino;
11170#endif
11171} DirEntry;
11172
11173static void
11174DirEntry_dealloc(DirEntry *entry)
11175{
11176 Py_XDECREF(entry->name);
11177 Py_XDECREF(entry->path);
11178 Py_XDECREF(entry->stat);
11179 Py_XDECREF(entry->lstat);
11180 Py_TYPE(entry)->tp_free((PyObject *)entry);
11181}
11182
11183/* Forward reference */
11184static int
11185DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11186
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011187/*[clinic input]
11188os.DirEntry.is_symlink -> bool
11189
11190Return True if the entry is a symbolic link; cached per entry.
11191[clinic start generated code]*/
11192
Victor Stinner6036e442015-03-08 01:58:04 +010011193static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011194os_DirEntry_is_symlink_impl(DirEntry *self)
11195/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011196{
11197#ifdef MS_WINDOWS
11198 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011199#elif defined(HAVE_DIRENT_D_TYPE)
11200 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011201 if (self->d_type != DT_UNKNOWN)
11202 return self->d_type == DT_LNK;
11203 else
11204 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011205#else
11206 /* POSIX without d_type */
11207 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011208#endif
11209}
11210
11211static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011212DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11213{
11214 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011215 STRUCT_STAT st;
11216 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011217
11218#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011219 if (PyUnicode_FSDecoder(self->path, &ub)) {
11220 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011221#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011222 if (PyUnicode_FSConverter(self->path, &ub)) {
11223 const char *path = PyBytes_AS_STRING(ub);
11224#endif
11225 if (follow_symlinks)
11226 result = STAT(path, &st);
11227 else
11228 result = LSTAT(path, &st);
11229 Py_DECREF(ub);
11230 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011231 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011232
11233 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011234 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011235
11236 return _pystat_fromstructstat(&st);
11237}
11238
11239static PyObject *
11240DirEntry_get_lstat(DirEntry *self)
11241{
11242 if (!self->lstat) {
11243#ifdef MS_WINDOWS
11244 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11245#else /* POSIX */
11246 self->lstat = DirEntry_fetch_stat(self, 0);
11247#endif
11248 }
11249 Py_XINCREF(self->lstat);
11250 return self->lstat;
11251}
11252
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011253/*[clinic input]
11254os.DirEntry.stat
11255 *
11256 follow_symlinks: bool = True
11257
11258Return stat_result object for the entry; cached per entry.
11259[clinic start generated code]*/
11260
Victor Stinner6036e442015-03-08 01:58:04 +010011261static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011262os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11263/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011264{
11265 if (!follow_symlinks)
11266 return DirEntry_get_lstat(self);
11267
11268 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011269 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011270 if (result == -1)
11271 return NULL;
11272 else if (result)
11273 self->stat = DirEntry_fetch_stat(self, 1);
11274 else
11275 self->stat = DirEntry_get_lstat(self);
11276 }
11277
11278 Py_XINCREF(self->stat);
11279 return self->stat;
11280}
11281
Victor Stinner6036e442015-03-08 01:58:04 +010011282/* Set exception and return -1 on error, 0 for False, 1 for True */
11283static int
11284DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11285{
11286 PyObject *stat = NULL;
11287 PyObject *st_mode = NULL;
11288 long mode;
11289 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011290#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011291 int is_symlink;
11292 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011293#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011294#ifdef MS_WINDOWS
11295 unsigned long dir_bits;
11296#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011297 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011298
11299#ifdef MS_WINDOWS
11300 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11301 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011302#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011303 is_symlink = self->d_type == DT_LNK;
11304 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11305#endif
11306
Victor Stinner35a97c02015-03-08 02:59:09 +010011307#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011308 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011309#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011310 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011311 if (!stat) {
11312 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11313 /* If file doesn't exist (anymore), then return False
11314 (i.e., say it's not a file/directory) */
11315 PyErr_Clear();
11316 return 0;
11317 }
11318 goto error;
11319 }
11320 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11321 if (!st_mode)
11322 goto error;
11323
11324 mode = PyLong_AsLong(st_mode);
11325 if (mode == -1 && PyErr_Occurred())
11326 goto error;
11327 Py_CLEAR(st_mode);
11328 Py_CLEAR(stat);
11329 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011330#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011331 }
11332 else if (is_symlink) {
11333 assert(mode_bits != S_IFLNK);
11334 result = 0;
11335 }
11336 else {
11337 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11338#ifdef MS_WINDOWS
11339 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11340 if (mode_bits == S_IFDIR)
11341 result = dir_bits != 0;
11342 else
11343 result = dir_bits == 0;
11344#else /* POSIX */
11345 if (mode_bits == S_IFDIR)
11346 result = self->d_type == DT_DIR;
11347 else
11348 result = self->d_type == DT_REG;
11349#endif
11350 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011351#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011352
11353 return result;
11354
11355error:
11356 Py_XDECREF(st_mode);
11357 Py_XDECREF(stat);
11358 return -1;
11359}
11360
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011361/*[clinic input]
11362os.DirEntry.is_dir -> bool
11363 *
11364 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011365
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011366Return True if the entry is a directory; cached per entry.
11367[clinic start generated code]*/
11368
11369static int
11370os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11371/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11372{
11373 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011374}
11375
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011376/*[clinic input]
11377os.DirEntry.is_file -> bool
11378 *
11379 follow_symlinks: bool = True
11380
11381Return True if the entry is a file; cached per entry.
11382[clinic start generated code]*/
11383
11384static int
11385os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11386/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011387{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011388 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011389}
11390
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011391/*[clinic input]
11392os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011393
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011394Return inode of the entry; cached per entry.
11395[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011396
11397static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011398os_DirEntry_inode_impl(DirEntry *self)
11399/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011400{
11401#ifdef MS_WINDOWS
11402 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011403 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011404 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011405 STRUCT_STAT stat;
11406 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011407
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011408 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011409 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011410 path = PyUnicode_AsUnicode(unicode);
11411 result = LSTAT(path, &stat);
11412 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011413
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011414 if (result != 0)
11415 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011416
11417 self->win32_file_index = stat.st_ino;
11418 self->got_file_index = 1;
11419 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011420 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011421#else /* POSIX */
11422#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011423 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011424#else
11425 return PyLong_FromLong((long)self->d_ino);
11426#endif
11427#endif
11428}
11429
11430static PyObject *
11431DirEntry_repr(DirEntry *self)
11432{
11433 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11434}
11435
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011436/*[clinic input]
11437os.DirEntry.__fspath__
11438
11439Returns the path for the entry.
11440[clinic start generated code]*/
11441
Brett Cannon96881cd2016-06-10 14:37:21 -070011442static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011443os_DirEntry___fspath___impl(DirEntry *self)
11444/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011445{
11446 Py_INCREF(self->path);
11447 return self->path;
11448}
11449
Victor Stinner6036e442015-03-08 01:58:04 +010011450static PyMemberDef DirEntry_members[] = {
11451 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11452 "the entry's base filename, relative to scandir() \"path\" argument"},
11453 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11454 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11455 {NULL}
11456};
11457
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011458#include "clinic/posixmodule.c.h"
11459
Victor Stinner6036e442015-03-08 01:58:04 +010011460static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011461 OS_DIRENTRY_IS_DIR_METHODDEF
11462 OS_DIRENTRY_IS_FILE_METHODDEF
11463 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11464 OS_DIRENTRY_STAT_METHODDEF
11465 OS_DIRENTRY_INODE_METHODDEF
11466 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011467 {NULL}
11468};
11469
Benjamin Peterson5646de42015-04-12 17:56:34 -040011470static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011471 PyVarObject_HEAD_INIT(NULL, 0)
11472 MODNAME ".DirEntry", /* tp_name */
11473 sizeof(DirEntry), /* tp_basicsize */
11474 0, /* tp_itemsize */
11475 /* methods */
11476 (destructor)DirEntry_dealloc, /* tp_dealloc */
11477 0, /* tp_print */
11478 0, /* tp_getattr */
11479 0, /* tp_setattr */
11480 0, /* tp_compare */
11481 (reprfunc)DirEntry_repr, /* tp_repr */
11482 0, /* tp_as_number */
11483 0, /* tp_as_sequence */
11484 0, /* tp_as_mapping */
11485 0, /* tp_hash */
11486 0, /* tp_call */
11487 0, /* tp_str */
11488 0, /* tp_getattro */
11489 0, /* tp_setattro */
11490 0, /* tp_as_buffer */
11491 Py_TPFLAGS_DEFAULT, /* tp_flags */
11492 0, /* tp_doc */
11493 0, /* tp_traverse */
11494 0, /* tp_clear */
11495 0, /* tp_richcompare */
11496 0, /* tp_weaklistoffset */
11497 0, /* tp_iter */
11498 0, /* tp_iternext */
11499 DirEntry_methods, /* tp_methods */
11500 DirEntry_members, /* tp_members */
11501};
11502
11503#ifdef MS_WINDOWS
11504
11505static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011506join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011507{
11508 Py_ssize_t path_len;
11509 Py_ssize_t size;
11510 wchar_t *result;
11511 wchar_t ch;
11512
11513 if (!path_wide) { /* Default arg: "." */
11514 path_wide = L".";
11515 path_len = 1;
11516 }
11517 else {
11518 path_len = wcslen(path_wide);
11519 }
11520
11521 /* The +1's are for the path separator and the NUL */
11522 size = path_len + 1 + wcslen(filename) + 1;
11523 result = PyMem_New(wchar_t, size);
11524 if (!result) {
11525 PyErr_NoMemory();
11526 return NULL;
11527 }
11528 wcscpy(result, path_wide);
11529 if (path_len > 0) {
11530 ch = result[path_len - 1];
11531 if (ch != SEP && ch != ALTSEP && ch != L':')
11532 result[path_len++] = SEP;
11533 wcscpy(result + path_len, filename);
11534 }
11535 return result;
11536}
11537
11538static PyObject *
11539DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11540{
11541 DirEntry *entry;
11542 BY_HANDLE_FILE_INFORMATION file_info;
11543 ULONG reparse_tag;
11544 wchar_t *joined_path;
11545
11546 entry = PyObject_New(DirEntry, &DirEntryType);
11547 if (!entry)
11548 return NULL;
11549 entry->name = NULL;
11550 entry->path = NULL;
11551 entry->stat = NULL;
11552 entry->lstat = NULL;
11553 entry->got_file_index = 0;
11554
11555 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11556 if (!entry->name)
11557 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011558 if (path->narrow) {
11559 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11560 if (!entry->name)
11561 goto error;
11562 }
Victor Stinner6036e442015-03-08 01:58:04 +010011563
11564 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11565 if (!joined_path)
11566 goto error;
11567
11568 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11569 PyMem_Free(joined_path);
11570 if (!entry->path)
11571 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011572 if (path->narrow) {
11573 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11574 if (!entry->path)
11575 goto error;
11576 }
Victor Stinner6036e442015-03-08 01:58:04 +010011577
Steve Dowercc16be82016-09-08 10:35:16 -070011578 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011579 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11580
11581 return (PyObject *)entry;
11582
11583error:
11584 Py_DECREF(entry);
11585 return NULL;
11586}
11587
11588#else /* POSIX */
11589
11590static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011591join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011592{
11593 Py_ssize_t path_len;
11594 Py_ssize_t size;
11595 char *result;
11596
11597 if (!path_narrow) { /* Default arg: "." */
11598 path_narrow = ".";
11599 path_len = 1;
11600 }
11601 else {
11602 path_len = strlen(path_narrow);
11603 }
11604
11605 if (filename_len == -1)
11606 filename_len = strlen(filename);
11607
11608 /* The +1's are for the path separator and the NUL */
11609 size = path_len + 1 + filename_len + 1;
11610 result = PyMem_New(char, size);
11611 if (!result) {
11612 PyErr_NoMemory();
11613 return NULL;
11614 }
11615 strcpy(result, path_narrow);
11616 if (path_len > 0 && result[path_len - 1] != '/')
11617 result[path_len++] = '/';
11618 strcpy(result + path_len, filename);
11619 return result;
11620}
11621
11622static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011623DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011624 ino_t d_ino
11625#ifdef HAVE_DIRENT_D_TYPE
11626 , unsigned char d_type
11627#endif
11628 )
Victor Stinner6036e442015-03-08 01:58:04 +010011629{
11630 DirEntry *entry;
11631 char *joined_path;
11632
11633 entry = PyObject_New(DirEntry, &DirEntryType);
11634 if (!entry)
11635 return NULL;
11636 entry->name = NULL;
11637 entry->path = NULL;
11638 entry->stat = NULL;
11639 entry->lstat = NULL;
11640
11641 joined_path = join_path_filename(path->narrow, name, name_len);
11642 if (!joined_path)
11643 goto error;
11644
11645 if (!path->narrow || !PyBytes_Check(path->object)) {
11646 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11647 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11648 }
11649 else {
11650 entry->name = PyBytes_FromStringAndSize(name, name_len);
11651 entry->path = PyBytes_FromString(joined_path);
11652 }
11653 PyMem_Free(joined_path);
11654 if (!entry->name || !entry->path)
11655 goto error;
11656
Victor Stinner35a97c02015-03-08 02:59:09 +010011657#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011658 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011659#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011660 entry->d_ino = d_ino;
11661
11662 return (PyObject *)entry;
11663
11664error:
11665 Py_XDECREF(entry);
11666 return NULL;
11667}
11668
11669#endif
11670
11671
11672typedef struct {
11673 PyObject_HEAD
11674 path_t path;
11675#ifdef MS_WINDOWS
11676 HANDLE handle;
11677 WIN32_FIND_DATAW file_data;
11678 int first_time;
11679#else /* POSIX */
11680 DIR *dirp;
11681#endif
11682} ScandirIterator;
11683
11684#ifdef MS_WINDOWS
11685
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011686static int
11687ScandirIterator_is_closed(ScandirIterator *iterator)
11688{
11689 return iterator->handle == INVALID_HANDLE_VALUE;
11690}
11691
Victor Stinner6036e442015-03-08 01:58:04 +010011692static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011693ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011694{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011695 HANDLE handle = iterator->handle;
11696
11697 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011698 return;
11699
Victor Stinner6036e442015-03-08 01:58:04 +010011700 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011701 Py_BEGIN_ALLOW_THREADS
11702 FindClose(handle);
11703 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011704}
11705
11706static PyObject *
11707ScandirIterator_iternext(ScandirIterator *iterator)
11708{
11709 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11710 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011711 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011712
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011713 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011714 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011715 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011716
11717 while (1) {
11718 if (!iterator->first_time) {
11719 Py_BEGIN_ALLOW_THREADS
11720 success = FindNextFileW(iterator->handle, file_data);
11721 Py_END_ALLOW_THREADS
11722 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011723 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011724 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011725 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011726 break;
11727 }
11728 }
11729 iterator->first_time = 0;
11730
11731 /* Skip over . and .. */
11732 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011733 wcscmp(file_data->cFileName, L"..") != 0) {
11734 entry = DirEntry_from_find_data(&iterator->path, file_data);
11735 if (!entry)
11736 break;
11737 return entry;
11738 }
Victor Stinner6036e442015-03-08 01:58:04 +010011739
11740 /* Loop till we get a non-dot directory or finish iterating */
11741 }
11742
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011743 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011744 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011745 return NULL;
11746}
11747
11748#else /* POSIX */
11749
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011750static int
11751ScandirIterator_is_closed(ScandirIterator *iterator)
11752{
11753 return !iterator->dirp;
11754}
11755
Victor Stinner6036e442015-03-08 01:58:04 +010011756static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011757ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011758{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011759 DIR *dirp = iterator->dirp;
11760
11761 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011762 return;
11763
Victor Stinner6036e442015-03-08 01:58:04 +010011764 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011765 Py_BEGIN_ALLOW_THREADS
11766 closedir(dirp);
11767 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011768 return;
11769}
11770
11771static PyObject *
11772ScandirIterator_iternext(ScandirIterator *iterator)
11773{
11774 struct dirent *direntp;
11775 Py_ssize_t name_len;
11776 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011777 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011778
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011779 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011780 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011781 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011782
11783 while (1) {
11784 errno = 0;
11785 Py_BEGIN_ALLOW_THREADS
11786 direntp = readdir(iterator->dirp);
11787 Py_END_ALLOW_THREADS
11788
11789 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011790 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011791 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011792 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011793 break;
11794 }
11795
11796 /* Skip over . and .. */
11797 name_len = NAMLEN(direntp);
11798 is_dot = direntp->d_name[0] == '.' &&
11799 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11800 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011801 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011802 name_len, direntp->d_ino
11803#ifdef HAVE_DIRENT_D_TYPE
11804 , direntp->d_type
11805#endif
11806 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011807 if (!entry)
11808 break;
11809 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011810 }
11811
11812 /* Loop till we get a non-dot directory or finish iterating */
11813 }
11814
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011815 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011816 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011817 return NULL;
11818}
11819
11820#endif
11821
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011822static PyObject *
11823ScandirIterator_close(ScandirIterator *self, PyObject *args)
11824{
11825 ScandirIterator_closedir(self);
11826 Py_RETURN_NONE;
11827}
11828
11829static PyObject *
11830ScandirIterator_enter(PyObject *self, PyObject *args)
11831{
11832 Py_INCREF(self);
11833 return self;
11834}
11835
11836static PyObject *
11837ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11838{
11839 ScandirIterator_closedir(self);
11840 Py_RETURN_NONE;
11841}
11842
Victor Stinner6036e442015-03-08 01:58:04 +010011843static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011844ScandirIterator_finalize(ScandirIterator *iterator)
11845{
11846 PyObject *error_type, *error_value, *error_traceback;
11847
11848 /* Save the current exception, if any. */
11849 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11850
11851 if (!ScandirIterator_is_closed(iterator)) {
11852 ScandirIterator_closedir(iterator);
11853
11854 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11855 "unclosed scandir iterator %R", iterator)) {
11856 /* Spurious errors can appear at shutdown */
11857 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11858 PyErr_WriteUnraisable((PyObject *) iterator);
11859 }
11860 }
11861 }
11862
11863 Py_CLEAR(iterator->path.object);
11864 path_cleanup(&iterator->path);
11865
11866 /* Restore the saved exception. */
11867 PyErr_Restore(error_type, error_value, error_traceback);
11868}
11869
11870static void
Victor Stinner6036e442015-03-08 01:58:04 +010011871ScandirIterator_dealloc(ScandirIterator *iterator)
11872{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011873 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11874 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011875
Victor Stinner6036e442015-03-08 01:58:04 +010011876 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11877}
11878
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011879static PyMethodDef ScandirIterator_methods[] = {
11880 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11881 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11882 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11883 {NULL}
11884};
11885
Benjamin Peterson5646de42015-04-12 17:56:34 -040011886static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011887 PyVarObject_HEAD_INIT(NULL, 0)
11888 MODNAME ".ScandirIterator", /* tp_name */
11889 sizeof(ScandirIterator), /* tp_basicsize */
11890 0, /* tp_itemsize */
11891 /* methods */
11892 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11893 0, /* tp_print */
11894 0, /* tp_getattr */
11895 0, /* tp_setattr */
11896 0, /* tp_compare */
11897 0, /* tp_repr */
11898 0, /* tp_as_number */
11899 0, /* tp_as_sequence */
11900 0, /* tp_as_mapping */
11901 0, /* tp_hash */
11902 0, /* tp_call */
11903 0, /* tp_str */
11904 0, /* tp_getattro */
11905 0, /* tp_setattro */
11906 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011907 Py_TPFLAGS_DEFAULT
11908 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011909 0, /* tp_doc */
11910 0, /* tp_traverse */
11911 0, /* tp_clear */
11912 0, /* tp_richcompare */
11913 0, /* tp_weaklistoffset */
11914 PyObject_SelfIter, /* tp_iter */
11915 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011916 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011917 0, /* tp_members */
11918 0, /* tp_getset */
11919 0, /* tp_base */
11920 0, /* tp_dict */
11921 0, /* tp_descr_get */
11922 0, /* tp_descr_set */
11923 0, /* tp_dictoffset */
11924 0, /* tp_init */
11925 0, /* tp_alloc */
11926 0, /* tp_new */
11927 0, /* tp_free */
11928 0, /* tp_is_gc */
11929 0, /* tp_bases */
11930 0, /* tp_mro */
11931 0, /* tp_cache */
11932 0, /* tp_subclasses */
11933 0, /* tp_weaklist */
11934 0, /* tp_del */
11935 0, /* tp_version_tag */
11936 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011937};
11938
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011939/*[clinic input]
11940os.scandir
11941
11942 path : path_t(nullable=True) = None
11943
11944Return an iterator of DirEntry objects for given path.
11945
11946path can be specified as either str, bytes or path-like object. If path
11947is bytes, the names of yielded DirEntry objects will also be bytes; in
11948all other circumstances they will be str.
11949
11950If path is None, uses the path='.'.
11951[clinic start generated code]*/
11952
Victor Stinner6036e442015-03-08 01:58:04 +010011953static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011954os_scandir_impl(PyObject *module, path_t *path)
11955/*[clinic end generated code: output=6eb2668b675ca89e input=e62b08b3cd41f604]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011956{
11957 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010011958#ifdef MS_WINDOWS
11959 wchar_t *path_strW;
11960#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011961 const char *path_str;
Victor Stinner6036e442015-03-08 01:58:04 +010011962#endif
11963
11964 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11965 if (!iterator)
11966 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011967
11968#ifdef MS_WINDOWS
11969 iterator->handle = INVALID_HANDLE_VALUE;
11970#else
11971 iterator->dirp = NULL;
11972#endif
11973
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011974 memcpy(&iterator->path, path, sizeof(path_t));
Victor Stinner6036e442015-03-08 01:58:04 +010011975 /* path_converter doesn't keep path.object around, so do it
11976 manually for the lifetime of the iterator here (the refcount
11977 is decremented in ScandirIterator_dealloc)
11978 */
11979 Py_XINCREF(iterator->path.object);
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011980 Py_XINCREF(iterator->path.cleanup);
Victor Stinner6036e442015-03-08 01:58:04 +010011981
11982#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011983 iterator->first_time = 1;
11984
11985 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11986 if (!path_strW)
11987 goto error;
11988
11989 Py_BEGIN_ALLOW_THREADS
11990 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11991 Py_END_ALLOW_THREADS
11992
11993 PyMem_Free(path_strW);
11994
11995 if (iterator->handle == INVALID_HANDLE_VALUE) {
11996 path_error(&iterator->path);
11997 goto error;
11998 }
11999#else /* POSIX */
12000 if (iterator->path.narrow)
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012001 path_str = iterator->path.narrow;
Victor Stinner6036e442015-03-08 01:58:04 +010012002 else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012003 path_str = ".";
Victor Stinner6036e442015-03-08 01:58:04 +010012004
12005 errno = 0;
12006 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012007 iterator->dirp = opendir(path_str);
Victor Stinner6036e442015-03-08 01:58:04 +010012008 Py_END_ALLOW_THREADS
12009
12010 if (!iterator->dirp) {
12011 path_error(&iterator->path);
12012 goto error;
12013 }
12014#endif
12015
12016 return (PyObject *)iterator;
12017
12018error:
12019 Py_DECREF(iterator);
12020 return NULL;
12021}
12022
Ethan Furman410ef8e2016-06-04 12:06:26 -070012023/*
12024 Return the file system path representation of the object.
12025
12026 If the object is str or bytes, then allow it to pass through with
12027 an incremented refcount. If the object defines __fspath__(), then
12028 return the result of that method. All other types raise a TypeError.
12029*/
12030PyObject *
12031PyOS_FSPath(PyObject *path)
12032{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012033 /* For error message reasons, this function is manually inlined in
12034 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012035 _Py_IDENTIFIER(__fspath__);
12036 PyObject *func = NULL;
12037 PyObject *path_repr = NULL;
12038
12039 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12040 Py_INCREF(path);
12041 return path;
12042 }
12043
12044 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12045 if (NULL == func) {
12046 return PyErr_Format(PyExc_TypeError,
12047 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012048 "not %.200s",
12049 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012050 }
12051
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012052 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012053 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012054 if (NULL == path_repr) {
12055 return NULL;
12056 }
12057
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012058 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12059 PyErr_Format(PyExc_TypeError,
12060 "expected %.200s.__fspath__() to return str or bytes, "
12061 "not %.200s", Py_TYPE(path)->tp_name,
12062 Py_TYPE(path_repr)->tp_name);
12063 Py_DECREF(path_repr);
12064 return NULL;
12065 }
12066
Ethan Furman410ef8e2016-06-04 12:06:26 -070012067 return path_repr;
12068}
12069
12070/*[clinic input]
12071os.fspath
12072
12073 path: object
12074
12075Return the file system path representation of the object.
12076
Brett Cannonb4f43e92016-06-09 14:32:08 -070012077If the object is str or bytes, then allow it to pass through as-is. If the
12078object defines __fspath__(), then return the result of that method. All other
12079types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012080[clinic start generated code]*/
12081
12082static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012083os_fspath_impl(PyObject *module, PyObject *path)
12084/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012085{
12086 return PyOS_FSPath(path);
12087}
Victor Stinner6036e442015-03-08 01:58:04 +010012088
Victor Stinner9b1f4742016-09-06 16:18:52 -070012089#ifdef HAVE_GETRANDOM_SYSCALL
12090/*[clinic input]
12091os.getrandom
12092
12093 size: Py_ssize_t
12094 flags: int=0
12095
12096Obtain a series of random bytes.
12097[clinic start generated code]*/
12098
12099static PyObject *
12100os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12101/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12102{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012103 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012104 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012105
12106 if (size < 0) {
12107 errno = EINVAL;
12108 return posix_error();
12109 }
12110
Victor Stinnerec2319c2016-09-20 23:00:59 +020012111 bytes = PyBytes_FromStringAndSize(NULL, size);
12112 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012113 PyErr_NoMemory();
12114 return NULL;
12115 }
12116
12117 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012118 n = syscall(SYS_getrandom,
12119 PyBytes_AS_STRING(bytes),
12120 PyBytes_GET_SIZE(bytes),
12121 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012122 if (n < 0 && errno == EINTR) {
12123 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012124 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012125 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012126
12127 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012128 continue;
12129 }
12130 break;
12131 }
12132
12133 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012134 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012135 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012136 }
12137
Victor Stinnerec2319c2016-09-20 23:00:59 +020012138 if (n != size) {
12139 _PyBytes_Resize(&bytes, n);
12140 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012141
12142 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012143
12144error:
12145 Py_DECREF(bytes);
12146 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012147}
12148#endif /* HAVE_GETRANDOM_SYSCALL */
12149
Larry Hastings31826802013-10-19 00:09:25 -070012150
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012151static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012152
12153 OS_STAT_METHODDEF
12154 OS_ACCESS_METHODDEF
12155 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012156 OS_CHDIR_METHODDEF
12157 OS_CHFLAGS_METHODDEF
12158 OS_CHMOD_METHODDEF
12159 OS_FCHMOD_METHODDEF
12160 OS_LCHMOD_METHODDEF
12161 OS_CHOWN_METHODDEF
12162 OS_FCHOWN_METHODDEF
12163 OS_LCHOWN_METHODDEF
12164 OS_LCHFLAGS_METHODDEF
12165 OS_CHROOT_METHODDEF
12166 OS_CTERMID_METHODDEF
12167 OS_GETCWD_METHODDEF
12168 OS_GETCWDB_METHODDEF
12169 OS_LINK_METHODDEF
12170 OS_LISTDIR_METHODDEF
12171 OS_LSTAT_METHODDEF
12172 OS_MKDIR_METHODDEF
12173 OS_NICE_METHODDEF
12174 OS_GETPRIORITY_METHODDEF
12175 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012176#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012177 {"readlink", (PyCFunction)posix_readlink,
12178 METH_VARARGS | METH_KEYWORDS,
12179 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012180#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012181#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012182 {"readlink", (PyCFunction)win_readlink,
12183 METH_VARARGS | METH_KEYWORDS,
12184 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012185#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012186 OS_RENAME_METHODDEF
12187 OS_REPLACE_METHODDEF
12188 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012189 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012190 OS_SYMLINK_METHODDEF
12191 OS_SYSTEM_METHODDEF
12192 OS_UMASK_METHODDEF
12193 OS_UNAME_METHODDEF
12194 OS_UNLINK_METHODDEF
12195 OS_REMOVE_METHODDEF
12196 OS_UTIME_METHODDEF
12197 OS_TIMES_METHODDEF
12198 OS__EXIT_METHODDEF
12199 OS_EXECV_METHODDEF
12200 OS_EXECVE_METHODDEF
12201 OS_SPAWNV_METHODDEF
12202 OS_SPAWNVE_METHODDEF
12203 OS_FORK1_METHODDEF
12204 OS_FORK_METHODDEF
12205 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12206 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12207 OS_SCHED_GETPARAM_METHODDEF
12208 OS_SCHED_GETSCHEDULER_METHODDEF
12209 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12210 OS_SCHED_SETPARAM_METHODDEF
12211 OS_SCHED_SETSCHEDULER_METHODDEF
12212 OS_SCHED_YIELD_METHODDEF
12213 OS_SCHED_SETAFFINITY_METHODDEF
12214 OS_SCHED_GETAFFINITY_METHODDEF
12215 OS_OPENPTY_METHODDEF
12216 OS_FORKPTY_METHODDEF
12217 OS_GETEGID_METHODDEF
12218 OS_GETEUID_METHODDEF
12219 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012220#ifdef HAVE_GETGROUPLIST
12221 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12222#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012223 OS_GETGROUPS_METHODDEF
12224 OS_GETPID_METHODDEF
12225 OS_GETPGRP_METHODDEF
12226 OS_GETPPID_METHODDEF
12227 OS_GETUID_METHODDEF
12228 OS_GETLOGIN_METHODDEF
12229 OS_KILL_METHODDEF
12230 OS_KILLPG_METHODDEF
12231 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012232#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012233 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012234#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012235 OS_SETUID_METHODDEF
12236 OS_SETEUID_METHODDEF
12237 OS_SETREUID_METHODDEF
12238 OS_SETGID_METHODDEF
12239 OS_SETEGID_METHODDEF
12240 OS_SETREGID_METHODDEF
12241 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012242#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012243 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012244#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012245 OS_GETPGID_METHODDEF
12246 OS_SETPGRP_METHODDEF
12247 OS_WAIT_METHODDEF
12248 OS_WAIT3_METHODDEF
12249 OS_WAIT4_METHODDEF
12250 OS_WAITID_METHODDEF
12251 OS_WAITPID_METHODDEF
12252 OS_GETSID_METHODDEF
12253 OS_SETSID_METHODDEF
12254 OS_SETPGID_METHODDEF
12255 OS_TCGETPGRP_METHODDEF
12256 OS_TCSETPGRP_METHODDEF
12257 OS_OPEN_METHODDEF
12258 OS_CLOSE_METHODDEF
12259 OS_CLOSERANGE_METHODDEF
12260 OS_DEVICE_ENCODING_METHODDEF
12261 OS_DUP_METHODDEF
12262 OS_DUP2_METHODDEF
12263 OS_LOCKF_METHODDEF
12264 OS_LSEEK_METHODDEF
12265 OS_READ_METHODDEF
12266 OS_READV_METHODDEF
12267 OS_PREAD_METHODDEF
12268 OS_WRITE_METHODDEF
12269 OS_WRITEV_METHODDEF
12270 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012271#ifdef HAVE_SENDFILE
12272 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12273 posix_sendfile__doc__},
12274#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012275 OS_FSTAT_METHODDEF
12276 OS_ISATTY_METHODDEF
12277 OS_PIPE_METHODDEF
12278 OS_PIPE2_METHODDEF
12279 OS_MKFIFO_METHODDEF
12280 OS_MKNOD_METHODDEF
12281 OS_MAJOR_METHODDEF
12282 OS_MINOR_METHODDEF
12283 OS_MAKEDEV_METHODDEF
12284 OS_FTRUNCATE_METHODDEF
12285 OS_TRUNCATE_METHODDEF
12286 OS_POSIX_FALLOCATE_METHODDEF
12287 OS_POSIX_FADVISE_METHODDEF
12288 OS_PUTENV_METHODDEF
12289 OS_UNSETENV_METHODDEF
12290 OS_STRERROR_METHODDEF
12291 OS_FCHDIR_METHODDEF
12292 OS_FSYNC_METHODDEF
12293 OS_SYNC_METHODDEF
12294 OS_FDATASYNC_METHODDEF
12295 OS_WCOREDUMP_METHODDEF
12296 OS_WIFCONTINUED_METHODDEF
12297 OS_WIFSTOPPED_METHODDEF
12298 OS_WIFSIGNALED_METHODDEF
12299 OS_WIFEXITED_METHODDEF
12300 OS_WEXITSTATUS_METHODDEF
12301 OS_WTERMSIG_METHODDEF
12302 OS_WSTOPSIG_METHODDEF
12303 OS_FSTATVFS_METHODDEF
12304 OS_STATVFS_METHODDEF
12305 OS_CONFSTR_METHODDEF
12306 OS_SYSCONF_METHODDEF
12307 OS_FPATHCONF_METHODDEF
12308 OS_PATHCONF_METHODDEF
12309 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012310 OS__GETFULLPATHNAME_METHODDEF
12311 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012312 OS__GETDISKUSAGE_METHODDEF
12313 OS__GETFINALPATHNAME_METHODDEF
12314 OS__GETVOLUMEPATHNAME_METHODDEF
12315 OS_GETLOADAVG_METHODDEF
12316 OS_URANDOM_METHODDEF
12317 OS_SETRESUID_METHODDEF
12318 OS_SETRESGID_METHODDEF
12319 OS_GETRESUID_METHODDEF
12320 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012321
Larry Hastings2f936352014-08-05 14:04:04 +100012322 OS_GETXATTR_METHODDEF
12323 OS_SETXATTR_METHODDEF
12324 OS_REMOVEXATTR_METHODDEF
12325 OS_LISTXATTR_METHODDEF
12326
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012327#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12328 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12329#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012330 OS_CPU_COUNT_METHODDEF
12331 OS_GET_INHERITABLE_METHODDEF
12332 OS_SET_INHERITABLE_METHODDEF
12333 OS_GET_HANDLE_INHERITABLE_METHODDEF
12334 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012335#ifndef MS_WINDOWS
12336 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12337 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12338#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012339 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012340 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012341 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012342 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012343};
12344
12345
Brian Curtin52173d42010-12-02 18:29:18 +000012346#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012347static int
Brian Curtin52173d42010-12-02 18:29:18 +000012348enable_symlink()
12349{
12350 HANDLE tok;
12351 TOKEN_PRIVILEGES tok_priv;
12352 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012353
12354 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012355 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012356
12357 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012358 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012359
12360 tok_priv.PrivilegeCount = 1;
12361 tok_priv.Privileges[0].Luid = luid;
12362 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12363
12364 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12365 sizeof(TOKEN_PRIVILEGES),
12366 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012367 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012368
Brian Curtin3b4499c2010-12-28 14:31:47 +000012369 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12370 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012371}
12372#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12373
Barry Warsaw4a342091996-12-19 23:50:02 +000012374static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012375all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012376{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012377#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012378 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012379#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012380#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012381 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012382#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012383#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012384 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012385#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012386#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012387 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012388#endif
Fred Drakec9680921999-12-13 16:37:25 +000012389#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012390 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012391#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012392#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012393 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012394#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012395#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012396 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012397#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012398#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012399 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012400#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012401#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012402 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012403#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012404#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012405 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012406#endif
12407#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012408 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012409#endif
12410#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012411 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012412#endif
12413#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012414 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012415#endif
12416#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012417 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012418#endif
12419#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012420 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012421#endif
12422#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012423 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012424#endif
12425#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012426 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012427#endif
12428#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012429 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012430#endif
12431#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012433#endif
12434#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012435 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012436#endif
12437#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012438 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012439#endif
12440#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012441 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012442#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012443#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012445#endif
12446#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012447 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012448#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012449#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012450 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012451#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012452#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012453 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012454#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012455#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012456#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012457 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012458#endif
12459#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012460 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012461#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012462#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012463#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012464 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012465#endif
12466#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012468#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012469#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012470 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012471#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012472#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012473 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012474#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012475#ifdef O_TMPFILE
12476 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12477#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012478#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012480#endif
12481#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012483#endif
12484#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012486#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012487#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012489#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012490#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012492#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012493
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012494
Jesus Cea94363612012-06-22 18:32:07 +020012495#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012497#endif
12498#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012499 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012500#endif
12501
Tim Peters5aa91602002-01-30 05:46:57 +000012502/* MS Windows */
12503#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012504 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012505 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012506#endif
12507#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012508 /* Optimize for short life (keep in memory). */
12509 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012510 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012511#endif
12512#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012513 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012514 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012515#endif
12516#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012517 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012518 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012519#endif
12520#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012521 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012522 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012523#endif
12524
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012525/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012526#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012527 /* Send a SIGIO signal whenever input or output
12528 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012530#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012531#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012532 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012533 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012534#endif
12535#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012536 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012537 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012538#endif
12539#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012540 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012541 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012542#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012543#ifdef O_NOLINKS
12544 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012545 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012546#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012547#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012548 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012549 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012550#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012551
Victor Stinner8c62be82010-05-06 00:08:46 +000012552 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012553#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012555#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012556#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012557 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012558#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012559#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012560 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012561#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012562#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012563 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012564#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012565#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012567#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012568#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012569 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012570#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012571#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012573#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012574#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012576#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012577#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012578 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012579#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012580#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012581 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012582#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012583#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012584 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012585#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012586#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012587 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012588#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012589#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012591#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012592#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012594#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012595#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012597#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012598#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012600#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012601#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012603#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012604
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012605 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012606#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012607 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012608#endif /* ST_RDONLY */
12609#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012611#endif /* ST_NOSUID */
12612
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012613 /* GNU extensions */
12614#ifdef ST_NODEV
12615 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12616#endif /* ST_NODEV */
12617#ifdef ST_NOEXEC
12618 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12619#endif /* ST_NOEXEC */
12620#ifdef ST_SYNCHRONOUS
12621 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12622#endif /* ST_SYNCHRONOUS */
12623#ifdef ST_MANDLOCK
12624 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12625#endif /* ST_MANDLOCK */
12626#ifdef ST_WRITE
12627 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12628#endif /* ST_WRITE */
12629#ifdef ST_APPEND
12630 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12631#endif /* ST_APPEND */
12632#ifdef ST_NOATIME
12633 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12634#endif /* ST_NOATIME */
12635#ifdef ST_NODIRATIME
12636 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12637#endif /* ST_NODIRATIME */
12638#ifdef ST_RELATIME
12639 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12640#endif /* ST_RELATIME */
12641
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012642 /* FreeBSD sendfile() constants */
12643#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012645#endif
12646#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012648#endif
12649#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012651#endif
12652
Ross Lagerwall7807c352011-03-17 20:20:30 +020012653 /* constants for posix_fadvise */
12654#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012656#endif
12657#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012659#endif
12660#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012662#endif
12663#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012665#endif
12666#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012668#endif
12669#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012671#endif
12672
12673 /* constants for waitid */
12674#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12676 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12677 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012678#endif
12679#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012681#endif
12682#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684#endif
12685#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012693#endif
12694#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012699#endif
12700
12701 /* constants for lockf */
12702#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012704#endif
12705#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012707#endif
12708#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012709 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012710#endif
12711#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012712 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012713#endif
12714
Guido van Rossum246bc171999-02-01 23:54:31 +000012715#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12717 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12718 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12719 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12720 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012721#endif
12722
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012723#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012724#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012726#endif
12727#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012729#endif
12730#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012732#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012733#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012735#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012736#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012738#endif
12739#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012741#endif
12742#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012744#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012745#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012747#endif
12748#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012750#endif
12751#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012753#endif
12754#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012755 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012756#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012757#endif
12758
Benjamin Peterson9428d532011-09-14 11:45:52 -040012759#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12761 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12762 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012763#endif
12764
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012765#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012767#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012768#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012770#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012771#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012773#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012774#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012776#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012777#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012778 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012779#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012780#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012781 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012782#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012783#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012784 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012785#endif
12786
Victor Stinner9b1f4742016-09-06 16:18:52 -070012787#ifdef HAVE_GETRANDOM_SYSCALL
12788 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12789 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12790#endif
12791
Victor Stinner8c62be82010-05-06 00:08:46 +000012792 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012793}
12794
12795
Martin v. Löwis1a214512008-06-11 05:26:20 +000012796static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012797 PyModuleDef_HEAD_INIT,
12798 MODNAME,
12799 posix__doc__,
12800 -1,
12801 posix_methods,
12802 NULL,
12803 NULL,
12804 NULL,
12805 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012806};
12807
12808
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012809static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012810
12811#ifdef HAVE_FACCESSAT
12812 "HAVE_FACCESSAT",
12813#endif
12814
12815#ifdef HAVE_FCHDIR
12816 "HAVE_FCHDIR",
12817#endif
12818
12819#ifdef HAVE_FCHMOD
12820 "HAVE_FCHMOD",
12821#endif
12822
12823#ifdef HAVE_FCHMODAT
12824 "HAVE_FCHMODAT",
12825#endif
12826
12827#ifdef HAVE_FCHOWN
12828 "HAVE_FCHOWN",
12829#endif
12830
Larry Hastings00964ed2013-08-12 13:49:30 -040012831#ifdef HAVE_FCHOWNAT
12832 "HAVE_FCHOWNAT",
12833#endif
12834
Larry Hastings9cf065c2012-06-22 16:30:09 -070012835#ifdef HAVE_FEXECVE
12836 "HAVE_FEXECVE",
12837#endif
12838
12839#ifdef HAVE_FDOPENDIR
12840 "HAVE_FDOPENDIR",
12841#endif
12842
Georg Brandl306336b2012-06-24 12:55:33 +020012843#ifdef HAVE_FPATHCONF
12844 "HAVE_FPATHCONF",
12845#endif
12846
Larry Hastings9cf065c2012-06-22 16:30:09 -070012847#ifdef HAVE_FSTATAT
12848 "HAVE_FSTATAT",
12849#endif
12850
12851#ifdef HAVE_FSTATVFS
12852 "HAVE_FSTATVFS",
12853#endif
12854
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012855#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012856 "HAVE_FTRUNCATE",
12857#endif
12858
Larry Hastings9cf065c2012-06-22 16:30:09 -070012859#ifdef HAVE_FUTIMENS
12860 "HAVE_FUTIMENS",
12861#endif
12862
12863#ifdef HAVE_FUTIMES
12864 "HAVE_FUTIMES",
12865#endif
12866
12867#ifdef HAVE_FUTIMESAT
12868 "HAVE_FUTIMESAT",
12869#endif
12870
12871#ifdef HAVE_LINKAT
12872 "HAVE_LINKAT",
12873#endif
12874
12875#ifdef HAVE_LCHFLAGS
12876 "HAVE_LCHFLAGS",
12877#endif
12878
12879#ifdef HAVE_LCHMOD
12880 "HAVE_LCHMOD",
12881#endif
12882
12883#ifdef HAVE_LCHOWN
12884 "HAVE_LCHOWN",
12885#endif
12886
12887#ifdef HAVE_LSTAT
12888 "HAVE_LSTAT",
12889#endif
12890
12891#ifdef HAVE_LUTIMES
12892 "HAVE_LUTIMES",
12893#endif
12894
12895#ifdef HAVE_MKDIRAT
12896 "HAVE_MKDIRAT",
12897#endif
12898
12899#ifdef HAVE_MKFIFOAT
12900 "HAVE_MKFIFOAT",
12901#endif
12902
12903#ifdef HAVE_MKNODAT
12904 "HAVE_MKNODAT",
12905#endif
12906
12907#ifdef HAVE_OPENAT
12908 "HAVE_OPENAT",
12909#endif
12910
12911#ifdef HAVE_READLINKAT
12912 "HAVE_READLINKAT",
12913#endif
12914
12915#ifdef HAVE_RENAMEAT
12916 "HAVE_RENAMEAT",
12917#endif
12918
12919#ifdef HAVE_SYMLINKAT
12920 "HAVE_SYMLINKAT",
12921#endif
12922
12923#ifdef HAVE_UNLINKAT
12924 "HAVE_UNLINKAT",
12925#endif
12926
12927#ifdef HAVE_UTIMENSAT
12928 "HAVE_UTIMENSAT",
12929#endif
12930
12931#ifdef MS_WINDOWS
12932 "MS_WINDOWS",
12933#endif
12934
12935 NULL
12936};
12937
12938
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012939PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012940INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012941{
Victor Stinner8c62be82010-05-06 00:08:46 +000012942 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012943 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012944 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012945
Brian Curtin52173d42010-12-02 18:29:18 +000012946#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012947 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012948#endif
12949
Victor Stinner8c62be82010-05-06 00:08:46 +000012950 m = PyModule_Create(&posixmodule);
12951 if (m == NULL)
12952 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012953
Victor Stinner8c62be82010-05-06 00:08:46 +000012954 /* Initialize environ dictionary */
12955 v = convertenviron();
12956 Py_XINCREF(v);
12957 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12958 return NULL;
12959 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012960
Victor Stinner8c62be82010-05-06 00:08:46 +000012961 if (all_ins(m))
12962 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012963
Victor Stinner8c62be82010-05-06 00:08:46 +000012964 if (setup_confname_tables(m))
12965 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012966
Victor Stinner8c62be82010-05-06 00:08:46 +000012967 Py_INCREF(PyExc_OSError);
12968 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012969
Guido van Rossumb3d39562000-01-31 18:41:26 +000012970#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012971 if (posix_putenv_garbage == NULL)
12972 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012973#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012974
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012976#if defined(HAVE_WAITID) && !defined(__APPLE__)
12977 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012978 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12979 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012980#endif
12981
Christian Heimes25827622013-10-12 01:27:08 +020012982 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012983 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12984 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12985 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012986 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12987 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012988 structseq_new = StatResultType.tp_new;
12989 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012990
Christian Heimes25827622013-10-12 01:27:08 +020012991 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012992 if (PyStructSequence_InitType2(&StatVFSResultType,
12993 &statvfs_result_desc) < 0)
12994 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012995#ifdef NEED_TICKS_PER_SECOND
12996# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012998# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012999 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013000# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013002# endif
13003#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013004
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013005#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013006 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013007 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13008 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013009 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013010#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013011
13012 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013013 if (PyStructSequence_InitType2(&TerminalSizeType,
13014 &TerminalSize_desc) < 0)
13015 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013016
13017 /* initialize scandir types */
13018 if (PyType_Ready(&ScandirIteratorType) < 0)
13019 return NULL;
13020 if (PyType_Ready(&DirEntryType) < 0)
13021 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013022 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013023#if defined(HAVE_WAITID) && !defined(__APPLE__)
13024 Py_INCREF((PyObject*) &WaitidResultType);
13025 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13026#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013027 Py_INCREF((PyObject*) &StatResultType);
13028 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13029 Py_INCREF((PyObject*) &StatVFSResultType);
13030 PyModule_AddObject(m, "statvfs_result",
13031 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013032
13033#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013034 Py_INCREF(&SchedParamType);
13035 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013036#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013037
Larry Hastings605a62d2012-06-24 04:33:36 -070013038 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013039 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13040 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013041 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13042
13043 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013044 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13045 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013046 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13047
Thomas Wouters477c8d52006-05-27 19:21:47 +000013048#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013049 /*
13050 * Step 2 of weak-linking support on Mac OS X.
13051 *
13052 * The code below removes functions that are not available on the
13053 * currently active platform.
13054 *
13055 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013056 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013057 * OSX 10.4.
13058 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013059#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013060 if (fstatvfs == NULL) {
13061 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13062 return NULL;
13063 }
13064 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013065#endif /* HAVE_FSTATVFS */
13066
13067#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013068 if (statvfs == NULL) {
13069 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13070 return NULL;
13071 }
13072 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013073#endif /* HAVE_STATVFS */
13074
13075# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013076 if (lchown == NULL) {
13077 if (PyObject_DelAttrString(m, "lchown") == -1) {
13078 return NULL;
13079 }
13080 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013081#endif /* HAVE_LCHOWN */
13082
13083
13084#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013085
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013086 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013087 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13088
Larry Hastings6fe20b32012-04-19 15:07:49 -070013089 billion = PyLong_FromLong(1000000000);
13090 if (!billion)
13091 return NULL;
13092
Larry Hastings9cf065c2012-06-22 16:30:09 -070013093 /* suppress "function not used" warnings */
13094 {
13095 int ignored;
13096 fd_specified("", -1);
13097 follow_symlinks_specified("", 1);
13098 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13099 dir_fd_converter(Py_None, &ignored);
13100 dir_fd_unavailable(Py_None, &ignored);
13101 }
13102
13103 /*
13104 * provide list of locally available functions
13105 * so os.py can populate support_* lists
13106 */
13107 list = PyList_New(0);
13108 if (!list)
13109 return NULL;
13110 for (trace = have_functions; *trace; trace++) {
13111 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13112 if (!unicode)
13113 return NULL;
13114 if (PyList_Append(list, unicode))
13115 return NULL;
13116 Py_DECREF(unicode);
13117 }
13118 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013119
13120 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013121 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013122
13123 initialized = 1;
13124
Victor Stinner8c62be82010-05-06 00:08:46 +000013125 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013126}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013127
13128#ifdef __cplusplus
13129}
13130#endif