blob: ffe4815d66d16a016b11c5923fcf05e7f0488af5 [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;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001874 Py_RETURN_NONE;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001875}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001876
Larry Hastings6fe20b32012-04-19 15:07:49 -07001877static PyObject *billion = NULL;
1878
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001879static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001880fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001881{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001882 PyObject *s = _PyLong_FromTime_t(sec);
1883 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1884 PyObject *s_in_ns = NULL;
1885 PyObject *ns_total = NULL;
1886 PyObject *float_s = NULL;
1887
1888 if (!(s && ns_fractional))
1889 goto exit;
1890
1891 s_in_ns = PyNumber_Multiply(s, billion);
1892 if (!s_in_ns)
1893 goto exit;
1894
1895 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1896 if (!ns_total)
1897 goto exit;
1898
Victor Stinner4195b5c2012-02-08 23:03:19 +01001899 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001900 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1901 if (!float_s)
1902 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001904 else {
1905 float_s = s;
1906 Py_INCREF(float_s);
1907 }
1908
1909 PyStructSequence_SET_ITEM(v, index, s);
1910 PyStructSequence_SET_ITEM(v, index+3, float_s);
1911 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1912 s = NULL;
1913 float_s = NULL;
1914 ns_total = NULL;
1915exit:
1916 Py_XDECREF(s);
1917 Py_XDECREF(ns_fractional);
1918 Py_XDECREF(s_in_ns);
1919 Py_XDECREF(ns_total);
1920 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001921}
1922
Tim Peters5aa91602002-01-30 05:46:57 +00001923/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001924 (used by posix_stat() and posix_fstat()) */
1925static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001926_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001927{
Victor Stinner8c62be82010-05-06 00:08:46 +00001928 unsigned long ansec, mnsec, cnsec;
1929 PyObject *v = PyStructSequence_New(&StatResultType);
1930 if (v == NULL)
1931 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001932
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001934#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001936 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001937#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001939#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001940#ifdef MS_WINDOWS
1941 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001942#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001943 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001944#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001945 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001946#if defined(MS_WINDOWS)
1947 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1948 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1949#else
1950 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1951 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1952#endif
Fred Drake699f3522000-06-29 21:12:41 +00001953#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001954 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001955 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001956#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001957 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001958#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001959
Martin v. Löwis14694662006-02-03 12:54:16 +00001960#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001961 ansec = st->st_atim.tv_nsec;
1962 mnsec = st->st_mtim.tv_nsec;
1963 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001964#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 ansec = st->st_atimespec.tv_nsec;
1966 mnsec = st->st_mtimespec.tv_nsec;
1967 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001968#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001969 ansec = st->st_atime_nsec;
1970 mnsec = st->st_mtime_nsec;
1971 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001972#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001975 fill_time(v, 7, st->st_atime, ansec);
1976 fill_time(v, 8, st->st_mtime, mnsec);
1977 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001978
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001979#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1981 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001982#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001983#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001984 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1985 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001986#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001987#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001988 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1989 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001990#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001991#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001992 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1993 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001994#endif
1995#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001997 PyObject *val;
1998 unsigned long bsec,bnsec;
1999 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002000#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002001 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002002#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002003 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002004#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002005 if (_stat_float_times) {
2006 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2007 } else {
2008 val = PyLong_FromLong((long)bsec);
2009 }
2010 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2011 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002012 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002013#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002014#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2016 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002017#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002018#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2019 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2020 PyLong_FromUnsignedLong(st->st_file_attributes));
2021#endif
Fred Drake699f3522000-06-29 21:12:41 +00002022
Victor Stinner8c62be82010-05-06 00:08:46 +00002023 if (PyErr_Occurred()) {
2024 Py_DECREF(v);
2025 return NULL;
2026 }
Fred Drake699f3522000-06-29 21:12:41 +00002027
Victor Stinner8c62be82010-05-06 00:08:46 +00002028 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002029}
2030
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002031/* POSIX methods */
2032
Guido van Rossum94f6f721999-01-06 18:42:14 +00002033
2034static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002035posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002036 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002037{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002038 STRUCT_STAT st;
2039 int result;
2040
2041#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2042 if (follow_symlinks_specified(function_name, follow_symlinks))
2043 return NULL;
2044#endif
2045
2046 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2047 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2048 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2049 return NULL;
2050
2051 Py_BEGIN_ALLOW_THREADS
2052 if (path->fd != -1)
2053 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002054#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002055 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002056 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002057 else
Steve Dowercc16be82016-09-08 10:35:16 -07002058 result = win32_lstat(path->wide, &st);
2059#else
2060 else
2061#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002062 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2063 result = LSTAT(path->narrow, &st);
2064 else
Steve Dowercc16be82016-09-08 10:35:16 -07002065#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002066#ifdef HAVE_FSTATAT
2067 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2068 result = fstatat(dir_fd, path->narrow, &st,
2069 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2070 else
Steve Dowercc16be82016-09-08 10:35:16 -07002071#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002072 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002073#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002074 Py_END_ALLOW_THREADS
2075
Victor Stinner292c8352012-10-30 02:17:38 +01002076 if (result != 0) {
2077 return path_error(path);
2078 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002079
2080 return _pystat_fromstructstat(&st);
2081}
2082
Larry Hastings2f936352014-08-05 14:04:04 +10002083/*[python input]
2084
2085for s in """
2086
2087FACCESSAT
2088FCHMODAT
2089FCHOWNAT
2090FSTATAT
2091LINKAT
2092MKDIRAT
2093MKFIFOAT
2094MKNODAT
2095OPENAT
2096READLINKAT
2097SYMLINKAT
2098UNLINKAT
2099
2100""".strip().split():
2101 s = s.strip()
2102 print("""
2103#ifdef HAVE_{s}
2104 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002105#else
Larry Hastings2f936352014-08-05 14:04:04 +10002106 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002107#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002108""".rstrip().format(s=s))
2109
2110for s in """
2111
2112FCHDIR
2113FCHMOD
2114FCHOWN
2115FDOPENDIR
2116FEXECVE
2117FPATHCONF
2118FSTATVFS
2119FTRUNCATE
2120
2121""".strip().split():
2122 s = s.strip()
2123 print("""
2124#ifdef HAVE_{s}
2125 #define PATH_HAVE_{s} 1
2126#else
2127 #define PATH_HAVE_{s} 0
2128#endif
2129
2130""".rstrip().format(s=s))
2131[python start generated code]*/
2132
2133#ifdef HAVE_FACCESSAT
2134 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2135#else
2136 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2137#endif
2138
2139#ifdef HAVE_FCHMODAT
2140 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2141#else
2142 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2143#endif
2144
2145#ifdef HAVE_FCHOWNAT
2146 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2147#else
2148 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2149#endif
2150
2151#ifdef HAVE_FSTATAT
2152 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2153#else
2154 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2155#endif
2156
2157#ifdef HAVE_LINKAT
2158 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2159#else
2160 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2161#endif
2162
2163#ifdef HAVE_MKDIRAT
2164 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2165#else
2166 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2167#endif
2168
2169#ifdef HAVE_MKFIFOAT
2170 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2171#else
2172 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2173#endif
2174
2175#ifdef HAVE_MKNODAT
2176 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2177#else
2178 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2179#endif
2180
2181#ifdef HAVE_OPENAT
2182 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2183#else
2184 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2185#endif
2186
2187#ifdef HAVE_READLINKAT
2188 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2189#else
2190 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2191#endif
2192
2193#ifdef HAVE_SYMLINKAT
2194 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2195#else
2196 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2197#endif
2198
2199#ifdef HAVE_UNLINKAT
2200 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2201#else
2202 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2203#endif
2204
2205#ifdef HAVE_FCHDIR
2206 #define PATH_HAVE_FCHDIR 1
2207#else
2208 #define PATH_HAVE_FCHDIR 0
2209#endif
2210
2211#ifdef HAVE_FCHMOD
2212 #define PATH_HAVE_FCHMOD 1
2213#else
2214 #define PATH_HAVE_FCHMOD 0
2215#endif
2216
2217#ifdef HAVE_FCHOWN
2218 #define PATH_HAVE_FCHOWN 1
2219#else
2220 #define PATH_HAVE_FCHOWN 0
2221#endif
2222
2223#ifdef HAVE_FDOPENDIR
2224 #define PATH_HAVE_FDOPENDIR 1
2225#else
2226 #define PATH_HAVE_FDOPENDIR 0
2227#endif
2228
2229#ifdef HAVE_FEXECVE
2230 #define PATH_HAVE_FEXECVE 1
2231#else
2232 #define PATH_HAVE_FEXECVE 0
2233#endif
2234
2235#ifdef HAVE_FPATHCONF
2236 #define PATH_HAVE_FPATHCONF 1
2237#else
2238 #define PATH_HAVE_FPATHCONF 0
2239#endif
2240
2241#ifdef HAVE_FSTATVFS
2242 #define PATH_HAVE_FSTATVFS 1
2243#else
2244 #define PATH_HAVE_FSTATVFS 0
2245#endif
2246
2247#ifdef HAVE_FTRUNCATE
2248 #define PATH_HAVE_FTRUNCATE 1
2249#else
2250 #define PATH_HAVE_FTRUNCATE 0
2251#endif
2252/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002253
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002254#ifdef MS_WINDOWS
2255 #undef PATH_HAVE_FTRUNCATE
2256 #define PATH_HAVE_FTRUNCATE 1
2257#endif
Larry Hastings31826802013-10-19 00:09:25 -07002258
Larry Hastings61272b72014-01-07 12:41:53 -08002259/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002260
2261class path_t_converter(CConverter):
2262
2263 type = "path_t"
2264 impl_by_reference = True
2265 parse_by_reference = True
2266
2267 converter = 'path_converter'
2268
2269 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002270 # right now path_t doesn't support default values.
2271 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002272 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002273 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002274
Larry Hastings2f936352014-08-05 14:04:04 +10002275 if self.c_default not in (None, 'Py_None'):
2276 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002277
2278 self.nullable = nullable
2279 self.allow_fd = allow_fd
2280
Larry Hastings7726ac92014-01-31 22:03:12 -08002281 def pre_render(self):
2282 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002283 if isinstance(value, str):
2284 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002285 return str(int(bool(value)))
2286
2287 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002288 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002289 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002290 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002291 strify(self.nullable),
2292 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002293 )
2294
2295 def cleanup(self):
2296 return "path_cleanup(&" + self.name + ");\n"
2297
2298
2299class dir_fd_converter(CConverter):
2300 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002301
Larry Hastings2f936352014-08-05 14:04:04 +10002302 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002303 if self.default in (unspecified, None):
2304 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002305 if isinstance(requires, str):
2306 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2307 else:
2308 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002309
Larry Hastings2f936352014-08-05 14:04:04 +10002310class fildes_converter(CConverter):
2311 type = 'int'
2312 converter = 'fildes_converter'
2313
2314class uid_t_converter(CConverter):
2315 type = "uid_t"
2316 converter = '_Py_Uid_Converter'
2317
2318class gid_t_converter(CConverter):
2319 type = "gid_t"
2320 converter = '_Py_Gid_Converter'
2321
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002322class dev_t_converter(CConverter):
2323 type = 'dev_t'
2324 converter = '_Py_Dev_Converter'
2325
2326class dev_t_return_converter(unsigned_long_return_converter):
2327 type = 'dev_t'
2328 conversion_fn = '_PyLong_FromDev'
2329 unsigned_cast = '(dev_t)'
2330
Larry Hastings2f936352014-08-05 14:04:04 +10002331class FSConverter_converter(CConverter):
2332 type = 'PyObject *'
2333 converter = 'PyUnicode_FSConverter'
2334 def converter_init(self):
2335 if self.default is not unspecified:
2336 fail("FSConverter_converter does not support default values")
2337 self.c_default = 'NULL'
2338
2339 def cleanup(self):
2340 return "Py_XDECREF(" + self.name + ");\n"
2341
2342class pid_t_converter(CConverter):
2343 type = 'pid_t'
2344 format_unit = '" _Py_PARSE_PID "'
2345
2346class idtype_t_converter(int_converter):
2347 type = 'idtype_t'
2348
2349class id_t_converter(CConverter):
2350 type = 'id_t'
2351 format_unit = '" _Py_PARSE_PID "'
2352
Benjamin Petersonca470632016-09-06 13:47:26 -07002353class intptr_t_converter(CConverter):
2354 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002355 format_unit = '" _Py_PARSE_INTPTR "'
2356
2357class Py_off_t_converter(CConverter):
2358 type = 'Py_off_t'
2359 converter = 'Py_off_t_converter'
2360
2361class Py_off_t_return_converter(long_return_converter):
2362 type = 'Py_off_t'
2363 conversion_fn = 'PyLong_FromPy_off_t'
2364
2365class path_confname_converter(CConverter):
2366 type="int"
2367 converter="conv_path_confname"
2368
2369class confstr_confname_converter(path_confname_converter):
2370 converter='conv_confstr_confname'
2371
2372class sysconf_confname_converter(path_confname_converter):
2373 converter="conv_sysconf_confname"
2374
2375class sched_param_converter(CConverter):
2376 type = 'struct sched_param'
2377 converter = 'convert_sched_param'
2378 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002379
Larry Hastings61272b72014-01-07 12:41:53 -08002380[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002381/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002382
Larry Hastings61272b72014-01-07 12:41:53 -08002383/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002384
Larry Hastings2a727912014-01-16 11:32:01 -08002385os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002386
2387 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002388 Path to be examined; can be string, bytes, path-like object or
2389 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002390
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)
Xiang Zhang4459e002017-01-22 13:04:17 +08002416/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
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
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006196 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006197}
Larry Hastings2f936352014-08-05 14:04:04 +10006198#endif /* HAVE_INITGROUPS */
6199
Antoine Pitroub7572f02009-12-02 20:46:48 +00006200
Martin v. Löwis606edc12002-06-13 21:09:11 +00006201#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006202/*[clinic input]
6203os.getpgid
6204
6205 pid: pid_t
6206
6207Call the system call getpgid(), and return the result.
6208[clinic start generated code]*/
6209
Larry Hastings2f936352014-08-05 14:04:04 +10006210static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006211os_getpgid_impl(PyObject *module, pid_t pid)
6212/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006213{
6214 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 if (pgid < 0)
6216 return posix_error();
6217 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006218}
6219#endif /* HAVE_GETPGID */
6220
6221
Guido van Rossumb6775db1994-08-01 11:34:53 +00006222#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006223/*[clinic input]
6224os.getpgrp
6225
6226Return the current process group id.
6227[clinic start generated code]*/
6228
Larry Hastings2f936352014-08-05 14:04:04 +10006229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006230os_getpgrp_impl(PyObject *module)
6231/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006232{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006233#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006235#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006237#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006238}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006239#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006241
Guido van Rossumb6775db1994-08-01 11:34:53 +00006242#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006243/*[clinic input]
6244os.setpgrp
6245
6246Make the current process the leader of its process group.
6247[clinic start generated code]*/
6248
Larry Hastings2f936352014-08-05 14:04:04 +10006249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006250os_setpgrp_impl(PyObject *module)
6251/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006252{
Guido van Rossum64933891994-10-20 21:56:42 +00006253#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006255#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006257#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006259 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006260}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006261#endif /* HAVE_SETPGRP */
6262
Guido van Rossumad0ee831995-03-01 10:34:45 +00006263#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006264
6265#ifdef MS_WINDOWS
6266#include <tlhelp32.h>
6267
6268static PyObject*
6269win32_getppid()
6270{
6271 HANDLE snapshot;
6272 pid_t mypid;
6273 PyObject* result = NULL;
6274 BOOL have_record;
6275 PROCESSENTRY32 pe;
6276
6277 mypid = getpid(); /* This function never fails */
6278
6279 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6280 if (snapshot == INVALID_HANDLE_VALUE)
6281 return PyErr_SetFromWindowsErr(GetLastError());
6282
6283 pe.dwSize = sizeof(pe);
6284 have_record = Process32First(snapshot, &pe);
6285 while (have_record) {
6286 if (mypid == (pid_t)pe.th32ProcessID) {
6287 /* We could cache the ulong value in a static variable. */
6288 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6289 break;
6290 }
6291
6292 have_record = Process32Next(snapshot, &pe);
6293 }
6294
6295 /* If our loop exits and our pid was not found (result will be NULL)
6296 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6297 * error anyway, so let's raise it. */
6298 if (!result)
6299 result = PyErr_SetFromWindowsErr(GetLastError());
6300
6301 CloseHandle(snapshot);
6302
6303 return result;
6304}
6305#endif /*MS_WINDOWS*/
6306
Larry Hastings2f936352014-08-05 14:04:04 +10006307
6308/*[clinic input]
6309os.getppid
6310
6311Return the parent's process id.
6312
6313If the parent process has already exited, Windows machines will still
6314return its id; others systems will return the id of the 'init' process (1).
6315[clinic start generated code]*/
6316
Larry Hastings2f936352014-08-05 14:04:04 +10006317static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006318os_getppid_impl(PyObject *module)
6319/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006320{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006321#ifdef MS_WINDOWS
6322 return win32_getppid();
6323#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006325#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006326}
6327#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006329
Fred Drake12c6e2d1999-12-14 21:25:03 +00006330#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006331/*[clinic input]
6332os.getlogin
6333
6334Return the actual login name.
6335[clinic start generated code]*/
6336
Larry Hastings2f936352014-08-05 14:04:04 +10006337static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006338os_getlogin_impl(PyObject *module)
6339/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006340{
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006342#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006343 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006344 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006345
6346 if (GetUserNameW(user_name, &num_chars)) {
6347 /* num_chars is the number of unicode chars plus null terminator */
6348 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006349 }
6350 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006351 result = PyErr_SetFromWindowsErr(GetLastError());
6352#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 char *name;
6354 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006355
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 errno = 0;
6357 name = getlogin();
6358 if (name == NULL) {
6359 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006360 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006361 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006362 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 }
6364 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006365 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006367#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006368 return result;
6369}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006370#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006371
Larry Hastings2f936352014-08-05 14:04:04 +10006372
Guido van Rossumad0ee831995-03-01 10:34:45 +00006373#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006374/*[clinic input]
6375os.getuid
6376
6377Return the current process's user id.
6378[clinic start generated code]*/
6379
Larry Hastings2f936352014-08-05 14:04:04 +10006380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006381os_getuid_impl(PyObject *module)
6382/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006383{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006384 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006385}
Larry Hastings2f936352014-08-05 14:04:04 +10006386#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006387
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006388
Brian Curtineb24d742010-04-12 17:16:38 +00006389#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006390#define HAVE_KILL
6391#endif /* MS_WINDOWS */
6392
6393#ifdef HAVE_KILL
6394/*[clinic input]
6395os.kill
6396
6397 pid: pid_t
6398 signal: Py_ssize_t
6399 /
6400
6401Kill a process with a signal.
6402[clinic start generated code]*/
6403
Larry Hastings2f936352014-08-05 14:04:04 +10006404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006405os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6406/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006407#ifndef MS_WINDOWS
6408{
6409 if (kill(pid, (int)signal) == -1)
6410 return posix_error();
6411 Py_RETURN_NONE;
6412}
6413#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006414{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006415 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006416 DWORD sig = (DWORD)signal;
6417 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006418 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006419
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 /* Console processes which share a common console can be sent CTRL+C or
6421 CTRL+BREAK events, provided they handle said events. */
6422 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006423 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 err = GetLastError();
6425 PyErr_SetFromWindowsErr(err);
6426 }
6427 else
6428 Py_RETURN_NONE;
6429 }
Brian Curtineb24d742010-04-12 17:16:38 +00006430
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6432 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006433 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 if (handle == NULL) {
6435 err = GetLastError();
6436 return PyErr_SetFromWindowsErr(err);
6437 }
Brian Curtineb24d742010-04-12 17:16:38 +00006438
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 if (TerminateProcess(handle, sig) == 0) {
6440 err = GetLastError();
6441 result = PyErr_SetFromWindowsErr(err);
6442 } else {
6443 Py_INCREF(Py_None);
6444 result = Py_None;
6445 }
Brian Curtineb24d742010-04-12 17:16:38 +00006446
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 CloseHandle(handle);
6448 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006449}
Larry Hastings2f936352014-08-05 14:04:04 +10006450#endif /* !MS_WINDOWS */
6451#endif /* HAVE_KILL */
6452
6453
6454#ifdef HAVE_KILLPG
6455/*[clinic input]
6456os.killpg
6457
6458 pgid: pid_t
6459 signal: int
6460 /
6461
6462Kill a process group with a signal.
6463[clinic start generated code]*/
6464
Larry Hastings2f936352014-08-05 14:04:04 +10006465static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006466os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6467/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006468{
6469 /* XXX some man pages make the `pgid` parameter an int, others
6470 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6471 take the same type. Moreover, pid_t is always at least as wide as
6472 int (else compilation of this module fails), which is safe. */
6473 if (killpg(pgid, signal) == -1)
6474 return posix_error();
6475 Py_RETURN_NONE;
6476}
6477#endif /* HAVE_KILLPG */
6478
Brian Curtineb24d742010-04-12 17:16:38 +00006479
Guido van Rossumc0125471996-06-28 18:55:32 +00006480#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006481#ifdef HAVE_SYS_LOCK_H
6482#include <sys/lock.h>
6483#endif
6484
Larry Hastings2f936352014-08-05 14:04:04 +10006485/*[clinic input]
6486os.plock
6487 op: int
6488 /
6489
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006491[clinic start generated code]*/
6492
Larry Hastings2f936352014-08-05 14:04:04 +10006493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006494os_plock_impl(PyObject *module, int op)
6495/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006496{
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 if (plock(op) == -1)
6498 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006499 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006500}
Larry Hastings2f936352014-08-05 14:04:04 +10006501#endif /* HAVE_PLOCK */
6502
Guido van Rossumc0125471996-06-28 18:55:32 +00006503
Guido van Rossumb6775db1994-08-01 11:34:53 +00006504#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006505/*[clinic input]
6506os.setuid
6507
6508 uid: uid_t
6509 /
6510
6511Set the current process's user id.
6512[clinic start generated code]*/
6513
Larry Hastings2f936352014-08-05 14:04:04 +10006514static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006515os_setuid_impl(PyObject *module, uid_t uid)
6516/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006517{
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 if (setuid(uid) < 0)
6519 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006520 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006521}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006522#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006524
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006525#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006526/*[clinic input]
6527os.seteuid
6528
6529 euid: uid_t
6530 /
6531
6532Set the current process's effective user id.
6533[clinic start generated code]*/
6534
Larry Hastings2f936352014-08-05 14:04:04 +10006535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006536os_seteuid_impl(PyObject *module, uid_t euid)
6537/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006538{
6539 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006541 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006542}
6543#endif /* HAVE_SETEUID */
6544
Larry Hastings2f936352014-08-05 14:04:04 +10006545
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006546#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006547/*[clinic input]
6548os.setegid
6549
6550 egid: gid_t
6551 /
6552
6553Set the current process's effective group id.
6554[clinic start generated code]*/
6555
Larry Hastings2f936352014-08-05 14:04:04 +10006556static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006557os_setegid_impl(PyObject *module, gid_t egid)
6558/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006559{
6560 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006562 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006563}
6564#endif /* HAVE_SETEGID */
6565
Larry Hastings2f936352014-08-05 14:04:04 +10006566
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006567#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006568/*[clinic input]
6569os.setreuid
6570
6571 ruid: uid_t
6572 euid: uid_t
6573 /
6574
6575Set the current process's real and effective user ids.
6576[clinic start generated code]*/
6577
Larry Hastings2f936352014-08-05 14:04:04 +10006578static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006579os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6580/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006581{
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 if (setreuid(ruid, euid) < 0) {
6583 return posix_error();
6584 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006585 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006587}
6588#endif /* HAVE_SETREUID */
6589
Larry Hastings2f936352014-08-05 14:04:04 +10006590
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006591#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006592/*[clinic input]
6593os.setregid
6594
6595 rgid: gid_t
6596 egid: gid_t
6597 /
6598
6599Set the current process's real and effective group ids.
6600[clinic start generated code]*/
6601
Larry Hastings2f936352014-08-05 14:04:04 +10006602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006603os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6604/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006605{
6606 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006608 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006609}
6610#endif /* HAVE_SETREGID */
6611
Larry Hastings2f936352014-08-05 14:04:04 +10006612
Guido van Rossumb6775db1994-08-01 11:34:53 +00006613#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006614/*[clinic input]
6615os.setgid
6616 gid: gid_t
6617 /
6618
6619Set the current process's group id.
6620[clinic start generated code]*/
6621
Larry Hastings2f936352014-08-05 14:04:04 +10006622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006623os_setgid_impl(PyObject *module, gid_t gid)
6624/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006625{
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 if (setgid(gid) < 0)
6627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006628 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006629}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006630#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006631
Larry Hastings2f936352014-08-05 14:04:04 +10006632
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006633#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006634/*[clinic input]
6635os.setgroups
6636
6637 groups: object
6638 /
6639
6640Set the groups of the current process to list.
6641[clinic start generated code]*/
6642
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006644os_setgroups(PyObject *module, PyObject *groups)
6645/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006646{
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 int i, len;
6648 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006649
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 if (!PySequence_Check(groups)) {
6651 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6652 return NULL;
6653 }
6654 len = PySequence_Size(groups);
6655 if (len > MAX_GROUPS) {
6656 PyErr_SetString(PyExc_ValueError, "too many groups");
6657 return NULL;
6658 }
6659 for(i = 0; i < len; i++) {
6660 PyObject *elem;
6661 elem = PySequence_GetItem(groups, i);
6662 if (!elem)
6663 return NULL;
6664 if (!PyLong_Check(elem)) {
6665 PyErr_SetString(PyExc_TypeError,
6666 "groups must be integers");
6667 Py_DECREF(elem);
6668 return NULL;
6669 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006670 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 Py_DECREF(elem);
6672 return NULL;
6673 }
6674 }
6675 Py_DECREF(elem);
6676 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006677
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 if (setgroups(len, grouplist) < 0)
6679 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006680 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006681}
6682#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006683
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006684#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6685static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006686wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006687{
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 PyObject *result;
6689 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006690 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006691
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 if (pid == -1)
6693 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006694
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 if (struct_rusage == NULL) {
6696 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6697 if (m == NULL)
6698 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006699 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 Py_DECREF(m);
6701 if (struct_rusage == NULL)
6702 return NULL;
6703 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006704
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6706 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6707 if (!result)
6708 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006709
6710#ifndef doubletime
6711#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6712#endif
6713
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006715 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006717 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006718#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6720 SET_INT(result, 2, ru->ru_maxrss);
6721 SET_INT(result, 3, ru->ru_ixrss);
6722 SET_INT(result, 4, ru->ru_idrss);
6723 SET_INT(result, 5, ru->ru_isrss);
6724 SET_INT(result, 6, ru->ru_minflt);
6725 SET_INT(result, 7, ru->ru_majflt);
6726 SET_INT(result, 8, ru->ru_nswap);
6727 SET_INT(result, 9, ru->ru_inblock);
6728 SET_INT(result, 10, ru->ru_oublock);
6729 SET_INT(result, 11, ru->ru_msgsnd);
6730 SET_INT(result, 12, ru->ru_msgrcv);
6731 SET_INT(result, 13, ru->ru_nsignals);
6732 SET_INT(result, 14, ru->ru_nvcsw);
6733 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006734#undef SET_INT
6735
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 if (PyErr_Occurred()) {
6737 Py_DECREF(result);
6738 return NULL;
6739 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006740
Victor Stinner8c62be82010-05-06 00:08:46 +00006741 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006742}
6743#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6744
Larry Hastings2f936352014-08-05 14:04:04 +10006745
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006746#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006747/*[clinic input]
6748os.wait3
6749
6750 options: int
6751Wait for completion of a child process.
6752
6753Returns a tuple of information about the child process:
6754 (pid, status, rusage)
6755[clinic start generated code]*/
6756
Larry Hastings2f936352014-08-05 14:04:04 +10006757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006758os_wait3_impl(PyObject *module, int options)
6759/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006760{
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006763 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 WAIT_TYPE status;
6765 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006766
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006767 do {
6768 Py_BEGIN_ALLOW_THREADS
6769 pid = wait3(&status, options, &ru);
6770 Py_END_ALLOW_THREADS
6771 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6772 if (pid < 0)
6773 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006774
Victor Stinner4195b5c2012-02-08 23:03:19 +01006775 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776}
6777#endif /* HAVE_WAIT3 */
6778
Larry Hastings2f936352014-08-05 14:04:04 +10006779
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006780#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006781/*[clinic input]
6782
6783os.wait4
6784
6785 pid: pid_t
6786 options: int
6787
6788Wait for completion of a specific child process.
6789
6790Returns a tuple of information about the child process:
6791 (pid, status, rusage)
6792[clinic start generated code]*/
6793
Larry Hastings2f936352014-08-05 14:04:04 +10006794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006795os_wait4_impl(PyObject *module, pid_t pid, int options)
6796/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006797{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006798 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006800 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 WAIT_TYPE status;
6802 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006803
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006804 do {
6805 Py_BEGIN_ALLOW_THREADS
6806 res = wait4(pid, &status, options, &ru);
6807 Py_END_ALLOW_THREADS
6808 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6809 if (res < 0)
6810 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006811
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006812 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006813}
6814#endif /* HAVE_WAIT4 */
6815
Larry Hastings2f936352014-08-05 14:04:04 +10006816
Ross Lagerwall7807c352011-03-17 20:20:30 +02006817#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006818/*[clinic input]
6819os.waitid
6820
6821 idtype: idtype_t
6822 Must be one of be P_PID, P_PGID or P_ALL.
6823 id: id_t
6824 The id to wait on.
6825 options: int
6826 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6827 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6828 /
6829
6830Returns the result of waiting for a process or processes.
6831
6832Returns either waitid_result or None if WNOHANG is specified and there are
6833no children in a waitable state.
6834[clinic start generated code]*/
6835
Larry Hastings2f936352014-08-05 14:04:04 +10006836static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006837os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6838/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006839{
6840 PyObject *result;
6841 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006842 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006843 siginfo_t si;
6844 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006845
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006846 do {
6847 Py_BEGIN_ALLOW_THREADS
6848 res = waitid(idtype, id, &si, options);
6849 Py_END_ALLOW_THREADS
6850 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6851 if (res < 0)
6852 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006853
6854 if (si.si_pid == 0)
6855 Py_RETURN_NONE;
6856
6857 result = PyStructSequence_New(&WaitidResultType);
6858 if (!result)
6859 return NULL;
6860
6861 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006862 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006863 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6864 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6865 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6866 if (PyErr_Occurred()) {
6867 Py_DECREF(result);
6868 return NULL;
6869 }
6870
6871 return result;
6872}
Larry Hastings2f936352014-08-05 14:04:04 +10006873#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006874
Larry Hastings2f936352014-08-05 14:04:04 +10006875
6876#if defined(HAVE_WAITPID)
6877/*[clinic input]
6878os.waitpid
6879 pid: pid_t
6880 options: int
6881 /
6882
6883Wait for completion of a given child process.
6884
6885Returns a tuple of information regarding the child process:
6886 (pid, status)
6887
6888The options argument is ignored on Windows.
6889[clinic start generated code]*/
6890
Larry Hastings2f936352014-08-05 14:04:04 +10006891static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006892os_waitpid_impl(PyObject *module, pid_t pid, int options)
6893/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006894{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006895 pid_t res;
6896 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 WAIT_TYPE status;
6898 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006899
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006900 do {
6901 Py_BEGIN_ALLOW_THREADS
6902 res = waitpid(pid, &status, options);
6903 Py_END_ALLOW_THREADS
6904 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6905 if (res < 0)
6906 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006908 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006909}
Tim Petersab034fa2002-02-01 11:27:43 +00006910#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006911/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006912/*[clinic input]
6913os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006914 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006915 options: int
6916 /
6917
6918Wait for completion of a given process.
6919
6920Returns a tuple of information regarding the process:
6921 (pid, status << 8)
6922
6923The options argument is ignored on Windows.
6924[clinic start generated code]*/
6925
Larry Hastings2f936352014-08-05 14:04:04 +10006926static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006927os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006928/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006929{
6930 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006931 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006932 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006933
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006934 do {
6935 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006936 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006937 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006938 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006939 Py_END_ALLOW_THREADS
6940 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006941 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006942 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006943
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006945 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006946}
Larry Hastings2f936352014-08-05 14:04:04 +10006947#endif
6948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006949
Guido van Rossumad0ee831995-03-01 10:34:45 +00006950#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006951/*[clinic input]
6952os.wait
6953
6954Wait for completion of a child process.
6955
6956Returns a tuple of information about the child process:
6957 (pid, status)
6958[clinic start generated code]*/
6959
Larry Hastings2f936352014-08-05 14:04:04 +10006960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006961os_wait_impl(PyObject *module)
6962/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006963{
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006965 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 WAIT_TYPE status;
6967 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006968
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006969 do {
6970 Py_BEGIN_ALLOW_THREADS
6971 pid = wait(&status);
6972 Py_END_ALLOW_THREADS
6973 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6974 if (pid < 0)
6975 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006976
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006978}
Larry Hastings2f936352014-08-05 14:04:04 +10006979#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006981
Larry Hastings9cf065c2012-06-22 16:30:09 -07006982#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6983PyDoc_STRVAR(readlink__doc__,
6984"readlink(path, *, dir_fd=None) -> path\n\n\
6985Return a string representing the path to which the symbolic link points.\n\
6986\n\
6987If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6988 and path should be relative; path will then be relative to that directory.\n\
6989dir_fd may not be implemented on your platform.\n\
6990 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006991#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006992
Guido van Rossumb6775db1994-08-01 11:34:53 +00006993#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006994
Larry Hastings2f936352014-08-05 14:04:04 +10006995/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006996static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006997posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006998{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006999 path_t path;
7000 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007001 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007002 ssize_t length;
7003 PyObject *return_value = NULL;
7004 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007005
Larry Hastings9cf065c2012-06-22 16:30:09 -07007006 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007007 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007008 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7009 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007010 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007012
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007014#ifdef HAVE_READLINKAT
7015 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007016 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007017 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007018#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007019 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007020 Py_END_ALLOW_THREADS
7021
7022 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007023 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007024 goto exit;
7025 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007026 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007027
7028 if (PyUnicode_Check(path.object))
7029 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7030 else
7031 return_value = PyBytes_FromStringAndSize(buffer, length);
7032exit:
7033 path_cleanup(&path);
7034 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007035}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007036
Guido van Rossumb6775db1994-08-01 11:34:53 +00007037#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007038
Larry Hastings2f936352014-08-05 14:04:04 +10007039#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7040
7041static PyObject *
7042win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7043{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007044 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007045 DWORD n_bytes_returned;
7046 DWORD io_result;
7047 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007048 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007049 HANDLE reparse_point_handle;
7050
Martin Panter70214ad2016-08-04 02:38:59 +00007051 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7052 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007053 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007054
7055 static char *keywords[] = {"path", "dir_fd", NULL};
7056
7057 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7058 &po,
7059 dir_fd_unavailable, &dir_fd
7060 ))
7061 return NULL;
7062
7063 path = PyUnicode_AsUnicode(po);
7064 if (path == NULL)
7065 return NULL;
7066
7067 /* First get a handle to the reparse point */
7068 Py_BEGIN_ALLOW_THREADS
7069 reparse_point_handle = CreateFileW(
7070 path,
7071 0,
7072 0,
7073 0,
7074 OPEN_EXISTING,
7075 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7076 0);
7077 Py_END_ALLOW_THREADS
7078
7079 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7080 return win32_error_object("readlink", po);
7081
7082 Py_BEGIN_ALLOW_THREADS
7083 /* New call DeviceIoControl to read the reparse point */
7084 io_result = DeviceIoControl(
7085 reparse_point_handle,
7086 FSCTL_GET_REPARSE_POINT,
7087 0, 0, /* in buffer */
7088 target_buffer, sizeof(target_buffer),
7089 &n_bytes_returned,
7090 0 /* we're not using OVERLAPPED_IO */
7091 );
7092 CloseHandle(reparse_point_handle);
7093 Py_END_ALLOW_THREADS
7094
7095 if (io_result==0)
7096 return win32_error_object("readlink", po);
7097
7098 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7099 {
7100 PyErr_SetString(PyExc_ValueError,
7101 "not a symbolic link");
7102 return NULL;
7103 }
7104 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7105 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7106
7107 result = PyUnicode_FromWideChar(print_name,
7108 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7109 return result;
7110}
7111
7112#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7113
7114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007115
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007117
7118#if defined(MS_WINDOWS)
7119
7120/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007121static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007122
Larry Hastings9cf065c2012-06-22 16:30:09 -07007123static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007124check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125{
7126 HINSTANCE hKernel32;
7127 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007128 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129 return 1;
7130 hKernel32 = GetModuleHandleW(L"KERNEL32");
7131 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7132 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007133 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134}
7135
Victor Stinner31b3b922013-06-05 01:49:17 +02007136/* Remove the last portion of the path */
7137static void
7138_dirnameW(WCHAR *path)
7139{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007140 WCHAR *ptr;
7141
7142 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007143 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007144 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007145 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007146 }
7147 *ptr = 0;
7148}
7149
Victor Stinner31b3b922013-06-05 01:49:17 +02007150/* Is this path absolute? */
7151static int
7152_is_absW(const WCHAR *path)
7153{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007154 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7155
7156}
7157
Victor Stinner31b3b922013-06-05 01:49:17 +02007158/* join root and rest with a backslash */
7159static void
7160_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7161{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007162 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007163
Victor Stinner31b3b922013-06-05 01:49:17 +02007164 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007165 wcscpy(dest_path, rest);
7166 return;
7167 }
7168
7169 root_len = wcslen(root);
7170
7171 wcscpy(dest_path, root);
7172 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007173 dest_path[root_len] = L'\\';
7174 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007175 }
7176 wcscpy(dest_path+root_len, rest);
7177}
7178
Victor Stinner31b3b922013-06-05 01:49:17 +02007179/* Return True if the path at src relative to dest is a directory */
7180static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007181_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007182{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007183 WIN32_FILE_ATTRIBUTE_DATA src_info;
7184 WCHAR dest_parent[MAX_PATH];
7185 WCHAR src_resolved[MAX_PATH] = L"";
7186
7187 /* dest_parent = os.path.dirname(dest) */
7188 wcscpy(dest_parent, dest);
7189 _dirnameW(dest_parent);
7190 /* src_resolved = os.path.join(dest_parent, src) */
7191 _joinW(src_resolved, dest_parent, src);
7192 return (
7193 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7194 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7195 );
7196}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007198
Larry Hastings2f936352014-08-05 14:04:04 +10007199
7200/*[clinic input]
7201os.symlink
7202 src: path_t
7203 dst: path_t
7204 target_is_directory: bool = False
7205 *
7206 dir_fd: dir_fd(requires='symlinkat')=None
7207
7208# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7209
7210Create a symbolic link pointing to src named dst.
7211
7212target_is_directory is required on Windows if the target is to be
7213 interpreted as a directory. (On Windows, symlink requires
7214 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7215 target_is_directory is ignored on non-Windows platforms.
7216
7217If dir_fd is not None, it should be a file descriptor open to a directory,
7218 and path should be relative; path will then be relative to that directory.
7219dir_fd may not be implemented on your platform.
7220 If it is unavailable, using it will raise a NotImplementedError.
7221
7222[clinic start generated code]*/
7223
Larry Hastings2f936352014-08-05 14:04:04 +10007224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007225os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007226 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007227/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007228{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007229#ifdef MS_WINDOWS
7230 DWORD result;
7231#else
7232 int result;
7233#endif
7234
Larry Hastings9cf065c2012-06-22 16:30:09 -07007235#ifdef MS_WINDOWS
7236 if (!check_CreateSymbolicLink()) {
7237 PyErr_SetString(PyExc_NotImplementedError,
7238 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007239 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007240 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007241 if (!win32_can_symlink) {
7242 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
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#endif
7246
Larry Hastings2f936352014-08-05 14:04:04 +10007247 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007248 PyErr_SetString(PyExc_ValueError,
7249 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007250 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007251 }
7252
7253#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254
Larry Hastings9cf065c2012-06-22 16:30:09 -07007255 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007256 /* if src is a directory, ensure target_is_directory==1 */
7257 target_is_directory |= _check_dirW(src->wide, dst->wide);
7258 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7259 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007260 Py_END_ALLOW_THREADS
7261
Larry Hastings2f936352014-08-05 14:04:04 +10007262 if (!result)
7263 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007264
7265#else
7266
7267 Py_BEGIN_ALLOW_THREADS
7268#if HAVE_SYMLINKAT
7269 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007270 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007271 else
7272#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007273 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007274 Py_END_ALLOW_THREADS
7275
Larry Hastings2f936352014-08-05 14:04:04 +10007276 if (result)
7277 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007278#endif
7279
Larry Hastings2f936352014-08-05 14:04:04 +10007280 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007281}
7282#endif /* HAVE_SYMLINK */
7283
Larry Hastings9cf065c2012-06-22 16:30:09 -07007284
Brian Curtind40e6f72010-07-08 21:39:08 +00007285
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007286
Larry Hastings605a62d2012-06-24 04:33:36 -07007287static PyStructSequence_Field times_result_fields[] = {
7288 {"user", "user time"},
7289 {"system", "system time"},
7290 {"children_user", "user time of children"},
7291 {"children_system", "system time of children"},
7292 {"elapsed", "elapsed time since an arbitrary point in the past"},
7293 {NULL}
7294};
7295
7296PyDoc_STRVAR(times_result__doc__,
7297"times_result: Result from os.times().\n\n\
7298This object may be accessed either as a tuple of\n\
7299 (user, system, children_user, children_system, elapsed),\n\
7300or via the attributes user, system, children_user, children_system,\n\
7301and elapsed.\n\
7302\n\
7303See os.times for more information.");
7304
7305static PyStructSequence_Desc times_result_desc = {
7306 "times_result", /* name */
7307 times_result__doc__, /* doc */
7308 times_result_fields,
7309 5
7310};
7311
7312static PyTypeObject TimesResultType;
7313
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007314#ifdef MS_WINDOWS
7315#define HAVE_TIMES /* mandatory, for the method table */
7316#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007317
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007318#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007319
7320static PyObject *
7321build_times_result(double user, double system,
7322 double children_user, double children_system,
7323 double elapsed)
7324{
7325 PyObject *value = PyStructSequence_New(&TimesResultType);
7326 if (value == NULL)
7327 return NULL;
7328
7329#define SET(i, field) \
7330 { \
7331 PyObject *o = PyFloat_FromDouble(field); \
7332 if (!o) { \
7333 Py_DECREF(value); \
7334 return NULL; \
7335 } \
7336 PyStructSequence_SET_ITEM(value, i, o); \
7337 } \
7338
7339 SET(0, user);
7340 SET(1, system);
7341 SET(2, children_user);
7342 SET(3, children_system);
7343 SET(4, elapsed);
7344
7345#undef SET
7346
7347 return value;
7348}
7349
Larry Hastings605a62d2012-06-24 04:33:36 -07007350
Larry Hastings2f936352014-08-05 14:04:04 +10007351#ifndef MS_WINDOWS
7352#define NEED_TICKS_PER_SECOND
7353static long ticks_per_second = -1;
7354#endif /* MS_WINDOWS */
7355
7356/*[clinic input]
7357os.times
7358
7359Return a collection containing process timing information.
7360
7361The object returned behaves like a named tuple with these fields:
7362 (utime, stime, cutime, cstime, elapsed_time)
7363All fields are floating point numbers.
7364[clinic start generated code]*/
7365
Larry Hastings2f936352014-08-05 14:04:04 +10007366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007367os_times_impl(PyObject *module)
7368/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007369#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007370{
Victor Stinner8c62be82010-05-06 00:08:46 +00007371 FILETIME create, exit, kernel, user;
7372 HANDLE hProc;
7373 hProc = GetCurrentProcess();
7374 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7375 /* The fields of a FILETIME structure are the hi and lo part
7376 of a 64-bit value expressed in 100 nanosecond units.
7377 1e7 is one second in such units; 1e-7 the inverse.
7378 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7379 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007380 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 (double)(user.dwHighDateTime*429.4967296 +
7382 user.dwLowDateTime*1e-7),
7383 (double)(kernel.dwHighDateTime*429.4967296 +
7384 kernel.dwLowDateTime*1e-7),
7385 (double)0,
7386 (double)0,
7387 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007388}
Larry Hastings2f936352014-08-05 14:04:04 +10007389#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007390{
Larry Hastings2f936352014-08-05 14:04:04 +10007391
7392
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007393 struct tms t;
7394 clock_t c;
7395 errno = 0;
7396 c = times(&t);
7397 if (c == (clock_t) -1)
7398 return posix_error();
7399 return build_times_result(
7400 (double)t.tms_utime / ticks_per_second,
7401 (double)t.tms_stime / ticks_per_second,
7402 (double)t.tms_cutime / ticks_per_second,
7403 (double)t.tms_cstime / ticks_per_second,
7404 (double)c / ticks_per_second);
7405}
Larry Hastings2f936352014-08-05 14:04:04 +10007406#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007407#endif /* HAVE_TIMES */
7408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007409
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007410#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007411/*[clinic input]
7412os.getsid
7413
7414 pid: pid_t
7415 /
7416
7417Call the system call getsid(pid) and return the result.
7418[clinic start generated code]*/
7419
Larry Hastings2f936352014-08-05 14:04:04 +10007420static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007421os_getsid_impl(PyObject *module, pid_t pid)
7422/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007423{
Victor Stinner8c62be82010-05-06 00:08:46 +00007424 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007425 sid = getsid(pid);
7426 if (sid < 0)
7427 return posix_error();
7428 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007429}
7430#endif /* HAVE_GETSID */
7431
7432
Guido van Rossumb6775db1994-08-01 11:34:53 +00007433#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007434/*[clinic input]
7435os.setsid
7436
7437Call the system call setsid().
7438[clinic start generated code]*/
7439
Larry Hastings2f936352014-08-05 14:04:04 +10007440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007441os_setsid_impl(PyObject *module)
7442/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007443{
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 if (setsid() < 0)
7445 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007446 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007447}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007448#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007449
Larry Hastings2f936352014-08-05 14:04:04 +10007450
Guido van Rossumb6775db1994-08-01 11:34:53 +00007451#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007452/*[clinic input]
7453os.setpgid
7454
7455 pid: pid_t
7456 pgrp: pid_t
7457 /
7458
7459Call the system call setpgid(pid, pgrp).
7460[clinic start generated code]*/
7461
Larry Hastings2f936352014-08-05 14:04:04 +10007462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007463os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7464/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007465{
Victor Stinner8c62be82010-05-06 00:08:46 +00007466 if (setpgid(pid, pgrp) < 0)
7467 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007468 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007469}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007470#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007472
Guido van Rossumb6775db1994-08-01 11:34:53 +00007473#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007474/*[clinic input]
7475os.tcgetpgrp
7476
7477 fd: int
7478 /
7479
7480Return the process group associated with the terminal specified by fd.
7481[clinic start generated code]*/
7482
Larry Hastings2f936352014-08-05 14:04:04 +10007483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007484os_tcgetpgrp_impl(PyObject *module, int fd)
7485/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007486{
7487 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007488 if (pgid < 0)
7489 return posix_error();
7490 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007491}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007492#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007494
Guido van Rossumb6775db1994-08-01 11:34:53 +00007495#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007496/*[clinic input]
7497os.tcsetpgrp
7498
7499 fd: int
7500 pgid: pid_t
7501 /
7502
7503Set the process group associated with the terminal specified by fd.
7504[clinic start generated code]*/
7505
Larry Hastings2f936352014-08-05 14:04:04 +10007506static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007507os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7508/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007509{
Victor Stinner8c62be82010-05-06 00:08:46 +00007510 if (tcsetpgrp(fd, pgid) < 0)
7511 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007512 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007513}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007514#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007515
Guido van Rossum687dd131993-05-17 08:34:16 +00007516/* Functions acting on file descriptors */
7517
Victor Stinnerdaf45552013-08-28 00:53:59 +02007518#ifdef O_CLOEXEC
7519extern int _Py_open_cloexec_works;
7520#endif
7521
Larry Hastings2f936352014-08-05 14:04:04 +10007522
7523/*[clinic input]
7524os.open -> int
7525 path: path_t
7526 flags: int
7527 mode: int = 0o777
7528 *
7529 dir_fd: dir_fd(requires='openat') = None
7530
7531# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7532
7533Open a file for low level IO. Returns a file descriptor (integer).
7534
7535If dir_fd is not None, it should be a file descriptor open to a directory,
7536 and path should be relative; path will then be relative to that directory.
7537dir_fd may not be implemented on your platform.
7538 If it is unavailable, using it will raise a NotImplementedError.
7539[clinic start generated code]*/
7540
Larry Hastings2f936352014-08-05 14:04:04 +10007541static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007542os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7543/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007544{
7545 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007546 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007547
Victor Stinnerdaf45552013-08-28 00:53:59 +02007548#ifdef O_CLOEXEC
7549 int *atomic_flag_works = &_Py_open_cloexec_works;
7550#elif !defined(MS_WINDOWS)
7551 int *atomic_flag_works = NULL;
7552#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007553
Victor Stinnerdaf45552013-08-28 00:53:59 +02007554#ifdef MS_WINDOWS
7555 flags |= O_NOINHERIT;
7556#elif defined(O_CLOEXEC)
7557 flags |= O_CLOEXEC;
7558#endif
7559
Steve Dower8fc89802015-04-12 00:26:27 -04007560 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007561 do {
7562 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007563#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007564 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007565#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007566#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007567 if (dir_fd != DEFAULT_DIR_FD)
7568 fd = openat(dir_fd, path->narrow, flags, mode);
7569 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007570#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007571 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007572#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007573 Py_END_ALLOW_THREADS
7574 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007575 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007576
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007577 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007578 if (!async_err)
7579 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007580 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007581 }
7582
Victor Stinnerdaf45552013-08-28 00:53:59 +02007583#ifndef MS_WINDOWS
7584 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7585 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007586 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007587 }
7588#endif
7589
Larry Hastings2f936352014-08-05 14:04:04 +10007590 return fd;
7591}
7592
7593
7594/*[clinic input]
7595os.close
7596
7597 fd: int
7598
7599Close a file descriptor.
7600[clinic start generated code]*/
7601
Barry Warsaw53699e91996-12-10 23:23:01 +00007602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007603os_close_impl(PyObject *module, int fd)
7604/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007605{
Larry Hastings2f936352014-08-05 14:04:04 +10007606 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007607 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7608 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7609 * for more details.
7610 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007612 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007614 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 Py_END_ALLOW_THREADS
7616 if (res < 0)
7617 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007618 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007619}
7620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007621
Larry Hastings2f936352014-08-05 14:04:04 +10007622/*[clinic input]
7623os.closerange
7624
7625 fd_low: int
7626 fd_high: int
7627 /
7628
7629Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7630[clinic start generated code]*/
7631
Larry Hastings2f936352014-08-05 14:04:04 +10007632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007633os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7634/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007635{
7636 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007638 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007639 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007640 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007641 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 Py_END_ALLOW_THREADS
7643 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007644}
7645
7646
Larry Hastings2f936352014-08-05 14:04:04 +10007647/*[clinic input]
7648os.dup -> int
7649
7650 fd: int
7651 /
7652
7653Return a duplicate of a file descriptor.
7654[clinic start generated code]*/
7655
Larry Hastings2f936352014-08-05 14:04:04 +10007656static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007657os_dup_impl(PyObject *module, int fd)
7658/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007659{
7660 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007661}
7662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007663
Larry Hastings2f936352014-08-05 14:04:04 +10007664/*[clinic input]
7665os.dup2
7666 fd: int
7667 fd2: int
7668 inheritable: bool=True
7669
7670Duplicate file descriptor.
7671[clinic start generated code]*/
7672
Larry Hastings2f936352014-08-05 14:04:04 +10007673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007674os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7675/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007676{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007677 int res;
7678#if defined(HAVE_DUP3) && \
7679 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7680 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7681 int dup3_works = -1;
7682#endif
7683
Steve Dower940f33a2016-09-08 11:21:54 -07007684 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007685 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007686
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007687 /* dup2() can fail with EINTR if the target FD is already open, because it
7688 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7689 * upon close(), and therefore below.
7690 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007691#ifdef MS_WINDOWS
7692 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007693 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007694 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007695 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007696 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007697 if (res < 0)
7698 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007699
7700 /* Character files like console cannot be make non-inheritable */
7701 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7702 close(fd2);
7703 return NULL;
7704 }
7705
7706#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7707 Py_BEGIN_ALLOW_THREADS
7708 if (!inheritable)
7709 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7710 else
7711 res = dup2(fd, fd2);
7712 Py_END_ALLOW_THREADS
7713 if (res < 0)
7714 return posix_error();
7715
7716#else
7717
7718#ifdef HAVE_DUP3
7719 if (!inheritable && dup3_works != 0) {
7720 Py_BEGIN_ALLOW_THREADS
7721 res = dup3(fd, fd2, O_CLOEXEC);
7722 Py_END_ALLOW_THREADS
7723 if (res < 0) {
7724 if (dup3_works == -1)
7725 dup3_works = (errno != ENOSYS);
7726 if (dup3_works)
7727 return posix_error();
7728 }
7729 }
7730
7731 if (inheritable || dup3_works == 0)
7732 {
7733#endif
7734 Py_BEGIN_ALLOW_THREADS
7735 res = dup2(fd, fd2);
7736 Py_END_ALLOW_THREADS
7737 if (res < 0)
7738 return posix_error();
7739
7740 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7741 close(fd2);
7742 return NULL;
7743 }
7744#ifdef HAVE_DUP3
7745 }
7746#endif
7747
7748#endif
7749
Larry Hastings2f936352014-08-05 14:04:04 +10007750 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007751}
7752
Larry Hastings2f936352014-08-05 14:04:04 +10007753
Ross Lagerwall7807c352011-03-17 20:20:30 +02007754#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007755/*[clinic input]
7756os.lockf
7757
7758 fd: int
7759 An open file descriptor.
7760 command: int
7761 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7762 length: Py_off_t
7763 The number of bytes to lock, starting at the current position.
7764 /
7765
7766Apply, test or remove a POSIX lock on an open file descriptor.
7767
7768[clinic start generated code]*/
7769
Larry Hastings2f936352014-08-05 14:04:04 +10007770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007771os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7772/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007773{
7774 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007775
7776 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007777 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007778 Py_END_ALLOW_THREADS
7779
7780 if (res < 0)
7781 return posix_error();
7782
7783 Py_RETURN_NONE;
7784}
Larry Hastings2f936352014-08-05 14:04:04 +10007785#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007787
Larry Hastings2f936352014-08-05 14:04:04 +10007788/*[clinic input]
7789os.lseek -> Py_off_t
7790
7791 fd: int
7792 position: Py_off_t
7793 how: int
7794 /
7795
7796Set the position of a file descriptor. Return the new position.
7797
7798Return the new cursor position in number of bytes
7799relative to the beginning of the file.
7800[clinic start generated code]*/
7801
Larry Hastings2f936352014-08-05 14:04:04 +10007802static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007803os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7804/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007805{
7806 Py_off_t result;
7807
Guido van Rossum687dd131993-05-17 08:34:16 +00007808#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7810 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007811 case 0: how = SEEK_SET; break;
7812 case 1: how = SEEK_CUR; break;
7813 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007815#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007816
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007818 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007819
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007821 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007822#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007823 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007824#else
Larry Hastings2f936352014-08-05 14:04:04 +10007825 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007826#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007827 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007829 if (result < 0)
7830 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007831
Larry Hastings2f936352014-08-05 14:04:04 +10007832 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007833}
7834
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007835
Larry Hastings2f936352014-08-05 14:04:04 +10007836/*[clinic input]
7837os.read
7838 fd: int
7839 length: Py_ssize_t
7840 /
7841
7842Read from a file descriptor. Returns a bytes object.
7843[clinic start generated code]*/
7844
Larry Hastings2f936352014-08-05 14:04:04 +10007845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007846os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7847/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007848{
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 Py_ssize_t n;
7850 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007851
7852 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 errno = EINVAL;
7854 return posix_error();
7855 }
Larry Hastings2f936352014-08-05 14:04:04 +10007856
7857#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007858 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007859 if (length > INT_MAX)
7860 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007861#endif
7862
7863 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 if (buffer == NULL)
7865 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007866
Victor Stinner66aab0c2015-03-19 22:53:20 +01007867 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7868 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007870 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007871 }
Larry Hastings2f936352014-08-05 14:04:04 +10007872
7873 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007875
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007877}
7878
Ross Lagerwall7807c352011-03-17 20:20:30 +02007879#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7880 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007881static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007882iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7883{
7884 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007885 Py_ssize_t blen, total = 0;
7886
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007887 *iov = PyMem_New(struct iovec, cnt);
7888 if (*iov == NULL) {
7889 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007890 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007891 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007892
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007893 *buf = PyMem_New(Py_buffer, cnt);
7894 if (*buf == NULL) {
7895 PyMem_Del(*iov);
7896 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007897 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007898 }
7899
7900 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007901 PyObject *item = PySequence_GetItem(seq, i);
7902 if (item == NULL)
7903 goto fail;
7904 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7905 Py_DECREF(item);
7906 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007907 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007908 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007909 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007910 blen = (*buf)[i].len;
7911 (*iov)[i].iov_len = blen;
7912 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007913 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007914 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007915
7916fail:
7917 PyMem_Del(*iov);
7918 for (j = 0; j < i; j++) {
7919 PyBuffer_Release(&(*buf)[j]);
7920 }
7921 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007922 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007923}
7924
7925static void
7926iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7927{
7928 int i;
7929 PyMem_Del(iov);
7930 for (i = 0; i < cnt; i++) {
7931 PyBuffer_Release(&buf[i]);
7932 }
7933 PyMem_Del(buf);
7934}
7935#endif
7936
Larry Hastings2f936352014-08-05 14:04:04 +10007937
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007939/*[clinic input]
7940os.readv -> Py_ssize_t
7941
7942 fd: int
7943 buffers: object
7944 /
7945
7946Read from a file descriptor fd into an iterable of buffers.
7947
7948The buffers should be mutable buffers accepting bytes.
7949readv will transfer data into each buffer until it is full
7950and then move on to the next buffer in the sequence to hold
7951the rest of the data.
7952
7953readv returns the total number of bytes read,
7954which may be less than the total capacity of all the buffers.
7955[clinic start generated code]*/
7956
Larry Hastings2f936352014-08-05 14:04:04 +10007957static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007958os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7959/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007960{
7961 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007962 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007963 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007964 struct iovec *iov;
7965 Py_buffer *buf;
7966
Larry Hastings2f936352014-08-05 14:04:04 +10007967 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007968 PyErr_SetString(PyExc_TypeError,
7969 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007970 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007971 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972
Larry Hastings2f936352014-08-05 14:04:04 +10007973 cnt = PySequence_Size(buffers);
7974
7975 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7976 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007977
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007978 do {
7979 Py_BEGIN_ALLOW_THREADS
7980 n = readv(fd, iov, cnt);
7981 Py_END_ALLOW_THREADS
7982 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007983
7984 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007985 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007986 if (!async_err)
7987 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007988 return -1;
7989 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007990
Larry Hastings2f936352014-08-05 14:04:04 +10007991 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007992}
Larry Hastings2f936352014-08-05 14:04:04 +10007993#endif /* HAVE_READV */
7994
Ross Lagerwall7807c352011-03-17 20:20:30 +02007995
7996#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007997/*[clinic input]
7998# TODO length should be size_t! but Python doesn't support parsing size_t yet.
7999os.pread
8000
8001 fd: int
8002 length: int
8003 offset: Py_off_t
8004 /
8005
8006Read a number of bytes from a file descriptor starting at a particular offset.
8007
8008Read length bytes from file descriptor fd, starting at offset bytes from
8009the beginning of the file. The file offset remains unchanged.
8010[clinic start generated code]*/
8011
Larry Hastings2f936352014-08-05 14:04:04 +10008012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008013os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8014/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008015{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008016 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008017 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008018 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008019
Larry Hastings2f936352014-08-05 14:04:04 +10008020 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008021 errno = EINVAL;
8022 return posix_error();
8023 }
Larry Hastings2f936352014-08-05 14:04:04 +10008024 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008025 if (buffer == NULL)
8026 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008027
8028 do {
8029 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008030 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008031 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008032 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008033 Py_END_ALLOW_THREADS
8034 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8035
Ross Lagerwall7807c352011-03-17 20:20:30 +02008036 if (n < 0) {
8037 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008038 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008039 }
Larry Hastings2f936352014-08-05 14:04:04 +10008040 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008041 _PyBytes_Resize(&buffer, n);
8042 return buffer;
8043}
Larry Hastings2f936352014-08-05 14:04:04 +10008044#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008045
Larry Hastings2f936352014-08-05 14:04:04 +10008046
8047/*[clinic input]
8048os.write -> Py_ssize_t
8049
8050 fd: int
8051 data: Py_buffer
8052 /
8053
8054Write a bytes object to a file descriptor.
8055[clinic start generated code]*/
8056
Larry Hastings2f936352014-08-05 14:04:04 +10008057static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008058os_write_impl(PyObject *module, int fd, Py_buffer *data)
8059/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008060{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008061 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008062}
8063
8064#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008066"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008067sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008069Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070
Larry Hastings2f936352014-08-05 14:04:04 +10008071/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072static PyObject *
8073posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8074{
8075 int in, out;
8076 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008077 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008078 off_t offset;
8079
8080#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8081#ifndef __APPLE__
8082 Py_ssize_t len;
8083#endif
8084 PyObject *headers = NULL, *trailers = NULL;
8085 Py_buffer *hbuf, *tbuf;
8086 off_t sbytes;
8087 struct sf_hdtr sf;
8088 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008089 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008090 static char *keywords[] = {"out", "in",
8091 "offset", "count",
8092 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008093
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008094 sf.headers = NULL;
8095 sf.trailers = NULL;
8096
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008097#ifdef __APPLE__
8098 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008099 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008100#else
8101 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008102 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008103#endif
8104 &headers, &trailers, &flags))
8105 return NULL;
8106 if (headers != NULL) {
8107 if (!PySequence_Check(headers)) {
8108 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008109 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008110 return NULL;
8111 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008112 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008113 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008114 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008115 (i = iov_setup(&(sf.headers), &hbuf,
8116 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008117 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008118#ifdef __APPLE__
8119 sbytes += i;
8120#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008121 }
8122 }
8123 if (trailers != NULL) {
8124 if (!PySequence_Check(trailers)) {
8125 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008126 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008127 return NULL;
8128 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008129 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008130 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008131 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008132 (i = iov_setup(&(sf.trailers), &tbuf,
8133 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008134 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008135#ifdef __APPLE__
8136 sbytes += i;
8137#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008138 }
8139 }
8140
Steve Dower8fc89802015-04-12 00:26:27 -04008141 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008142 do {
8143 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008144#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008145 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008146#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008147 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008148#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 Py_END_ALLOW_THREADS
8150 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008151 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008152
8153 if (sf.headers != NULL)
8154 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8155 if (sf.trailers != NULL)
8156 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8157
8158 if (ret < 0) {
8159 if ((errno == EAGAIN) || (errno == EBUSY)) {
8160 if (sbytes != 0) {
8161 // some data has been sent
8162 goto done;
8163 }
8164 else {
8165 // no data has been sent; upper application is supposed
8166 // to retry on EAGAIN or EBUSY
8167 return posix_error();
8168 }
8169 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008170 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008171 }
8172 goto done;
8173
8174done:
8175 #if !defined(HAVE_LARGEFILE_SUPPORT)
8176 return Py_BuildValue("l", sbytes);
8177 #else
8178 return Py_BuildValue("L", sbytes);
8179 #endif
8180
8181#else
8182 Py_ssize_t count;
8183 PyObject *offobj;
8184 static char *keywords[] = {"out", "in",
8185 "offset", "count", NULL};
8186 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8187 keywords, &out, &in, &offobj, &count))
8188 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008189#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008190 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008191 do {
8192 Py_BEGIN_ALLOW_THREADS
8193 ret = sendfile(out, in, NULL, count);
8194 Py_END_ALLOW_THREADS
8195 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008196 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008197 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008198 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008199 }
8200#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008201 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008202 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008203
8204 do {
8205 Py_BEGIN_ALLOW_THREADS
8206 ret = sendfile(out, in, &offset, count);
8207 Py_END_ALLOW_THREADS
8208 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008209 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008210 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008211 return Py_BuildValue("n", ret);
8212#endif
8213}
Larry Hastings2f936352014-08-05 14:04:04 +10008214#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008215
Larry Hastings2f936352014-08-05 14:04:04 +10008216
8217/*[clinic input]
8218os.fstat
8219
8220 fd : int
8221
8222Perform a stat system call on the given file descriptor.
8223
8224Like stat(), but for an open file descriptor.
8225Equivalent to os.stat(fd).
8226[clinic start generated code]*/
8227
Larry Hastings2f936352014-08-05 14:04:04 +10008228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008229os_fstat_impl(PyObject *module, int fd)
8230/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008231{
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 STRUCT_STAT st;
8233 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008234 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008235
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008236 do {
8237 Py_BEGIN_ALLOW_THREADS
8238 res = FSTAT(fd, &st);
8239 Py_END_ALLOW_THREADS
8240 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008242#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008243 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008244#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008245 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008246#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 }
Tim Peters5aa91602002-01-30 05:46:57 +00008248
Victor Stinner4195b5c2012-02-08 23:03:19 +01008249 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008250}
8251
Larry Hastings2f936352014-08-05 14:04:04 +10008252
8253/*[clinic input]
8254os.isatty -> bool
8255 fd: int
8256 /
8257
8258Return True if the fd is connected to a terminal.
8259
8260Return True if the file descriptor is an open file descriptor
8261connected to the slave end of a terminal.
8262[clinic start generated code]*/
8263
Larry Hastings2f936352014-08-05 14:04:04 +10008264static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008265os_isatty_impl(PyObject *module, int fd)
8266/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008267{
Steve Dower8fc89802015-04-12 00:26:27 -04008268 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008269 _Py_BEGIN_SUPPRESS_IPH
8270 return_value = isatty(fd);
8271 _Py_END_SUPPRESS_IPH
8272 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008273}
8274
8275
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008276#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008277/*[clinic input]
8278os.pipe
8279
8280Create a pipe.
8281
8282Returns a tuple of two file descriptors:
8283 (read_fd, write_fd)
8284[clinic start generated code]*/
8285
Larry Hastings2f936352014-08-05 14:04:04 +10008286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008287os_pipe_impl(PyObject *module)
8288/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008289{
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008291#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008293 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008294 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008295#else
8296 int res;
8297#endif
8298
8299#ifdef MS_WINDOWS
8300 attr.nLength = sizeof(attr);
8301 attr.lpSecurityDescriptor = NULL;
8302 attr.bInheritHandle = FALSE;
8303
8304 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008305 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008306 ok = CreatePipe(&read, &write, &attr, 0);
8307 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008308 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8309 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008310 if (fds[0] == -1 || fds[1] == -1) {
8311 CloseHandle(read);
8312 CloseHandle(write);
8313 ok = 0;
8314 }
8315 }
Steve Dowerc3630612016-11-19 18:41:16 -08008316 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008317 Py_END_ALLOW_THREADS
8318
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008320 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008321#else
8322
8323#ifdef HAVE_PIPE2
8324 Py_BEGIN_ALLOW_THREADS
8325 res = pipe2(fds, O_CLOEXEC);
8326 Py_END_ALLOW_THREADS
8327
8328 if (res != 0 && errno == ENOSYS)
8329 {
8330#endif
8331 Py_BEGIN_ALLOW_THREADS
8332 res = pipe(fds);
8333 Py_END_ALLOW_THREADS
8334
8335 if (res == 0) {
8336 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8337 close(fds[0]);
8338 close(fds[1]);
8339 return NULL;
8340 }
8341 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8342 close(fds[0]);
8343 close(fds[1]);
8344 return NULL;
8345 }
8346 }
8347#ifdef HAVE_PIPE2
8348 }
8349#endif
8350
8351 if (res != 0)
8352 return PyErr_SetFromErrno(PyExc_OSError);
8353#endif /* !MS_WINDOWS */
8354 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008355}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008356#endif /* HAVE_PIPE */
8357
Larry Hastings2f936352014-08-05 14:04:04 +10008358
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008359#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008360/*[clinic input]
8361os.pipe2
8362
8363 flags: int
8364 /
8365
8366Create a pipe with flags set atomically.
8367
8368Returns a tuple of two file descriptors:
8369 (read_fd, write_fd)
8370
8371flags can be constructed by ORing together one or more of these values:
8372O_NONBLOCK, O_CLOEXEC.
8373[clinic start generated code]*/
8374
Larry Hastings2f936352014-08-05 14:04:04 +10008375static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008376os_pipe2_impl(PyObject *module, int flags)
8377/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008378{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008379 int fds[2];
8380 int res;
8381
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008382 res = pipe2(fds, flags);
8383 if (res != 0)
8384 return posix_error();
8385 return Py_BuildValue("(ii)", fds[0], fds[1]);
8386}
8387#endif /* HAVE_PIPE2 */
8388
Larry Hastings2f936352014-08-05 14:04:04 +10008389
Ross Lagerwall7807c352011-03-17 20:20:30 +02008390#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008391/*[clinic input]
8392os.writev -> Py_ssize_t
8393 fd: int
8394 buffers: object
8395 /
8396
8397Iterate over buffers, and write the contents of each to a file descriptor.
8398
8399Returns the total number of bytes written.
8400buffers must be a sequence of bytes-like objects.
8401[clinic start generated code]*/
8402
Larry Hastings2f936352014-08-05 14:04:04 +10008403static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008404os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8405/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008406{
8407 int cnt;
8408 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008409 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008410 struct iovec *iov;
8411 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008412
8413 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008414 PyErr_SetString(PyExc_TypeError,
8415 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008416 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008417 }
Larry Hastings2f936352014-08-05 14:04:04 +10008418 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008419
Larry Hastings2f936352014-08-05 14:04:04 +10008420 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8421 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008422 }
8423
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008424 do {
8425 Py_BEGIN_ALLOW_THREADS
8426 result = writev(fd, iov, cnt);
8427 Py_END_ALLOW_THREADS
8428 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008429
8430 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008431 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008432 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008433
Georg Brandl306336b2012-06-24 12:55:33 +02008434 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008435}
Larry Hastings2f936352014-08-05 14:04:04 +10008436#endif /* HAVE_WRITEV */
8437
8438
8439#ifdef HAVE_PWRITE
8440/*[clinic input]
8441os.pwrite -> Py_ssize_t
8442
8443 fd: int
8444 buffer: Py_buffer
8445 offset: Py_off_t
8446 /
8447
8448Write bytes to a file descriptor starting at a particular offset.
8449
8450Write buffer to fd, starting at offset bytes from the beginning of
8451the file. Returns the number of bytes writte. Does not change the
8452current file offset.
8453[clinic start generated code]*/
8454
Larry Hastings2f936352014-08-05 14:04:04 +10008455static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008456os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8457/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008458{
8459 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008460 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008461
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008462 do {
8463 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008464 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008465 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008466 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008467 Py_END_ALLOW_THREADS
8468 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008469
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008470 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008471 posix_error();
8472 return size;
8473}
8474#endif /* HAVE_PWRITE */
8475
8476
8477#ifdef HAVE_MKFIFO
8478/*[clinic input]
8479os.mkfifo
8480
8481 path: path_t
8482 mode: int=0o666
8483 *
8484 dir_fd: dir_fd(requires='mkfifoat')=None
8485
8486Create a "fifo" (a POSIX named pipe).
8487
8488If dir_fd is not None, it should be a file descriptor open to a directory,
8489 and path should be relative; path will then be relative to that directory.
8490dir_fd may not be implemented on your platform.
8491 If it is unavailable, using it will raise a NotImplementedError.
8492[clinic start generated code]*/
8493
Larry Hastings2f936352014-08-05 14:04:04 +10008494static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008495os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8496/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008497{
8498 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008499 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008500
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008501 do {
8502 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008503#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008504 if (dir_fd != DEFAULT_DIR_FD)
8505 result = mkfifoat(dir_fd, path->narrow, mode);
8506 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008507#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008508 result = mkfifo(path->narrow, mode);
8509 Py_END_ALLOW_THREADS
8510 } while (result != 0 && errno == EINTR &&
8511 !(async_err = PyErr_CheckSignals()));
8512 if (result != 0)
8513 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008514
8515 Py_RETURN_NONE;
8516}
8517#endif /* HAVE_MKFIFO */
8518
8519
8520#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8521/*[clinic input]
8522os.mknod
8523
8524 path: path_t
8525 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008526 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008527 *
8528 dir_fd: dir_fd(requires='mknodat')=None
8529
8530Create a node in the file system.
8531
8532Create a node in the file system (file, device special file or named pipe)
8533at path. mode specifies both the permissions to use and the
8534type of node to be created, being combined (bitwise OR) with one of
8535S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8536device defines the newly created device special file (probably using
8537os.makedev()). Otherwise device is ignored.
8538
8539If dir_fd is not None, it should be a file descriptor open to a directory,
8540 and path should be relative; path will then be relative to that directory.
8541dir_fd may not be implemented on your platform.
8542 If it is unavailable, using it will raise a NotImplementedError.
8543[clinic start generated code]*/
8544
Larry Hastings2f936352014-08-05 14:04:04 +10008545static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008546os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008547 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008548/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008549{
8550 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008551 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008552
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008553 do {
8554 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008555#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008556 if (dir_fd != DEFAULT_DIR_FD)
8557 result = mknodat(dir_fd, path->narrow, mode, device);
8558 else
Larry Hastings2f936352014-08-05 14:04:04 +10008559#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008560 result = mknod(path->narrow, mode, device);
8561 Py_END_ALLOW_THREADS
8562 } while (result != 0 && errno == EINTR &&
8563 !(async_err = PyErr_CheckSignals()));
8564 if (result != 0)
8565 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008566
8567 Py_RETURN_NONE;
8568}
8569#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8570
8571
8572#ifdef HAVE_DEVICE_MACROS
8573/*[clinic input]
8574os.major -> unsigned_int
8575
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008576 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008577 /
8578
8579Extracts a device major number from a raw device number.
8580[clinic start generated code]*/
8581
Larry Hastings2f936352014-08-05 14:04:04 +10008582static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008583os_major_impl(PyObject *module, dev_t device)
8584/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008585{
8586 return major(device);
8587}
8588
8589
8590/*[clinic input]
8591os.minor -> unsigned_int
8592
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008593 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008594 /
8595
8596Extracts a device minor number from a raw device number.
8597[clinic start generated code]*/
8598
Larry Hastings2f936352014-08-05 14:04:04 +10008599static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008600os_minor_impl(PyObject *module, dev_t device)
8601/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008602{
8603 return minor(device);
8604}
8605
8606
8607/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008608os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008609
8610 major: int
8611 minor: int
8612 /
8613
8614Composes a raw device number from the major and minor device numbers.
8615[clinic start generated code]*/
8616
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008617static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008618os_makedev_impl(PyObject *module, int major, int minor)
8619/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008620{
8621 return makedev(major, minor);
8622}
8623#endif /* HAVE_DEVICE_MACROS */
8624
8625
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008626#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008627/*[clinic input]
8628os.ftruncate
8629
8630 fd: int
8631 length: Py_off_t
8632 /
8633
8634Truncate a file, specified by file descriptor, to a specific length.
8635[clinic start generated code]*/
8636
Larry Hastings2f936352014-08-05 14:04:04 +10008637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008638os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8639/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008640{
8641 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008642 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008643
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008644 do {
8645 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008646 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008647#ifdef MS_WINDOWS
8648 result = _chsize_s(fd, length);
8649#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008650 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008651#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008652 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008653 Py_END_ALLOW_THREADS
8654 } while (result != 0 && errno == EINTR &&
8655 !(async_err = PyErr_CheckSignals()));
8656 if (result != 0)
8657 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008658 Py_RETURN_NONE;
8659}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008660#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008661
8662
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008663#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008664/*[clinic input]
8665os.truncate
8666 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8667 length: Py_off_t
8668
8669Truncate a file, specified by path, to a specific length.
8670
8671On some platforms, path may also be specified as an open file descriptor.
8672 If this functionality is unavailable, using it raises an exception.
8673[clinic start generated code]*/
8674
Larry Hastings2f936352014-08-05 14:04:04 +10008675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008676os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8677/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008678{
8679 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008680#ifdef MS_WINDOWS
8681 int fd;
8682#endif
8683
8684 if (path->fd != -1)
8685 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008686
8687 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008688 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008689#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008690 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008691 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008692 result = -1;
8693 else {
8694 result = _chsize_s(fd, length);
8695 close(fd);
8696 if (result < 0)
8697 errno = result;
8698 }
8699#else
8700 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008701#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008702 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008703 Py_END_ALLOW_THREADS
8704 if (result < 0)
8705 return path_error(path);
8706
8707 Py_RETURN_NONE;
8708}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008709#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008710
Ross Lagerwall7807c352011-03-17 20:20:30 +02008711
Victor Stinnerd6b17692014-09-30 12:20:05 +02008712/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8713 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8714 defined, which is the case in Python on AIX. AIX bug report:
8715 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8716#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8717# define POSIX_FADVISE_AIX_BUG
8718#endif
8719
Victor Stinnerec39e262014-09-30 12:35:58 +02008720
Victor Stinnerd6b17692014-09-30 12:20:05 +02008721#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008722/*[clinic input]
8723os.posix_fallocate
8724
8725 fd: int
8726 offset: Py_off_t
8727 length: Py_off_t
8728 /
8729
8730Ensure a file has allocated at least a particular number of bytes on disk.
8731
8732Ensure that the file specified by fd encompasses a range of bytes
8733starting at offset bytes from the beginning and continuing for length bytes.
8734[clinic start generated code]*/
8735
Larry Hastings2f936352014-08-05 14:04:04 +10008736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008737os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008738 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008739/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008740{
8741 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008742 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008743
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008744 do {
8745 Py_BEGIN_ALLOW_THREADS
8746 result = posix_fallocate(fd, offset, length);
8747 Py_END_ALLOW_THREADS
8748 } while (result != 0 && errno == EINTR &&
8749 !(async_err = PyErr_CheckSignals()));
8750 if (result != 0)
8751 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008752 Py_RETURN_NONE;
8753}
Victor Stinnerec39e262014-09-30 12:35:58 +02008754#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008755
Ross Lagerwall7807c352011-03-17 20:20:30 +02008756
Victor Stinnerd6b17692014-09-30 12:20:05 +02008757#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008758/*[clinic input]
8759os.posix_fadvise
8760
8761 fd: int
8762 offset: Py_off_t
8763 length: Py_off_t
8764 advice: int
8765 /
8766
8767Announce an intention to access data in a specific pattern.
8768
8769Announce an intention to access data in a specific pattern, thus allowing
8770the kernel to make optimizations.
8771The advice applies to the region of the file specified by fd starting at
8772offset and continuing for length bytes.
8773advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8774POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8775POSIX_FADV_DONTNEED.
8776[clinic start generated code]*/
8777
Larry Hastings2f936352014-08-05 14:04:04 +10008778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008779os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008780 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008781/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008782{
8783 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008784 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008785
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008786 do {
8787 Py_BEGIN_ALLOW_THREADS
8788 result = posix_fadvise(fd, offset, length, advice);
8789 Py_END_ALLOW_THREADS
8790 } while (result != 0 && errno == EINTR &&
8791 !(async_err = PyErr_CheckSignals()));
8792 if (result != 0)
8793 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008794 Py_RETURN_NONE;
8795}
Victor Stinnerec39e262014-09-30 12:35:58 +02008796#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008797
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008798#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008799
Fred Drake762e2061999-08-26 17:23:54 +00008800/* Save putenv() parameters as values here, so we can collect them when they
8801 * get re-set with another call for the same key. */
8802static PyObject *posix_putenv_garbage;
8803
Larry Hastings2f936352014-08-05 14:04:04 +10008804static void
8805posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008806{
Larry Hastings2f936352014-08-05 14:04:04 +10008807 /* Install the first arg and newstr in posix_putenv_garbage;
8808 * this will cause previous value to be collected. This has to
8809 * happen after the real putenv() call because the old value
8810 * was still accessible until then. */
8811 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8812 /* really not much we can do; just leak */
8813 PyErr_Clear();
8814 else
8815 Py_DECREF(value);
8816}
8817
8818
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008819#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008820/*[clinic input]
8821os.putenv
8822
8823 name: unicode
8824 value: unicode
8825 /
8826
8827Change or add an environment variable.
8828[clinic start generated code]*/
8829
Larry Hastings2f936352014-08-05 14:04:04 +10008830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008831os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8832/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008833{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008834 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008835
8836 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8837 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008838 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008839 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008840 }
Larry Hastings2f936352014-08-05 14:04:04 +10008841 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008842 PyErr_Format(PyExc_ValueError,
8843 "the environment variable is longer than %u characters",
8844 _MAX_ENV);
8845 goto error;
8846 }
8847
Larry Hastings2f936352014-08-05 14:04:04 +10008848 env = PyUnicode_AsUnicode(unicode);
8849 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008850 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008851 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008853 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008854 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008855
Larry Hastings2f936352014-08-05 14:04:04 +10008856 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008857 Py_RETURN_NONE;
8858
8859error:
Larry Hastings2f936352014-08-05 14:04:04 +10008860 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008861 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008862}
Larry Hastings2f936352014-08-05 14:04:04 +10008863#else /* MS_WINDOWS */
8864/*[clinic input]
8865os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008866
Larry Hastings2f936352014-08-05 14:04:04 +10008867 name: FSConverter
8868 value: FSConverter
8869 /
8870
8871Change or add an environment variable.
8872[clinic start generated code]*/
8873
Larry Hastings2f936352014-08-05 14:04:04 +10008874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008875os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8876/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008877{
8878 PyObject *bytes = NULL;
8879 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008880 const char *name_string = PyBytes_AsString(name);
8881 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008882
8883 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8884 if (bytes == NULL) {
8885 PyErr_NoMemory();
8886 return NULL;
8887 }
8888
8889 env = PyBytes_AS_STRING(bytes);
8890 if (putenv(env)) {
8891 Py_DECREF(bytes);
8892 return posix_error();
8893 }
8894
8895 posix_putenv_garbage_setitem(name, bytes);
8896 Py_RETURN_NONE;
8897}
8898#endif /* MS_WINDOWS */
8899#endif /* HAVE_PUTENV */
8900
8901
8902#ifdef HAVE_UNSETENV
8903/*[clinic input]
8904os.unsetenv
8905 name: FSConverter
8906 /
8907
8908Delete an environment variable.
8909[clinic start generated code]*/
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008912os_unsetenv_impl(PyObject *module, PyObject *name)
8913/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008914{
Victor Stinner984890f2011-11-24 13:53:38 +01008915#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008916 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008917#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008918
Victor Stinner984890f2011-11-24 13:53:38 +01008919#ifdef HAVE_BROKEN_UNSETENV
8920 unsetenv(PyBytes_AS_STRING(name));
8921#else
Victor Stinner65170952011-11-22 22:16:17 +01008922 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008923 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008924 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008925#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008926
Victor Stinner8c62be82010-05-06 00:08:46 +00008927 /* Remove the key from posix_putenv_garbage;
8928 * this will cause it to be collected. This has to
8929 * happen after the real unsetenv() call because the
8930 * old value was still accessible until then.
8931 */
Victor Stinner65170952011-11-22 22:16:17 +01008932 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 /* really not much we can do; just leak */
8934 PyErr_Clear();
8935 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008936 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008937}
Larry Hastings2f936352014-08-05 14:04:04 +10008938#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008939
Larry Hastings2f936352014-08-05 14:04:04 +10008940
8941/*[clinic input]
8942os.strerror
8943
8944 code: int
8945 /
8946
8947Translate an error code to a message string.
8948[clinic start generated code]*/
8949
Larry Hastings2f936352014-08-05 14:04:04 +10008950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008951os_strerror_impl(PyObject *module, int code)
8952/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008953{
8954 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 if (message == NULL) {
8956 PyErr_SetString(PyExc_ValueError,
8957 "strerror() argument out of range");
8958 return NULL;
8959 }
Victor Stinner1b579672011-12-17 05:47:23 +01008960 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008961}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008962
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008963
Guido van Rossumc9641791998-08-04 15:26:23 +00008964#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008965#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008966/*[clinic input]
8967os.WCOREDUMP -> bool
8968
8969 status: int
8970 /
8971
8972Return True if the process returning status was dumped to a core file.
8973[clinic start generated code]*/
8974
Larry Hastings2f936352014-08-05 14:04:04 +10008975static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008976os_WCOREDUMP_impl(PyObject *module, int status)
8977/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008978{
8979 WAIT_TYPE wait_status;
8980 WAIT_STATUS_INT(wait_status) = status;
8981 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008982}
8983#endif /* WCOREDUMP */
8984
Larry Hastings2f936352014-08-05 14:04:04 +10008985
Fred Drake106c1a02002-04-23 15:58:02 +00008986#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008987/*[clinic input]
8988os.WIFCONTINUED -> bool
8989
8990 status: int
8991
8992Return True if a particular process was continued from a job control stop.
8993
8994Return True if the process returning status was continued from a
8995job control stop.
8996[clinic start generated code]*/
8997
Larry Hastings2f936352014-08-05 14:04:04 +10008998static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008999os_WIFCONTINUED_impl(PyObject *module, int status)
9000/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009001{
9002 WAIT_TYPE wait_status;
9003 WAIT_STATUS_INT(wait_status) = status;
9004 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009005}
9006#endif /* WIFCONTINUED */
9007
Larry Hastings2f936352014-08-05 14:04:04 +10009008
Guido van Rossumc9641791998-08-04 15:26:23 +00009009#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009010/*[clinic input]
9011os.WIFSTOPPED -> bool
9012
9013 status: int
9014
9015Return True if the process returning status was stopped.
9016[clinic start generated code]*/
9017
Larry Hastings2f936352014-08-05 14:04:04 +10009018static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009019os_WIFSTOPPED_impl(PyObject *module, int status)
9020/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009021{
9022 WAIT_TYPE wait_status;
9023 WAIT_STATUS_INT(wait_status) = status;
9024 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009025}
9026#endif /* WIFSTOPPED */
9027
Larry Hastings2f936352014-08-05 14:04:04 +10009028
Guido van Rossumc9641791998-08-04 15:26:23 +00009029#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009030/*[clinic input]
9031os.WIFSIGNALED -> bool
9032
9033 status: int
9034
9035Return True if the process returning status was terminated by a signal.
9036[clinic start generated code]*/
9037
Larry Hastings2f936352014-08-05 14:04:04 +10009038static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009039os_WIFSIGNALED_impl(PyObject *module, int status)
9040/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009041{
9042 WAIT_TYPE wait_status;
9043 WAIT_STATUS_INT(wait_status) = status;
9044 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009045}
9046#endif /* WIFSIGNALED */
9047
Larry Hastings2f936352014-08-05 14:04:04 +10009048
Guido van Rossumc9641791998-08-04 15:26:23 +00009049#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009050/*[clinic input]
9051os.WIFEXITED -> bool
9052
9053 status: int
9054
9055Return True if the process returning status exited via the exit() system call.
9056[clinic start generated code]*/
9057
Larry Hastings2f936352014-08-05 14:04:04 +10009058static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009059os_WIFEXITED_impl(PyObject *module, int status)
9060/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009061{
9062 WAIT_TYPE wait_status;
9063 WAIT_STATUS_INT(wait_status) = status;
9064 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009065}
9066#endif /* WIFEXITED */
9067
Larry Hastings2f936352014-08-05 14:04:04 +10009068
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009069#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009070/*[clinic input]
9071os.WEXITSTATUS -> int
9072
9073 status: int
9074
9075Return the process return code from status.
9076[clinic start generated code]*/
9077
Larry Hastings2f936352014-08-05 14:04:04 +10009078static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009079os_WEXITSTATUS_impl(PyObject *module, int status)
9080/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009081{
9082 WAIT_TYPE wait_status;
9083 WAIT_STATUS_INT(wait_status) = status;
9084 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009085}
9086#endif /* WEXITSTATUS */
9087
Larry Hastings2f936352014-08-05 14:04:04 +10009088
Guido van Rossumc9641791998-08-04 15:26:23 +00009089#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009090/*[clinic input]
9091os.WTERMSIG -> int
9092
9093 status: int
9094
9095Return the signal that terminated the process that provided the status value.
9096[clinic start generated code]*/
9097
Larry Hastings2f936352014-08-05 14:04:04 +10009098static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009099os_WTERMSIG_impl(PyObject *module, int status)
9100/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009101{
9102 WAIT_TYPE wait_status;
9103 WAIT_STATUS_INT(wait_status) = status;
9104 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009105}
9106#endif /* WTERMSIG */
9107
Larry Hastings2f936352014-08-05 14:04:04 +10009108
Guido van Rossumc9641791998-08-04 15:26:23 +00009109#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009110/*[clinic input]
9111os.WSTOPSIG -> int
9112
9113 status: int
9114
9115Return the signal that stopped the process that provided the status value.
9116[clinic start generated code]*/
9117
Larry Hastings2f936352014-08-05 14:04:04 +10009118static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009119os_WSTOPSIG_impl(PyObject *module, int status)
9120/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009121{
9122 WAIT_TYPE wait_status;
9123 WAIT_STATUS_INT(wait_status) = status;
9124 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009125}
9126#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009127#endif /* HAVE_SYS_WAIT_H */
9128
9129
Thomas Wouters477c8d52006-05-27 19:21:47 +00009130#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009131#ifdef _SCO_DS
9132/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9133 needed definitions in sys/statvfs.h */
9134#define _SVID3
9135#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009136#include <sys/statvfs.h>
9137
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009138static PyObject*
9139_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9141 if (v == NULL)
9142 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009143
9144#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9146 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9147 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9148 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9149 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9150 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9151 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9152 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9153 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9154 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009155#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9157 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9158 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009159 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009161 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009163 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009165 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009167 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009169 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009170 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9171 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009172#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009173 if (PyErr_Occurred()) {
9174 Py_DECREF(v);
9175 return NULL;
9176 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009177
Victor Stinner8c62be82010-05-06 00:08:46 +00009178 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009179}
9180
Larry Hastings2f936352014-08-05 14:04:04 +10009181
9182/*[clinic input]
9183os.fstatvfs
9184 fd: int
9185 /
9186
9187Perform an fstatvfs system call on the given fd.
9188
9189Equivalent to statvfs(fd).
9190[clinic start generated code]*/
9191
Larry Hastings2f936352014-08-05 14:04:04 +10009192static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009193os_fstatvfs_impl(PyObject *module, int fd)
9194/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009195{
9196 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009197 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009199
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009200 do {
9201 Py_BEGIN_ALLOW_THREADS
9202 result = fstatvfs(fd, &st);
9203 Py_END_ALLOW_THREADS
9204 } while (result != 0 && errno == EINTR &&
9205 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009206 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009207 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009208
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009210}
Larry Hastings2f936352014-08-05 14:04:04 +10009211#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009212
9213
Thomas Wouters477c8d52006-05-27 19:21:47 +00009214#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009215#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009216/*[clinic input]
9217os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009218
Larry Hastings2f936352014-08-05 14:04:04 +10009219 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9220
9221Perform a statvfs system call on the given path.
9222
9223path may always be specified as a string.
9224On some platforms, path may also be specified as an open file descriptor.
9225 If this functionality is unavailable, using it raises an exception.
9226[clinic start generated code]*/
9227
Larry Hastings2f936352014-08-05 14:04:04 +10009228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009229os_statvfs_impl(PyObject *module, path_t *path)
9230/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009231{
9232 int result;
9233 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009234
9235 Py_BEGIN_ALLOW_THREADS
9236#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009237 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009238#ifdef __APPLE__
9239 /* handle weak-linking on Mac OS X 10.3 */
9240 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009241 fd_specified("statvfs", path->fd);
9242 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009243 }
9244#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009245 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009246 }
9247 else
9248#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009249 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009250 Py_END_ALLOW_THREADS
9251
9252 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009253 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009254 }
9255
Larry Hastings2f936352014-08-05 14:04:04 +10009256 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009257}
Larry Hastings2f936352014-08-05 14:04:04 +10009258#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9259
Guido van Rossum94f6f721999-01-06 18:42:14 +00009260
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009261#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009262/*[clinic input]
9263os._getdiskusage
9264
9265 path: Py_UNICODE
9266
9267Return disk usage statistics about the given path as a (total, free) tuple.
9268[clinic start generated code]*/
9269
Larry Hastings2f936352014-08-05 14:04:04 +10009270static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009271os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9272/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009273{
9274 BOOL retval;
9275 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009276
9277 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009278 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009279 Py_END_ALLOW_THREADS
9280 if (retval == 0)
9281 return PyErr_SetFromWindowsErr(0);
9282
9283 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9284}
Larry Hastings2f936352014-08-05 14:04:04 +10009285#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009286
9287
Fred Drakec9680921999-12-13 16:37:25 +00009288/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9289 * It maps strings representing configuration variable names to
9290 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009291 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009292 * rarely-used constants. There are three separate tables that use
9293 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009294 *
9295 * This code is always included, even if none of the interfaces that
9296 * need it are included. The #if hackery needed to avoid it would be
9297 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009298 */
9299struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009300 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009301 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009302};
9303
Fred Drake12c6e2d1999-12-14 21:25:03 +00009304static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009305conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009306 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009307{
Christian Heimes217cfd12007-12-02 14:31:20 +00009308 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009309 int value = _PyLong_AsInt(arg);
9310 if (value == -1 && PyErr_Occurred())
9311 return 0;
9312 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009313 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009314 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009315 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009316 /* look up the value in the table using a binary search */
9317 size_t lo = 0;
9318 size_t mid;
9319 size_t hi = tablesize;
9320 int cmp;
9321 const char *confname;
9322 if (!PyUnicode_Check(arg)) {
9323 PyErr_SetString(PyExc_TypeError,
9324 "configuration names must be strings or integers");
9325 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009327 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009328 if (confname == NULL)
9329 return 0;
9330 while (lo < hi) {
9331 mid = (lo + hi) / 2;
9332 cmp = strcmp(confname, table[mid].name);
9333 if (cmp < 0)
9334 hi = mid;
9335 else if (cmp > 0)
9336 lo = mid + 1;
9337 else {
9338 *valuep = table[mid].value;
9339 return 1;
9340 }
9341 }
9342 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9343 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009345}
9346
9347
9348#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9349static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009350#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009352#endif
9353#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009355#endif
Fred Drakec9680921999-12-13 16:37:25 +00009356#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009358#endif
9359#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009361#endif
9362#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009364#endif
9365#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009367#endif
9368#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009370#endif
9371#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009373#endif
9374#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009376#endif
9377#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
9398#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009400#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009401#ifdef _PC_ACL_ENABLED
9402 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9403#endif
9404#ifdef _PC_MIN_HOLE_SIZE
9405 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9406#endif
9407#ifdef _PC_ALLOC_SIZE_MIN
9408 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9409#endif
9410#ifdef _PC_REC_INCR_XFER_SIZE
9411 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9412#endif
9413#ifdef _PC_REC_MAX_XFER_SIZE
9414 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9415#endif
9416#ifdef _PC_REC_MIN_XFER_SIZE
9417 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9418#endif
9419#ifdef _PC_REC_XFER_ALIGN
9420 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9421#endif
9422#ifdef _PC_SYMLINK_MAX
9423 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9424#endif
9425#ifdef _PC_XATTR_ENABLED
9426 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9427#endif
9428#ifdef _PC_XATTR_EXISTS
9429 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9430#endif
9431#ifdef _PC_TIMESTAMP_RESOLUTION
9432 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9433#endif
Fred Drakec9680921999-12-13 16:37:25 +00009434};
9435
Fred Drakec9680921999-12-13 16:37:25 +00009436static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009437conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009438{
9439 return conv_confname(arg, valuep, posix_constants_pathconf,
9440 sizeof(posix_constants_pathconf)
9441 / sizeof(struct constdef));
9442}
9443#endif
9444
Larry Hastings2f936352014-08-05 14:04:04 +10009445
Fred Drakec9680921999-12-13 16:37:25 +00009446#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009447/*[clinic input]
9448os.fpathconf -> long
9449
9450 fd: int
9451 name: path_confname
9452 /
9453
9454Return the configuration limit name for the file descriptor fd.
9455
9456If there is no limit, return -1.
9457[clinic start generated code]*/
9458
Larry Hastings2f936352014-08-05 14:04:04 +10009459static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009460os_fpathconf_impl(PyObject *module, int fd, int name)
9461/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009462{
9463 long limit;
9464
9465 errno = 0;
9466 limit = fpathconf(fd, name);
9467 if (limit == -1 && errno != 0)
9468 posix_error();
9469
9470 return limit;
9471}
9472#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009473
9474
9475#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009476/*[clinic input]
9477os.pathconf -> long
9478 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9479 name: path_confname
9480
9481Return the configuration limit name for the file or directory path.
9482
9483If there is no limit, return -1.
9484On some platforms, path may also be specified as an open file descriptor.
9485 If this functionality is unavailable, using it raises an exception.
9486[clinic start generated code]*/
9487
Larry Hastings2f936352014-08-05 14:04:04 +10009488static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009489os_pathconf_impl(PyObject *module, path_t *path, int name)
9490/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009491{
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009493
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009495#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009496 if (path->fd != -1)
9497 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009498 else
9499#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009500 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 if (limit == -1 && errno != 0) {
9502 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009503 /* could be a path or name problem */
9504 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009505 else
Larry Hastings2f936352014-08-05 14:04:04 +10009506 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 }
Larry Hastings2f936352014-08-05 14:04:04 +10009508
9509 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009510}
Larry Hastings2f936352014-08-05 14:04:04 +10009511#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009512
9513#ifdef HAVE_CONFSTR
9514static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009515#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009517#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009518#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009520#endif
9521#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009523#endif
Fred Draked86ed291999-12-15 15:34:33 +00009524#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009526#endif
9527#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009529#endif
9530#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009532#endif
9533#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
Fred Drakec9680921999-12-13 16:37:25 +00009536#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
9539#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
Fred Draked86ed291999-12-15 15:34:33 +00009560#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009562#endif
Fred Drakec9680921999-12-13 16:37:25 +00009563#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
Fred Draked86ed291999-12-15 15:34:33 +00009566#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009568#endif
9569#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009571#endif
9572#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009574#endif
9575#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009577#endif
Fred Drakec9680921999-12-13 16:37:25 +00009578#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
Fred Draked86ed291999-12-15 15:34:33 +00009626#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009628#endif
9629#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009631#endif
9632#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009634#endif
9635#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009637#endif
9638#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009640#endif
9641#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009643#endif
9644#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009646#endif
9647#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009649#endif
9650#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009652#endif
9653#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009655#endif
9656#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009658#endif
9659#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
9662#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
Fred Drakec9680921999-12-13 16:37:25 +00009665};
9666
9667static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009668conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009669{
9670 return conv_confname(arg, valuep, posix_constants_confstr,
9671 sizeof(posix_constants_confstr)
9672 / sizeof(struct constdef));
9673}
9674
Larry Hastings2f936352014-08-05 14:04:04 +10009675
9676/*[clinic input]
9677os.confstr
9678
9679 name: confstr_confname
9680 /
9681
9682Return a string-valued system configuration variable.
9683[clinic start generated code]*/
9684
Larry Hastings2f936352014-08-05 14:04:04 +10009685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009686os_confstr_impl(PyObject *module, int name)
9687/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009688{
9689 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009690 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009691 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009692
Victor Stinnercb043522010-09-10 23:49:04 +00009693 errno = 0;
9694 len = confstr(name, buffer, sizeof(buffer));
9695 if (len == 0) {
9696 if (errno) {
9697 posix_error();
9698 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009699 }
9700 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009701 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009702 }
9703 }
Victor Stinnercb043522010-09-10 23:49:04 +00009704
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009705 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009706 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009707 char *buf = PyMem_Malloc(len);
9708 if (buf == NULL)
9709 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009710 len2 = confstr(name, buf, len);
9711 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009712 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009713 PyMem_Free(buf);
9714 }
9715 else
9716 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009717 return result;
9718}
Larry Hastings2f936352014-08-05 14:04:04 +10009719#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009720
9721
9722#ifdef HAVE_SYSCONF
9723static struct constdef posix_constants_sysconf[] = {
9724#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
9730#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
Fred Draked86ed291999-12-15 15:34:33 +00009754#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009756#endif
9757#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009759#endif
Fred Drakec9680921999-12-13 16:37:25 +00009760#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
Fred Drakec9680921999-12-13 16:37:25 +00009763#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
Fred Draked86ed291999-12-15 15:34:33 +00009778#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009780#endif
Fred Drakec9680921999-12-13 16:37:25 +00009781#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
Fred Draked86ed291999-12-15 15:34:33 +00009796#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009798#endif
Fred Drakec9680921999-12-13 16:37:25 +00009799#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
9838#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009840#endif
9841#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009843#endif
9844#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
Fred Draked86ed291999-12-15 15:34:33 +00009868#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009870#endif
Fred Drakec9680921999-12-13 16:37:25 +00009871#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
Fred Draked86ed291999-12-15 15:34:33 +00009880#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009882#endif
Fred Drakec9680921999-12-13 16:37:25 +00009883#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
Fred Draked86ed291999-12-15 15:34:33 +00009886#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009888#endif
9889#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009891#endif
Fred Drakec9680921999-12-13 16:37:25 +00009892#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
Fred Draked86ed291999-12-15 15:34:33 +00009904#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009906#endif
Fred Drakec9680921999-12-13 16:37:25 +00009907#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
Fred Draked86ed291999-12-15 15:34:33 +00009928#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009930#endif
Fred Drakec9680921999-12-13 16:37:25 +00009931#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
Fred Draked86ed291999-12-15 15:34:33 +00009937#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009939#endif
Fred Drakec9680921999-12-13 16:37:25 +00009940#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
Fred Draked86ed291999-12-15 15:34:33 +00009967#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009969#endif
9970#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009972#endif
Fred Drakec9680921999-12-13 16:37:25 +00009973#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
Fred Draked86ed291999-12-15 15:34:33 +000010078#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010080#endif
Fred Drakec9680921999-12-13 16:37:25 +000010081#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216};
10217
10218static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010219conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010220{
10221 return conv_confname(arg, valuep, posix_constants_sysconf,
10222 sizeof(posix_constants_sysconf)
10223 / sizeof(struct constdef));
10224}
10225
Larry Hastings2f936352014-08-05 14:04:04 +100010226
10227/*[clinic input]
10228os.sysconf -> long
10229 name: sysconf_confname
10230 /
10231
10232Return an integer-valued system configuration variable.
10233[clinic start generated code]*/
10234
Larry Hastings2f936352014-08-05 14:04:04 +100010235static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010236os_sysconf_impl(PyObject *module, int name)
10237/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010238{
10239 long value;
10240
10241 errno = 0;
10242 value = sysconf(name);
10243 if (value == -1 && errno != 0)
10244 posix_error();
10245 return value;
10246}
10247#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010248
10249
Fred Drakebec628d1999-12-15 18:31:10 +000010250/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010251 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010252 * the exported dictionaries that are used to publish information about the
10253 * names available on the host platform.
10254 *
10255 * Sorting the table at runtime ensures that the table is properly ordered
10256 * when used, even for platforms we're not able to test on. It also makes
10257 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010258 */
Fred Drakebec628d1999-12-15 18:31:10 +000010259
10260static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010261cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010262{
10263 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010265 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010267
10268 return strcmp(c1->name, c2->name);
10269}
10270
10271static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010272setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010273 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010274{
Fred Drakebec628d1999-12-15 18:31:10 +000010275 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010276 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010277
10278 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10279 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010280 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010282
Barry Warsaw3155db32000-04-13 15:20:40 +000010283 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 PyObject *o = PyLong_FromLong(table[i].value);
10285 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10286 Py_XDECREF(o);
10287 Py_DECREF(d);
10288 return -1;
10289 }
10290 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010291 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010292 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010293}
10294
Fred Drakebec628d1999-12-15 18:31:10 +000010295/* Return -1 on failure, 0 on success. */
10296static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010297setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010298{
10299#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010300 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010301 sizeof(posix_constants_pathconf)
10302 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010303 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010304 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010305#endif
10306#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010307 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010308 sizeof(posix_constants_confstr)
10309 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010310 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010311 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010312#endif
10313#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010314 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010315 sizeof(posix_constants_sysconf)
10316 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010317 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010318 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010319#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010320 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010321}
Fred Draked86ed291999-12-15 15:34:33 +000010322
10323
Larry Hastings2f936352014-08-05 14:04:04 +100010324/*[clinic input]
10325os.abort
10326
10327Abort the interpreter immediately.
10328
10329This function 'dumps core' or otherwise fails in the hardest way possible
10330on the hosting operating system. This function never returns.
10331[clinic start generated code]*/
10332
Larry Hastings2f936352014-08-05 14:04:04 +100010333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010334os_abort_impl(PyObject *module)
10335/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010336{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010337 abort();
10338 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010339#ifndef __clang__
10340 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10341 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10342 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010343 Py_FatalError("abort() called from Python code didn't abort!");
10344 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010345#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010346}
Fred Drakebec628d1999-12-15 18:31:10 +000010347
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010348#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010349/* Grab ShellExecute dynamically from shell32 */
10350static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010351static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10352 LPCWSTR, INT);
10353static int
10354check_ShellExecute()
10355{
10356 HINSTANCE hShell32;
10357
10358 /* only recheck */
10359 if (-1 == has_ShellExecute) {
10360 Py_BEGIN_ALLOW_THREADS
10361 hShell32 = LoadLibraryW(L"SHELL32");
10362 Py_END_ALLOW_THREADS
10363 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010364 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10365 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010366 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010367 } else {
10368 has_ShellExecute = 0;
10369 }
10370 }
10371 return has_ShellExecute;
10372}
10373
10374
Steve Dowercc16be82016-09-08 10:35:16 -070010375/*[clinic input]
10376os.startfile
10377 filepath: path_t
10378 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010379
Steve Dowercc16be82016-09-08 10:35:16 -070010380startfile(filepath [, operation])
10381
10382Start a file with its associated application.
10383
10384When "operation" is not specified or "open", this acts like
10385double-clicking the file in Explorer, or giving the file name as an
10386argument to the DOS "start" command: the file is opened with whatever
10387application (if any) its extension is associated.
10388When another "operation" is given, it specifies what should be done with
10389the file. A typical operation is "print".
10390
10391startfile returns as soon as the associated application is launched.
10392There is no option to wait for the application to close, and no way
10393to retrieve the application's exit status.
10394
10395The filepath is relative to the current directory. If you want to use
10396an absolute path, make sure the first character is not a slash ("/");
10397the underlying Win32 ShellExecute function doesn't work if it is.
10398[clinic start generated code]*/
10399
10400static PyObject *
10401os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10402/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10403{
10404 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010405
10406 if(!check_ShellExecute()) {
10407 /* If the OS doesn't have ShellExecute, return a
10408 NotImplementedError. */
10409 return PyErr_Format(PyExc_NotImplementedError,
10410 "startfile not available on this platform");
10411 }
10412
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010414 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010415 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 Py_END_ALLOW_THREADS
10417
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010419 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010420 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 }
Steve Dowercc16be82016-09-08 10:35:16 -070010422 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010423}
Larry Hastings2f936352014-08-05 14:04:04 +100010424#endif /* MS_WINDOWS */
10425
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010426
Martin v. Löwis438b5342002-12-27 10:16:42 +000010427#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010428/*[clinic input]
10429os.getloadavg
10430
10431Return average recent system load information.
10432
10433Return the number of processes in the system run queue averaged over
10434the last 1, 5, and 15 minutes as a tuple of three floats.
10435Raises OSError if the load average was unobtainable.
10436[clinic start generated code]*/
10437
Larry Hastings2f936352014-08-05 14:04:04 +100010438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010439os_getloadavg_impl(PyObject *module)
10440/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010441{
10442 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010443 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010444 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10445 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010446 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010447 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010448}
Larry Hastings2f936352014-08-05 14:04:04 +100010449#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010450
Larry Hastings2f936352014-08-05 14:04:04 +100010451
10452/*[clinic input]
10453os.device_encoding
10454 fd: int
10455
10456Return a string describing the encoding of a terminal's file descriptor.
10457
10458The file descriptor must be attached to a terminal.
10459If the device is not a terminal, return None.
10460[clinic start generated code]*/
10461
Larry Hastings2f936352014-08-05 14:04:04 +100010462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010463os_device_encoding_impl(PyObject *module, int fd)
10464/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010465{
Brett Cannonefb00c02012-02-29 18:31:31 -050010466 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010467}
10468
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010469
Larry Hastings2f936352014-08-05 14:04:04 +100010470#ifdef HAVE_SETRESUID
10471/*[clinic input]
10472os.setresuid
10473
10474 ruid: uid_t
10475 euid: uid_t
10476 suid: uid_t
10477 /
10478
10479Set the current process's real, effective, and saved user ids.
10480[clinic start generated code]*/
10481
Larry Hastings2f936352014-08-05 14:04:04 +100010482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010483os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10484/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010485{
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 if (setresuid(ruid, euid, suid) < 0)
10487 return posix_error();
10488 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010489}
Larry Hastings2f936352014-08-05 14:04:04 +100010490#endif /* HAVE_SETRESUID */
10491
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010492
10493#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010494/*[clinic input]
10495os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010496
Larry Hastings2f936352014-08-05 14:04:04 +100010497 rgid: gid_t
10498 egid: gid_t
10499 sgid: gid_t
10500 /
10501
10502Set the current process's real, effective, and saved group ids.
10503[clinic start generated code]*/
10504
Larry Hastings2f936352014-08-05 14:04:04 +100010505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010506os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10507/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010508{
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 if (setresgid(rgid, egid, sgid) < 0)
10510 return posix_error();
10511 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010512}
Larry Hastings2f936352014-08-05 14:04:04 +100010513#endif /* HAVE_SETRESGID */
10514
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010515
10516#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010517/*[clinic input]
10518os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010519
Larry Hastings2f936352014-08-05 14:04:04 +100010520Return a tuple of the current process's real, effective, and saved user ids.
10521[clinic start generated code]*/
10522
Larry Hastings2f936352014-08-05 14:04:04 +100010523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010524os_getresuid_impl(PyObject *module)
10525/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010526{
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 if (getresuid(&ruid, &euid, &suid) < 0)
10529 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010530 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10531 _PyLong_FromUid(euid),
10532 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010533}
Larry Hastings2f936352014-08-05 14:04:04 +100010534#endif /* HAVE_GETRESUID */
10535
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010536
10537#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010538/*[clinic input]
10539os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010540
Larry Hastings2f936352014-08-05 14:04:04 +100010541Return a tuple of the current process's real, effective, and saved group ids.
10542[clinic start generated code]*/
10543
Larry Hastings2f936352014-08-05 14:04:04 +100010544static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010545os_getresgid_impl(PyObject *module)
10546/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010547{
10548 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 if (getresgid(&rgid, &egid, &sgid) < 0)
10550 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010551 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10552 _PyLong_FromGid(egid),
10553 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010554}
Larry Hastings2f936352014-08-05 14:04:04 +100010555#endif /* HAVE_GETRESGID */
10556
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010557
Benjamin Peterson9428d532011-09-14 11:45:52 -040010558#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010559/*[clinic input]
10560os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561
Larry Hastings2f936352014-08-05 14:04:04 +100010562 path: path_t(allow_fd=True)
10563 attribute: path_t
10564 *
10565 follow_symlinks: bool = True
10566
10567Return the value of extended attribute attribute on path.
10568
10569path may be either a string or an open file descriptor.
10570If follow_symlinks is False, and the last element of the path is a symbolic
10571 link, getxattr will examine the symbolic link itself instead of the file
10572 the link points to.
10573
10574[clinic start generated code]*/
10575
Larry Hastings2f936352014-08-05 14:04:04 +100010576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010577os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010578 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010579/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010580{
10581 Py_ssize_t i;
10582 PyObject *buffer = NULL;
10583
10584 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10585 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010586
Larry Hastings9cf065c2012-06-22 16:30:09 -070010587 for (i = 0; ; i++) {
10588 void *ptr;
10589 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010590 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010591 Py_ssize_t buffer_size = buffer_sizes[i];
10592 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010593 path_error(path);
10594 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 }
10596 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10597 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010598 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010600
Larry Hastings9cf065c2012-06-22 16:30:09 -070010601 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010602 if (path->fd >= 0)
10603 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010604 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010605 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 else
Larry Hastings2f936352014-08-05 14:04:04 +100010607 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010609
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 if (result < 0) {
10611 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 if (errno == ERANGE)
10613 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010614 path_error(path);
10615 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010617
Larry Hastings9cf065c2012-06-22 16:30:09 -070010618 if (result != buffer_size) {
10619 /* Can only shrink. */
10620 _PyBytes_Resize(&buffer, result);
10621 }
10622 break;
10623 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010624
Larry Hastings9cf065c2012-06-22 16:30:09 -070010625 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626}
10627
Larry Hastings2f936352014-08-05 14:04:04 +100010628
10629/*[clinic input]
10630os.setxattr
10631
10632 path: path_t(allow_fd=True)
10633 attribute: path_t
10634 value: Py_buffer
10635 flags: int = 0
10636 *
10637 follow_symlinks: bool = True
10638
10639Set extended attribute attribute on path to value.
10640
10641path may be either a string or an open file descriptor.
10642If follow_symlinks is False, and the last element of the path is a symbolic
10643 link, setxattr will modify the symbolic link itself instead of the file
10644 the link points to.
10645
10646[clinic start generated code]*/
10647
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010649os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010650 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010651/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652{
Larry Hastings2f936352014-08-05 14:04:04 +100010653 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010654
Larry Hastings2f936352014-08-05 14:04:04 +100010655 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010657
Benjamin Peterson799bd802011-08-31 22:15:17 -040010658 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010659 if (path->fd > -1)
10660 result = fsetxattr(path->fd, attribute->narrow,
10661 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010662 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010663 result = setxattr(path->narrow, attribute->narrow,
10664 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010665 else
Larry Hastings2f936352014-08-05 14:04:04 +100010666 result = lsetxattr(path->narrow, attribute->narrow,
10667 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010668 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010669
Larry Hastings9cf065c2012-06-22 16:30:09 -070010670 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010671 path_error(path);
10672 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010673 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010674
Larry Hastings2f936352014-08-05 14:04:04 +100010675 Py_RETURN_NONE;
10676}
10677
10678
10679/*[clinic input]
10680os.removexattr
10681
10682 path: path_t(allow_fd=True)
10683 attribute: path_t
10684 *
10685 follow_symlinks: bool = True
10686
10687Remove extended attribute attribute on path.
10688
10689path may be either a string or an open file descriptor.
10690If follow_symlinks is False, and the last element of the path is a symbolic
10691 link, removexattr will modify the symbolic link itself instead of the file
10692 the link points to.
10693
10694[clinic start generated code]*/
10695
Larry Hastings2f936352014-08-05 14:04:04 +100010696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010697os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010698 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010699/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010700{
10701 ssize_t result;
10702
10703 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10704 return NULL;
10705
10706 Py_BEGIN_ALLOW_THREADS;
10707 if (path->fd > -1)
10708 result = fremovexattr(path->fd, attribute->narrow);
10709 else if (follow_symlinks)
10710 result = removexattr(path->narrow, attribute->narrow);
10711 else
10712 result = lremovexattr(path->narrow, attribute->narrow);
10713 Py_END_ALLOW_THREADS;
10714
10715 if (result) {
10716 return path_error(path);
10717 }
10718
10719 Py_RETURN_NONE;
10720}
10721
10722
10723/*[clinic input]
10724os.listxattr
10725
10726 path: path_t(allow_fd=True, nullable=True) = None
10727 *
10728 follow_symlinks: bool = True
10729
10730Return a list of extended attributes on path.
10731
10732path may be either None, a string, or an open file descriptor.
10733if path is None, listxattr will examine the current directory.
10734If follow_symlinks is False, and the last element of the path is a symbolic
10735 link, listxattr will examine the symbolic link itself instead of the file
10736 the link points to.
10737[clinic start generated code]*/
10738
Larry Hastings2f936352014-08-05 14:04:04 +100010739static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010740os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10741/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010742{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 Py_ssize_t i;
10744 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010745 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010746 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010747
Larry Hastings2f936352014-08-05 14:04:04 +100010748 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010750
Larry Hastings2f936352014-08-05 14:04:04 +100010751 name = path->narrow ? path->narrow : ".";
10752
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010754 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010756 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 Py_ssize_t buffer_size = buffer_sizes[i];
10758 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010759 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010760 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761 break;
10762 }
10763 buffer = PyMem_MALLOC(buffer_size);
10764 if (!buffer) {
10765 PyErr_NoMemory();
10766 break;
10767 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010768
Larry Hastings9cf065c2012-06-22 16:30:09 -070010769 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010770 if (path->fd > -1)
10771 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 else if (follow_symlinks)
10773 length = listxattr(name, buffer, buffer_size);
10774 else
10775 length = llistxattr(name, buffer, buffer_size);
10776 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010777
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010779 if (errno == ERANGE) {
10780 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010781 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010783 }
Larry Hastings2f936352014-08-05 14:04:04 +100010784 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010785 break;
10786 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010787
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 result = PyList_New(0);
10789 if (!result) {
10790 goto exit;
10791 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010792
Larry Hastings9cf065c2012-06-22 16:30:09 -070010793 end = buffer + length;
10794 for (trace = start = buffer; trace != end; trace++) {
10795 if (!*trace) {
10796 int error;
10797 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10798 trace - start);
10799 if (!attribute) {
10800 Py_DECREF(result);
10801 result = NULL;
10802 goto exit;
10803 }
10804 error = PyList_Append(result, attribute);
10805 Py_DECREF(attribute);
10806 if (error) {
10807 Py_DECREF(result);
10808 result = NULL;
10809 goto exit;
10810 }
10811 start = trace + 1;
10812 }
10813 }
10814 break;
10815 }
10816exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817 if (buffer)
10818 PyMem_FREE(buffer);
10819 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010821#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010822
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010823
Larry Hastings2f936352014-08-05 14:04:04 +100010824/*[clinic input]
10825os.urandom
10826
10827 size: Py_ssize_t
10828 /
10829
10830Return a bytes object containing random bytes suitable for cryptographic use.
10831[clinic start generated code]*/
10832
Larry Hastings2f936352014-08-05 14:04:04 +100010833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010834os_urandom_impl(PyObject *module, Py_ssize_t size)
10835/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010836{
10837 PyObject *bytes;
10838 int result;
10839
Georg Brandl2fb477c2012-02-21 00:33:36 +010010840 if (size < 0)
10841 return PyErr_Format(PyExc_ValueError,
10842 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010843 bytes = PyBytes_FromStringAndSize(NULL, size);
10844 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010845 return NULL;
10846
Victor Stinnere66987e2016-09-06 16:33:52 -070010847 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010848 if (result == -1) {
10849 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010850 return NULL;
10851 }
Larry Hastings2f936352014-08-05 14:04:04 +100010852 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010853}
10854
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010855/* Terminal size querying */
10856
10857static PyTypeObject TerminalSizeType;
10858
10859PyDoc_STRVAR(TerminalSize_docstring,
10860 "A tuple of (columns, lines) for holding terminal window size");
10861
10862static PyStructSequence_Field TerminalSize_fields[] = {
10863 {"columns", "width of the terminal window in characters"},
10864 {"lines", "height of the terminal window in characters"},
10865 {NULL, NULL}
10866};
10867
10868static PyStructSequence_Desc TerminalSize_desc = {
10869 "os.terminal_size",
10870 TerminalSize_docstring,
10871 TerminalSize_fields,
10872 2,
10873};
10874
10875#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010876/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010877PyDoc_STRVAR(termsize__doc__,
10878 "Return the size of the terminal window as (columns, lines).\n" \
10879 "\n" \
10880 "The optional argument fd (default standard output) specifies\n" \
10881 "which file descriptor should be queried.\n" \
10882 "\n" \
10883 "If the file descriptor is not connected to a terminal, an OSError\n" \
10884 "is thrown.\n" \
10885 "\n" \
10886 "This function will only be defined if an implementation is\n" \
10887 "available for this system.\n" \
10888 "\n" \
10889 "shutil.get_terminal_size is the high-level function which should \n" \
10890 "normally be used, os.get_terminal_size is the low-level implementation.");
10891
10892static PyObject*
10893get_terminal_size(PyObject *self, PyObject *args)
10894{
10895 int columns, lines;
10896 PyObject *termsize;
10897
10898 int fd = fileno(stdout);
10899 /* Under some conditions stdout may not be connected and
10900 * fileno(stdout) may point to an invalid file descriptor. For example
10901 * GUI apps don't have valid standard streams by default.
10902 *
10903 * If this happens, and the optional fd argument is not present,
10904 * the ioctl below will fail returning EBADF. This is what we want.
10905 */
10906
10907 if (!PyArg_ParseTuple(args, "|i", &fd))
10908 return NULL;
10909
10910#ifdef TERMSIZE_USE_IOCTL
10911 {
10912 struct winsize w;
10913 if (ioctl(fd, TIOCGWINSZ, &w))
10914 return PyErr_SetFromErrno(PyExc_OSError);
10915 columns = w.ws_col;
10916 lines = w.ws_row;
10917 }
10918#endif /* TERMSIZE_USE_IOCTL */
10919
10920#ifdef TERMSIZE_USE_CONIO
10921 {
10922 DWORD nhandle;
10923 HANDLE handle;
10924 CONSOLE_SCREEN_BUFFER_INFO csbi;
10925 switch (fd) {
10926 case 0: nhandle = STD_INPUT_HANDLE;
10927 break;
10928 case 1: nhandle = STD_OUTPUT_HANDLE;
10929 break;
10930 case 2: nhandle = STD_ERROR_HANDLE;
10931 break;
10932 default:
10933 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10934 }
10935 handle = GetStdHandle(nhandle);
10936 if (handle == NULL)
10937 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10938 if (handle == INVALID_HANDLE_VALUE)
10939 return PyErr_SetFromWindowsErr(0);
10940
10941 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10942 return PyErr_SetFromWindowsErr(0);
10943
10944 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10945 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10946 }
10947#endif /* TERMSIZE_USE_CONIO */
10948
10949 termsize = PyStructSequence_New(&TerminalSizeType);
10950 if (termsize == NULL)
10951 return NULL;
10952 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10953 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10954 if (PyErr_Occurred()) {
10955 Py_DECREF(termsize);
10956 return NULL;
10957 }
10958 return termsize;
10959}
10960#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10961
Larry Hastings2f936352014-08-05 14:04:04 +100010962
10963/*[clinic input]
10964os.cpu_count
10965
Charles-François Natali80d62e62015-08-13 20:37:08 +010010966Return the number of CPUs in the system; return None if indeterminable.
10967
10968This number is not equivalent to the number of CPUs the current process can
10969use. The number of usable CPUs can be obtained with
10970``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010971[clinic start generated code]*/
10972
Larry Hastings2f936352014-08-05 14:04:04 +100010973static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010974os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010975/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010976{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010977 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010978#ifdef MS_WINDOWS
10979 SYSTEM_INFO sysinfo;
10980 GetSystemInfo(&sysinfo);
10981 ncpu = sysinfo.dwNumberOfProcessors;
10982#elif defined(__hpux)
10983 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10984#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10985 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010986#elif defined(__DragonFly__) || \
10987 defined(__OpenBSD__) || \
10988 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010989 defined(__NetBSD__) || \
10990 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010991 int mib[2];
10992 size_t len = sizeof(ncpu);
10993 mib[0] = CTL_HW;
10994 mib[1] = HW_NCPU;
10995 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10996 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010997#endif
10998 if (ncpu >= 1)
10999 return PyLong_FromLong(ncpu);
11000 else
11001 Py_RETURN_NONE;
11002}
11003
Victor Stinnerdaf45552013-08-28 00:53:59 +020011004
Larry Hastings2f936352014-08-05 14:04:04 +100011005/*[clinic input]
11006os.get_inheritable -> bool
11007
11008 fd: int
11009 /
11010
11011Get the close-on-exe flag of the specified file descriptor.
11012[clinic start generated code]*/
11013
Larry Hastings2f936352014-08-05 14:04:04 +100011014static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011015os_get_inheritable_impl(PyObject *module, int fd)
11016/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011017{
Steve Dower8fc89802015-04-12 00:26:27 -040011018 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011019 _Py_BEGIN_SUPPRESS_IPH
11020 return_value = _Py_get_inheritable(fd);
11021 _Py_END_SUPPRESS_IPH
11022 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011023}
11024
11025
11026/*[clinic input]
11027os.set_inheritable
11028 fd: int
11029 inheritable: int
11030 /
11031
11032Set the inheritable flag of the specified file descriptor.
11033[clinic start generated code]*/
11034
Larry Hastings2f936352014-08-05 14:04:04 +100011035static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011036os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11037/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011038{
Steve Dower8fc89802015-04-12 00:26:27 -040011039 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011040
Steve Dower8fc89802015-04-12 00:26:27 -040011041 _Py_BEGIN_SUPPRESS_IPH
11042 result = _Py_set_inheritable(fd, inheritable, NULL);
11043 _Py_END_SUPPRESS_IPH
11044 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011045 return NULL;
11046 Py_RETURN_NONE;
11047}
11048
11049
11050#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011051/*[clinic input]
11052os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011053 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011054 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011055
Larry Hastings2f936352014-08-05 14:04:04 +100011056Get the close-on-exe flag of the specified file descriptor.
11057[clinic start generated code]*/
11058
Larry Hastings2f936352014-08-05 14:04:04 +100011059static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011060os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011061/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011062{
11063 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011064
11065 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11066 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011067 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011068 }
11069
Larry Hastings2f936352014-08-05 14:04:04 +100011070 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011071}
11072
Victor Stinnerdaf45552013-08-28 00:53:59 +020011073
Larry Hastings2f936352014-08-05 14:04:04 +100011074/*[clinic input]
11075os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011076 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011077 inheritable: bool
11078 /
11079
11080Set the inheritable flag of the specified handle.
11081[clinic start generated code]*/
11082
Larry Hastings2f936352014-08-05 14:04:04 +100011083static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011084os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011085 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011086/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011087{
11088 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011089 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11090 PyErr_SetFromWindowsErr(0);
11091 return NULL;
11092 }
11093 Py_RETURN_NONE;
11094}
Larry Hastings2f936352014-08-05 14:04:04 +100011095#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011096
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011097#ifndef MS_WINDOWS
11098PyDoc_STRVAR(get_blocking__doc__,
11099 "get_blocking(fd) -> bool\n" \
11100 "\n" \
11101 "Get the blocking mode of the file descriptor:\n" \
11102 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11103
11104static PyObject*
11105posix_get_blocking(PyObject *self, PyObject *args)
11106{
11107 int fd;
11108 int blocking;
11109
11110 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11111 return NULL;
11112
Steve Dower8fc89802015-04-12 00:26:27 -040011113 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011114 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011115 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011116 if (blocking < 0)
11117 return NULL;
11118 return PyBool_FromLong(blocking);
11119}
11120
11121PyDoc_STRVAR(set_blocking__doc__,
11122 "set_blocking(fd, blocking)\n" \
11123 "\n" \
11124 "Set the blocking mode of the specified file descriptor.\n" \
11125 "Set the O_NONBLOCK flag if blocking is False,\n" \
11126 "clear the O_NONBLOCK flag otherwise.");
11127
11128static PyObject*
11129posix_set_blocking(PyObject *self, PyObject *args)
11130{
Steve Dower8fc89802015-04-12 00:26:27 -040011131 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011132
11133 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11134 return NULL;
11135
Steve Dower8fc89802015-04-12 00:26:27 -040011136 _Py_BEGIN_SUPPRESS_IPH
11137 result = _Py_set_blocking(fd, blocking);
11138 _Py_END_SUPPRESS_IPH
11139 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011140 return NULL;
11141 Py_RETURN_NONE;
11142}
11143#endif /* !MS_WINDOWS */
11144
11145
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011146/*[clinic input]
11147class os.DirEntry "DirEntry *" "&DirEntryType"
11148[clinic start generated code]*/
11149/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011150
11151typedef struct {
11152 PyObject_HEAD
11153 PyObject *name;
11154 PyObject *path;
11155 PyObject *stat;
11156 PyObject *lstat;
11157#ifdef MS_WINDOWS
11158 struct _Py_stat_struct win32_lstat;
11159 __int64 win32_file_index;
11160 int got_file_index;
11161#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011162#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011163 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011164#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011165 ino_t d_ino;
11166#endif
11167} DirEntry;
11168
11169static void
11170DirEntry_dealloc(DirEntry *entry)
11171{
11172 Py_XDECREF(entry->name);
11173 Py_XDECREF(entry->path);
11174 Py_XDECREF(entry->stat);
11175 Py_XDECREF(entry->lstat);
11176 Py_TYPE(entry)->tp_free((PyObject *)entry);
11177}
11178
11179/* Forward reference */
11180static int
11181DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11182
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011183/*[clinic input]
11184os.DirEntry.is_symlink -> bool
11185
11186Return True if the entry is a symbolic link; cached per entry.
11187[clinic start generated code]*/
11188
Victor Stinner6036e442015-03-08 01:58:04 +010011189static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011190os_DirEntry_is_symlink_impl(DirEntry *self)
11191/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011192{
11193#ifdef MS_WINDOWS
11194 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011195#elif defined(HAVE_DIRENT_D_TYPE)
11196 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011197 if (self->d_type != DT_UNKNOWN)
11198 return self->d_type == DT_LNK;
11199 else
11200 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011201#else
11202 /* POSIX without d_type */
11203 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011204#endif
11205}
11206
11207static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011208DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11209{
11210 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011211 STRUCT_STAT st;
11212 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011213
11214#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011215 if (PyUnicode_FSDecoder(self->path, &ub)) {
11216 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011217#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011218 if (PyUnicode_FSConverter(self->path, &ub)) {
11219 const char *path = PyBytes_AS_STRING(ub);
11220#endif
11221 if (follow_symlinks)
11222 result = STAT(path, &st);
11223 else
11224 result = LSTAT(path, &st);
11225 Py_DECREF(ub);
11226 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011227 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011228
11229 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011230 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011231
11232 return _pystat_fromstructstat(&st);
11233}
11234
11235static PyObject *
11236DirEntry_get_lstat(DirEntry *self)
11237{
11238 if (!self->lstat) {
11239#ifdef MS_WINDOWS
11240 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11241#else /* POSIX */
11242 self->lstat = DirEntry_fetch_stat(self, 0);
11243#endif
11244 }
11245 Py_XINCREF(self->lstat);
11246 return self->lstat;
11247}
11248
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011249/*[clinic input]
11250os.DirEntry.stat
11251 *
11252 follow_symlinks: bool = True
11253
11254Return stat_result object for the entry; cached per entry.
11255[clinic start generated code]*/
11256
Victor Stinner6036e442015-03-08 01:58:04 +010011257static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011258os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11259/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011260{
11261 if (!follow_symlinks)
11262 return DirEntry_get_lstat(self);
11263
11264 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011265 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011266 if (result == -1)
11267 return NULL;
11268 else if (result)
11269 self->stat = DirEntry_fetch_stat(self, 1);
11270 else
11271 self->stat = DirEntry_get_lstat(self);
11272 }
11273
11274 Py_XINCREF(self->stat);
11275 return self->stat;
11276}
11277
Victor Stinner6036e442015-03-08 01:58:04 +010011278/* Set exception and return -1 on error, 0 for False, 1 for True */
11279static int
11280DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11281{
11282 PyObject *stat = NULL;
11283 PyObject *st_mode = NULL;
11284 long mode;
11285 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011286#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011287 int is_symlink;
11288 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011289#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011290#ifdef MS_WINDOWS
11291 unsigned long dir_bits;
11292#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011293 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011294
11295#ifdef MS_WINDOWS
11296 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11297 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011298#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011299 is_symlink = self->d_type == DT_LNK;
11300 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11301#endif
11302
Victor Stinner35a97c02015-03-08 02:59:09 +010011303#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011304 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011305#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011306 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011307 if (!stat) {
11308 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11309 /* If file doesn't exist (anymore), then return False
11310 (i.e., say it's not a file/directory) */
11311 PyErr_Clear();
11312 return 0;
11313 }
11314 goto error;
11315 }
11316 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11317 if (!st_mode)
11318 goto error;
11319
11320 mode = PyLong_AsLong(st_mode);
11321 if (mode == -1 && PyErr_Occurred())
11322 goto error;
11323 Py_CLEAR(st_mode);
11324 Py_CLEAR(stat);
11325 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011326#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011327 }
11328 else if (is_symlink) {
11329 assert(mode_bits != S_IFLNK);
11330 result = 0;
11331 }
11332 else {
11333 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11334#ifdef MS_WINDOWS
11335 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11336 if (mode_bits == S_IFDIR)
11337 result = dir_bits != 0;
11338 else
11339 result = dir_bits == 0;
11340#else /* POSIX */
11341 if (mode_bits == S_IFDIR)
11342 result = self->d_type == DT_DIR;
11343 else
11344 result = self->d_type == DT_REG;
11345#endif
11346 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011347#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011348
11349 return result;
11350
11351error:
11352 Py_XDECREF(st_mode);
11353 Py_XDECREF(stat);
11354 return -1;
11355}
11356
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011357/*[clinic input]
11358os.DirEntry.is_dir -> bool
11359 *
11360 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011361
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011362Return True if the entry is a directory; cached per entry.
11363[clinic start generated code]*/
11364
11365static int
11366os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11367/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11368{
11369 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011370}
11371
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011372/*[clinic input]
11373os.DirEntry.is_file -> bool
11374 *
11375 follow_symlinks: bool = True
11376
11377Return True if the entry is a file; cached per entry.
11378[clinic start generated code]*/
11379
11380static int
11381os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11382/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011383{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011384 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011385}
11386
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011387/*[clinic input]
11388os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011389
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011390Return inode of the entry; cached per entry.
11391[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011392
11393static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011394os_DirEntry_inode_impl(DirEntry *self)
11395/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011396{
11397#ifdef MS_WINDOWS
11398 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011399 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011400 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011401 STRUCT_STAT stat;
11402 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011403
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011404 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011405 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011406 path = PyUnicode_AsUnicode(unicode);
11407 result = LSTAT(path, &stat);
11408 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011409
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011410 if (result != 0)
11411 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011412
11413 self->win32_file_index = stat.st_ino;
11414 self->got_file_index = 1;
11415 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011416 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011417#else /* POSIX */
11418#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011419 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011420#else
11421 return PyLong_FromLong((long)self->d_ino);
11422#endif
11423#endif
11424}
11425
11426static PyObject *
11427DirEntry_repr(DirEntry *self)
11428{
11429 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11430}
11431
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011432/*[clinic input]
11433os.DirEntry.__fspath__
11434
11435Returns the path for the entry.
11436[clinic start generated code]*/
11437
Brett Cannon96881cd2016-06-10 14:37:21 -070011438static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011439os_DirEntry___fspath___impl(DirEntry *self)
11440/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011441{
11442 Py_INCREF(self->path);
11443 return self->path;
11444}
11445
Victor Stinner6036e442015-03-08 01:58:04 +010011446static PyMemberDef DirEntry_members[] = {
11447 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11448 "the entry's base filename, relative to scandir() \"path\" argument"},
11449 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11450 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11451 {NULL}
11452};
11453
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011454#include "clinic/posixmodule.c.h"
11455
Victor Stinner6036e442015-03-08 01:58:04 +010011456static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011457 OS_DIRENTRY_IS_DIR_METHODDEF
11458 OS_DIRENTRY_IS_FILE_METHODDEF
11459 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11460 OS_DIRENTRY_STAT_METHODDEF
11461 OS_DIRENTRY_INODE_METHODDEF
11462 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011463 {NULL}
11464};
11465
Benjamin Peterson5646de42015-04-12 17:56:34 -040011466static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011467 PyVarObject_HEAD_INIT(NULL, 0)
11468 MODNAME ".DirEntry", /* tp_name */
11469 sizeof(DirEntry), /* tp_basicsize */
11470 0, /* tp_itemsize */
11471 /* methods */
11472 (destructor)DirEntry_dealloc, /* tp_dealloc */
11473 0, /* tp_print */
11474 0, /* tp_getattr */
11475 0, /* tp_setattr */
11476 0, /* tp_compare */
11477 (reprfunc)DirEntry_repr, /* tp_repr */
11478 0, /* tp_as_number */
11479 0, /* tp_as_sequence */
11480 0, /* tp_as_mapping */
11481 0, /* tp_hash */
11482 0, /* tp_call */
11483 0, /* tp_str */
11484 0, /* tp_getattro */
11485 0, /* tp_setattro */
11486 0, /* tp_as_buffer */
11487 Py_TPFLAGS_DEFAULT, /* tp_flags */
11488 0, /* tp_doc */
11489 0, /* tp_traverse */
11490 0, /* tp_clear */
11491 0, /* tp_richcompare */
11492 0, /* tp_weaklistoffset */
11493 0, /* tp_iter */
11494 0, /* tp_iternext */
11495 DirEntry_methods, /* tp_methods */
11496 DirEntry_members, /* tp_members */
11497};
11498
11499#ifdef MS_WINDOWS
11500
11501static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011502join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011503{
11504 Py_ssize_t path_len;
11505 Py_ssize_t size;
11506 wchar_t *result;
11507 wchar_t ch;
11508
11509 if (!path_wide) { /* Default arg: "." */
11510 path_wide = L".";
11511 path_len = 1;
11512 }
11513 else {
11514 path_len = wcslen(path_wide);
11515 }
11516
11517 /* The +1's are for the path separator and the NUL */
11518 size = path_len + 1 + wcslen(filename) + 1;
11519 result = PyMem_New(wchar_t, size);
11520 if (!result) {
11521 PyErr_NoMemory();
11522 return NULL;
11523 }
11524 wcscpy(result, path_wide);
11525 if (path_len > 0) {
11526 ch = result[path_len - 1];
11527 if (ch != SEP && ch != ALTSEP && ch != L':')
11528 result[path_len++] = SEP;
11529 wcscpy(result + path_len, filename);
11530 }
11531 return result;
11532}
11533
11534static PyObject *
11535DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11536{
11537 DirEntry *entry;
11538 BY_HANDLE_FILE_INFORMATION file_info;
11539 ULONG reparse_tag;
11540 wchar_t *joined_path;
11541
11542 entry = PyObject_New(DirEntry, &DirEntryType);
11543 if (!entry)
11544 return NULL;
11545 entry->name = NULL;
11546 entry->path = NULL;
11547 entry->stat = NULL;
11548 entry->lstat = NULL;
11549 entry->got_file_index = 0;
11550
11551 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11552 if (!entry->name)
11553 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011554 if (path->narrow) {
11555 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11556 if (!entry->name)
11557 goto error;
11558 }
Victor Stinner6036e442015-03-08 01:58:04 +010011559
11560 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11561 if (!joined_path)
11562 goto error;
11563
11564 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11565 PyMem_Free(joined_path);
11566 if (!entry->path)
11567 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011568 if (path->narrow) {
11569 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11570 if (!entry->path)
11571 goto error;
11572 }
Victor Stinner6036e442015-03-08 01:58:04 +010011573
Steve Dowercc16be82016-09-08 10:35:16 -070011574 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011575 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11576
11577 return (PyObject *)entry;
11578
11579error:
11580 Py_DECREF(entry);
11581 return NULL;
11582}
11583
11584#else /* POSIX */
11585
11586static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011587join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011588{
11589 Py_ssize_t path_len;
11590 Py_ssize_t size;
11591 char *result;
11592
11593 if (!path_narrow) { /* Default arg: "." */
11594 path_narrow = ".";
11595 path_len = 1;
11596 }
11597 else {
11598 path_len = strlen(path_narrow);
11599 }
11600
11601 if (filename_len == -1)
11602 filename_len = strlen(filename);
11603
11604 /* The +1's are for the path separator and the NUL */
11605 size = path_len + 1 + filename_len + 1;
11606 result = PyMem_New(char, size);
11607 if (!result) {
11608 PyErr_NoMemory();
11609 return NULL;
11610 }
11611 strcpy(result, path_narrow);
11612 if (path_len > 0 && result[path_len - 1] != '/')
11613 result[path_len++] = '/';
11614 strcpy(result + path_len, filename);
11615 return result;
11616}
11617
11618static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011619DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011620 ino_t d_ino
11621#ifdef HAVE_DIRENT_D_TYPE
11622 , unsigned char d_type
11623#endif
11624 )
Victor Stinner6036e442015-03-08 01:58:04 +010011625{
11626 DirEntry *entry;
11627 char *joined_path;
11628
11629 entry = PyObject_New(DirEntry, &DirEntryType);
11630 if (!entry)
11631 return NULL;
11632 entry->name = NULL;
11633 entry->path = NULL;
11634 entry->stat = NULL;
11635 entry->lstat = NULL;
11636
11637 joined_path = join_path_filename(path->narrow, name, name_len);
11638 if (!joined_path)
11639 goto error;
11640
11641 if (!path->narrow || !PyBytes_Check(path->object)) {
11642 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11643 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11644 }
11645 else {
11646 entry->name = PyBytes_FromStringAndSize(name, name_len);
11647 entry->path = PyBytes_FromString(joined_path);
11648 }
11649 PyMem_Free(joined_path);
11650 if (!entry->name || !entry->path)
11651 goto error;
11652
Victor Stinner35a97c02015-03-08 02:59:09 +010011653#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011654 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011655#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011656 entry->d_ino = d_ino;
11657
11658 return (PyObject *)entry;
11659
11660error:
11661 Py_XDECREF(entry);
11662 return NULL;
11663}
11664
11665#endif
11666
11667
11668typedef struct {
11669 PyObject_HEAD
11670 path_t path;
11671#ifdef MS_WINDOWS
11672 HANDLE handle;
11673 WIN32_FIND_DATAW file_data;
11674 int first_time;
11675#else /* POSIX */
11676 DIR *dirp;
11677#endif
11678} ScandirIterator;
11679
11680#ifdef MS_WINDOWS
11681
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011682static int
11683ScandirIterator_is_closed(ScandirIterator *iterator)
11684{
11685 return iterator->handle == INVALID_HANDLE_VALUE;
11686}
11687
Victor Stinner6036e442015-03-08 01:58:04 +010011688static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011689ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011690{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011691 HANDLE handle = iterator->handle;
11692
11693 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011694 return;
11695
Victor Stinner6036e442015-03-08 01:58:04 +010011696 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011697 Py_BEGIN_ALLOW_THREADS
11698 FindClose(handle);
11699 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011700}
11701
11702static PyObject *
11703ScandirIterator_iternext(ScandirIterator *iterator)
11704{
11705 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11706 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011707 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011708
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011709 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011710 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011711 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011712
11713 while (1) {
11714 if (!iterator->first_time) {
11715 Py_BEGIN_ALLOW_THREADS
11716 success = FindNextFileW(iterator->handle, file_data);
11717 Py_END_ALLOW_THREADS
11718 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011719 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011720 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011721 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011722 break;
11723 }
11724 }
11725 iterator->first_time = 0;
11726
11727 /* Skip over . and .. */
11728 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011729 wcscmp(file_data->cFileName, L"..") != 0) {
11730 entry = DirEntry_from_find_data(&iterator->path, file_data);
11731 if (!entry)
11732 break;
11733 return entry;
11734 }
Victor Stinner6036e442015-03-08 01:58:04 +010011735
11736 /* Loop till we get a non-dot directory or finish iterating */
11737 }
11738
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011739 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011740 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011741 return NULL;
11742}
11743
11744#else /* POSIX */
11745
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011746static int
11747ScandirIterator_is_closed(ScandirIterator *iterator)
11748{
11749 return !iterator->dirp;
11750}
11751
Victor Stinner6036e442015-03-08 01:58:04 +010011752static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011753ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011754{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011755 DIR *dirp = iterator->dirp;
11756
11757 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011758 return;
11759
Victor Stinner6036e442015-03-08 01:58:04 +010011760 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011761 Py_BEGIN_ALLOW_THREADS
11762 closedir(dirp);
11763 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011764 return;
11765}
11766
11767static PyObject *
11768ScandirIterator_iternext(ScandirIterator *iterator)
11769{
11770 struct dirent *direntp;
11771 Py_ssize_t name_len;
11772 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011773 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011774
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011775 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011776 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011777 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011778
11779 while (1) {
11780 errno = 0;
11781 Py_BEGIN_ALLOW_THREADS
11782 direntp = readdir(iterator->dirp);
11783 Py_END_ALLOW_THREADS
11784
11785 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011786 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011787 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011788 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011789 break;
11790 }
11791
11792 /* Skip over . and .. */
11793 name_len = NAMLEN(direntp);
11794 is_dot = direntp->d_name[0] == '.' &&
11795 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11796 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011797 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011798 name_len, direntp->d_ino
11799#ifdef HAVE_DIRENT_D_TYPE
11800 , direntp->d_type
11801#endif
11802 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011803 if (!entry)
11804 break;
11805 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011806 }
11807
11808 /* Loop till we get a non-dot directory or finish iterating */
11809 }
11810
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011811 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011812 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011813 return NULL;
11814}
11815
11816#endif
11817
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011818static PyObject *
11819ScandirIterator_close(ScandirIterator *self, PyObject *args)
11820{
11821 ScandirIterator_closedir(self);
11822 Py_RETURN_NONE;
11823}
11824
11825static PyObject *
11826ScandirIterator_enter(PyObject *self, PyObject *args)
11827{
11828 Py_INCREF(self);
11829 return self;
11830}
11831
11832static PyObject *
11833ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11834{
11835 ScandirIterator_closedir(self);
11836 Py_RETURN_NONE;
11837}
11838
Victor Stinner6036e442015-03-08 01:58:04 +010011839static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011840ScandirIterator_finalize(ScandirIterator *iterator)
11841{
11842 PyObject *error_type, *error_value, *error_traceback;
11843
11844 /* Save the current exception, if any. */
11845 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11846
11847 if (!ScandirIterator_is_closed(iterator)) {
11848 ScandirIterator_closedir(iterator);
11849
11850 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11851 "unclosed scandir iterator %R", iterator)) {
11852 /* Spurious errors can appear at shutdown */
11853 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11854 PyErr_WriteUnraisable((PyObject *) iterator);
11855 }
11856 }
11857 }
11858
Victor Stinner7bfa4092016-03-23 00:43:54 +010011859 path_cleanup(&iterator->path);
11860
11861 /* Restore the saved exception. */
11862 PyErr_Restore(error_type, error_value, error_traceback);
11863}
11864
11865static void
Victor Stinner6036e442015-03-08 01:58:04 +010011866ScandirIterator_dealloc(ScandirIterator *iterator)
11867{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011868 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11869 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011870
Victor Stinner6036e442015-03-08 01:58:04 +010011871 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11872}
11873
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011874static PyMethodDef ScandirIterator_methods[] = {
11875 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11876 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11877 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11878 {NULL}
11879};
11880
Benjamin Peterson5646de42015-04-12 17:56:34 -040011881static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011882 PyVarObject_HEAD_INIT(NULL, 0)
11883 MODNAME ".ScandirIterator", /* tp_name */
11884 sizeof(ScandirIterator), /* tp_basicsize */
11885 0, /* tp_itemsize */
11886 /* methods */
11887 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11888 0, /* tp_print */
11889 0, /* tp_getattr */
11890 0, /* tp_setattr */
11891 0, /* tp_compare */
11892 0, /* tp_repr */
11893 0, /* tp_as_number */
11894 0, /* tp_as_sequence */
11895 0, /* tp_as_mapping */
11896 0, /* tp_hash */
11897 0, /* tp_call */
11898 0, /* tp_str */
11899 0, /* tp_getattro */
11900 0, /* tp_setattro */
11901 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011902 Py_TPFLAGS_DEFAULT
11903 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011904 0, /* tp_doc */
11905 0, /* tp_traverse */
11906 0, /* tp_clear */
11907 0, /* tp_richcompare */
11908 0, /* tp_weaklistoffset */
11909 PyObject_SelfIter, /* tp_iter */
11910 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011911 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011912 0, /* tp_members */
11913 0, /* tp_getset */
11914 0, /* tp_base */
11915 0, /* tp_dict */
11916 0, /* tp_descr_get */
11917 0, /* tp_descr_set */
11918 0, /* tp_dictoffset */
11919 0, /* tp_init */
11920 0, /* tp_alloc */
11921 0, /* tp_new */
11922 0, /* tp_free */
11923 0, /* tp_is_gc */
11924 0, /* tp_bases */
11925 0, /* tp_mro */
11926 0, /* tp_cache */
11927 0, /* tp_subclasses */
11928 0, /* tp_weaklist */
11929 0, /* tp_del */
11930 0, /* tp_version_tag */
11931 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011932};
11933
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011934/*[clinic input]
11935os.scandir
11936
11937 path : path_t(nullable=True) = None
11938
11939Return an iterator of DirEntry objects for given path.
11940
11941path can be specified as either str, bytes or path-like object. If path
11942is bytes, the names of yielded DirEntry objects will also be bytes; in
11943all other circumstances they will be str.
11944
11945If path is None, uses the path='.'.
11946[clinic start generated code]*/
11947
Victor Stinner6036e442015-03-08 01:58:04 +010011948static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011949os_scandir_impl(PyObject *module, path_t *path)
11950/*[clinic end generated code: output=6eb2668b675ca89e input=e62b08b3cd41f604]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011951{
11952 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010011953#ifdef MS_WINDOWS
11954 wchar_t *path_strW;
11955#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011956 const char *path_str;
Victor Stinner6036e442015-03-08 01:58:04 +010011957#endif
11958
11959 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11960 if (!iterator)
11961 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011962
11963#ifdef MS_WINDOWS
11964 iterator->handle = INVALID_HANDLE_VALUE;
11965#else
11966 iterator->dirp = NULL;
11967#endif
11968
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011969 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020011970 /* Move the ownership to iterator->path */
11971 path->object = NULL;
11972 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011973
11974#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011975 iterator->first_time = 1;
11976
11977 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11978 if (!path_strW)
11979 goto error;
11980
11981 Py_BEGIN_ALLOW_THREADS
11982 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11983 Py_END_ALLOW_THREADS
11984
11985 PyMem_Free(path_strW);
11986
11987 if (iterator->handle == INVALID_HANDLE_VALUE) {
11988 path_error(&iterator->path);
11989 goto error;
11990 }
11991#else /* POSIX */
11992 if (iterator->path.narrow)
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011993 path_str = iterator->path.narrow;
Victor Stinner6036e442015-03-08 01:58:04 +010011994 else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011995 path_str = ".";
Victor Stinner6036e442015-03-08 01:58:04 +010011996
11997 errno = 0;
11998 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011999 iterator->dirp = opendir(path_str);
Victor Stinner6036e442015-03-08 01:58:04 +010012000 Py_END_ALLOW_THREADS
12001
12002 if (!iterator->dirp) {
12003 path_error(&iterator->path);
12004 goto error;
12005 }
12006#endif
12007
12008 return (PyObject *)iterator;
12009
12010error:
12011 Py_DECREF(iterator);
12012 return NULL;
12013}
12014
Ethan Furman410ef8e2016-06-04 12:06:26 -070012015/*
12016 Return the file system path representation of the object.
12017
12018 If the object is str or bytes, then allow it to pass through with
12019 an incremented refcount. If the object defines __fspath__(), then
12020 return the result of that method. All other types raise a TypeError.
12021*/
12022PyObject *
12023PyOS_FSPath(PyObject *path)
12024{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012025 /* For error message reasons, this function is manually inlined in
12026 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012027 _Py_IDENTIFIER(__fspath__);
12028 PyObject *func = NULL;
12029 PyObject *path_repr = NULL;
12030
12031 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12032 Py_INCREF(path);
12033 return path;
12034 }
12035
12036 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12037 if (NULL == func) {
12038 return PyErr_Format(PyExc_TypeError,
12039 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012040 "not %.200s",
12041 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012042 }
12043
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012044 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012045 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012046 if (NULL == path_repr) {
12047 return NULL;
12048 }
12049
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012050 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12051 PyErr_Format(PyExc_TypeError,
12052 "expected %.200s.__fspath__() to return str or bytes, "
12053 "not %.200s", Py_TYPE(path)->tp_name,
12054 Py_TYPE(path_repr)->tp_name);
12055 Py_DECREF(path_repr);
12056 return NULL;
12057 }
12058
Ethan Furman410ef8e2016-06-04 12:06:26 -070012059 return path_repr;
12060}
12061
12062/*[clinic input]
12063os.fspath
12064
12065 path: object
12066
12067Return the file system path representation of the object.
12068
Brett Cannonb4f43e92016-06-09 14:32:08 -070012069If the object is str or bytes, then allow it to pass through as-is. If the
12070object defines __fspath__(), then return the result of that method. All other
12071types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012072[clinic start generated code]*/
12073
12074static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012075os_fspath_impl(PyObject *module, PyObject *path)
12076/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012077{
12078 return PyOS_FSPath(path);
12079}
Victor Stinner6036e442015-03-08 01:58:04 +010012080
Victor Stinner9b1f4742016-09-06 16:18:52 -070012081#ifdef HAVE_GETRANDOM_SYSCALL
12082/*[clinic input]
12083os.getrandom
12084
12085 size: Py_ssize_t
12086 flags: int=0
12087
12088Obtain a series of random bytes.
12089[clinic start generated code]*/
12090
12091static PyObject *
12092os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12093/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12094{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012095 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012096 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012097
12098 if (size < 0) {
12099 errno = EINVAL;
12100 return posix_error();
12101 }
12102
Victor Stinnerec2319c2016-09-20 23:00:59 +020012103 bytes = PyBytes_FromStringAndSize(NULL, size);
12104 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012105 PyErr_NoMemory();
12106 return NULL;
12107 }
12108
12109 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012110 n = syscall(SYS_getrandom,
12111 PyBytes_AS_STRING(bytes),
12112 PyBytes_GET_SIZE(bytes),
12113 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012114 if (n < 0 && errno == EINTR) {
12115 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012116 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012117 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012118
12119 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012120 continue;
12121 }
12122 break;
12123 }
12124
12125 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012126 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012127 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012128 }
12129
Victor Stinnerec2319c2016-09-20 23:00:59 +020012130 if (n != size) {
12131 _PyBytes_Resize(&bytes, n);
12132 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012133
12134 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012135
12136error:
12137 Py_DECREF(bytes);
12138 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012139}
12140#endif /* HAVE_GETRANDOM_SYSCALL */
12141
Larry Hastings31826802013-10-19 00:09:25 -070012142
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012143static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012144
12145 OS_STAT_METHODDEF
12146 OS_ACCESS_METHODDEF
12147 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012148 OS_CHDIR_METHODDEF
12149 OS_CHFLAGS_METHODDEF
12150 OS_CHMOD_METHODDEF
12151 OS_FCHMOD_METHODDEF
12152 OS_LCHMOD_METHODDEF
12153 OS_CHOWN_METHODDEF
12154 OS_FCHOWN_METHODDEF
12155 OS_LCHOWN_METHODDEF
12156 OS_LCHFLAGS_METHODDEF
12157 OS_CHROOT_METHODDEF
12158 OS_CTERMID_METHODDEF
12159 OS_GETCWD_METHODDEF
12160 OS_GETCWDB_METHODDEF
12161 OS_LINK_METHODDEF
12162 OS_LISTDIR_METHODDEF
12163 OS_LSTAT_METHODDEF
12164 OS_MKDIR_METHODDEF
12165 OS_NICE_METHODDEF
12166 OS_GETPRIORITY_METHODDEF
12167 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012168#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012169 {"readlink", (PyCFunction)posix_readlink,
12170 METH_VARARGS | METH_KEYWORDS,
12171 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012172#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012173#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012174 {"readlink", (PyCFunction)win_readlink,
12175 METH_VARARGS | METH_KEYWORDS,
12176 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012177#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012178 OS_RENAME_METHODDEF
12179 OS_REPLACE_METHODDEF
12180 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012181 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012182 OS_SYMLINK_METHODDEF
12183 OS_SYSTEM_METHODDEF
12184 OS_UMASK_METHODDEF
12185 OS_UNAME_METHODDEF
12186 OS_UNLINK_METHODDEF
12187 OS_REMOVE_METHODDEF
12188 OS_UTIME_METHODDEF
12189 OS_TIMES_METHODDEF
12190 OS__EXIT_METHODDEF
12191 OS_EXECV_METHODDEF
12192 OS_EXECVE_METHODDEF
12193 OS_SPAWNV_METHODDEF
12194 OS_SPAWNVE_METHODDEF
12195 OS_FORK1_METHODDEF
12196 OS_FORK_METHODDEF
12197 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12198 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12199 OS_SCHED_GETPARAM_METHODDEF
12200 OS_SCHED_GETSCHEDULER_METHODDEF
12201 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12202 OS_SCHED_SETPARAM_METHODDEF
12203 OS_SCHED_SETSCHEDULER_METHODDEF
12204 OS_SCHED_YIELD_METHODDEF
12205 OS_SCHED_SETAFFINITY_METHODDEF
12206 OS_SCHED_GETAFFINITY_METHODDEF
12207 OS_OPENPTY_METHODDEF
12208 OS_FORKPTY_METHODDEF
12209 OS_GETEGID_METHODDEF
12210 OS_GETEUID_METHODDEF
12211 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012212#ifdef HAVE_GETGROUPLIST
12213 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12214#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012215 OS_GETGROUPS_METHODDEF
12216 OS_GETPID_METHODDEF
12217 OS_GETPGRP_METHODDEF
12218 OS_GETPPID_METHODDEF
12219 OS_GETUID_METHODDEF
12220 OS_GETLOGIN_METHODDEF
12221 OS_KILL_METHODDEF
12222 OS_KILLPG_METHODDEF
12223 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012224#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012225 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012226#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012227 OS_SETUID_METHODDEF
12228 OS_SETEUID_METHODDEF
12229 OS_SETREUID_METHODDEF
12230 OS_SETGID_METHODDEF
12231 OS_SETEGID_METHODDEF
12232 OS_SETREGID_METHODDEF
12233 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012234#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012235 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012236#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012237 OS_GETPGID_METHODDEF
12238 OS_SETPGRP_METHODDEF
12239 OS_WAIT_METHODDEF
12240 OS_WAIT3_METHODDEF
12241 OS_WAIT4_METHODDEF
12242 OS_WAITID_METHODDEF
12243 OS_WAITPID_METHODDEF
12244 OS_GETSID_METHODDEF
12245 OS_SETSID_METHODDEF
12246 OS_SETPGID_METHODDEF
12247 OS_TCGETPGRP_METHODDEF
12248 OS_TCSETPGRP_METHODDEF
12249 OS_OPEN_METHODDEF
12250 OS_CLOSE_METHODDEF
12251 OS_CLOSERANGE_METHODDEF
12252 OS_DEVICE_ENCODING_METHODDEF
12253 OS_DUP_METHODDEF
12254 OS_DUP2_METHODDEF
12255 OS_LOCKF_METHODDEF
12256 OS_LSEEK_METHODDEF
12257 OS_READ_METHODDEF
12258 OS_READV_METHODDEF
12259 OS_PREAD_METHODDEF
12260 OS_WRITE_METHODDEF
12261 OS_WRITEV_METHODDEF
12262 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012263#ifdef HAVE_SENDFILE
12264 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12265 posix_sendfile__doc__},
12266#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012267 OS_FSTAT_METHODDEF
12268 OS_ISATTY_METHODDEF
12269 OS_PIPE_METHODDEF
12270 OS_PIPE2_METHODDEF
12271 OS_MKFIFO_METHODDEF
12272 OS_MKNOD_METHODDEF
12273 OS_MAJOR_METHODDEF
12274 OS_MINOR_METHODDEF
12275 OS_MAKEDEV_METHODDEF
12276 OS_FTRUNCATE_METHODDEF
12277 OS_TRUNCATE_METHODDEF
12278 OS_POSIX_FALLOCATE_METHODDEF
12279 OS_POSIX_FADVISE_METHODDEF
12280 OS_PUTENV_METHODDEF
12281 OS_UNSETENV_METHODDEF
12282 OS_STRERROR_METHODDEF
12283 OS_FCHDIR_METHODDEF
12284 OS_FSYNC_METHODDEF
12285 OS_SYNC_METHODDEF
12286 OS_FDATASYNC_METHODDEF
12287 OS_WCOREDUMP_METHODDEF
12288 OS_WIFCONTINUED_METHODDEF
12289 OS_WIFSTOPPED_METHODDEF
12290 OS_WIFSIGNALED_METHODDEF
12291 OS_WIFEXITED_METHODDEF
12292 OS_WEXITSTATUS_METHODDEF
12293 OS_WTERMSIG_METHODDEF
12294 OS_WSTOPSIG_METHODDEF
12295 OS_FSTATVFS_METHODDEF
12296 OS_STATVFS_METHODDEF
12297 OS_CONFSTR_METHODDEF
12298 OS_SYSCONF_METHODDEF
12299 OS_FPATHCONF_METHODDEF
12300 OS_PATHCONF_METHODDEF
12301 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012302 OS__GETFULLPATHNAME_METHODDEF
12303 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012304 OS__GETDISKUSAGE_METHODDEF
12305 OS__GETFINALPATHNAME_METHODDEF
12306 OS__GETVOLUMEPATHNAME_METHODDEF
12307 OS_GETLOADAVG_METHODDEF
12308 OS_URANDOM_METHODDEF
12309 OS_SETRESUID_METHODDEF
12310 OS_SETRESGID_METHODDEF
12311 OS_GETRESUID_METHODDEF
12312 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012313
Larry Hastings2f936352014-08-05 14:04:04 +100012314 OS_GETXATTR_METHODDEF
12315 OS_SETXATTR_METHODDEF
12316 OS_REMOVEXATTR_METHODDEF
12317 OS_LISTXATTR_METHODDEF
12318
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012319#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12320 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12321#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012322 OS_CPU_COUNT_METHODDEF
12323 OS_GET_INHERITABLE_METHODDEF
12324 OS_SET_INHERITABLE_METHODDEF
12325 OS_GET_HANDLE_INHERITABLE_METHODDEF
12326 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012327#ifndef MS_WINDOWS
12328 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12329 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12330#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012331 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012332 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012333 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012334 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012335};
12336
12337
Brian Curtin52173d42010-12-02 18:29:18 +000012338#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012339static int
Brian Curtin52173d42010-12-02 18:29:18 +000012340enable_symlink()
12341{
12342 HANDLE tok;
12343 TOKEN_PRIVILEGES tok_priv;
12344 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012345
12346 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012347 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012348
12349 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012350 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012351
12352 tok_priv.PrivilegeCount = 1;
12353 tok_priv.Privileges[0].Luid = luid;
12354 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12355
12356 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12357 sizeof(TOKEN_PRIVILEGES),
12358 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012359 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012360
Brian Curtin3b4499c2010-12-28 14:31:47 +000012361 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12362 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012363}
12364#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12365
Barry Warsaw4a342091996-12-19 23:50:02 +000012366static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012367all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012368{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012369#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012370 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012371#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012372#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012373 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012374#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012375#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012376 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012377#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012378#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012379 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012380#endif
Fred Drakec9680921999-12-13 16:37:25 +000012381#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012383#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012384#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012385 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012386#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012387#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012388 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012389#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012390#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012391 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012392#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012393#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012394 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012395#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012396#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012397 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012398#endif
12399#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012401#endif
12402#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012404#endif
12405#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012407#endif
12408#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012410#endif
12411#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012413#endif
12414#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012416#endif
12417#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012419#endif
12420#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012422#endif
12423#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012424 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012425#endif
12426#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012428#endif
12429#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012430 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#endif
12432#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012433 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012434#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012435#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012437#endif
12438#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012439 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012440#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012441#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012442 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012443#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012444#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012445 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012446#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012447#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012448#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012449 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012450#endif
12451#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012452 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012453#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012454#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012455#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012456 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012457#endif
12458#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012460#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012461#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012462 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012463#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012464#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012466#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012467#ifdef O_TMPFILE
12468 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12469#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012470#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012472#endif
12473#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012474 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012475#endif
12476#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012477 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012478#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012479#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012480 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012481#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012482#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012484#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012485
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012486
Jesus Cea94363612012-06-22 18:32:07 +020012487#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012489#endif
12490#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012492#endif
12493
Tim Peters5aa91602002-01-30 05:46:57 +000012494/* MS Windows */
12495#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012496 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012498#endif
12499#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012500 /* Optimize for short life (keep in memory). */
12501 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012502 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012503#endif
12504#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012505 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012507#endif
12508#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012509 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012510 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012511#endif
12512#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012513 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012514 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012515#endif
12516
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012517/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012518#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012519 /* Send a SIGIO signal whenever input or output
12520 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012522#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012523#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012524 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012525 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012526#endif
12527#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012528 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012530#endif
12531#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012532 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012533 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012534#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012535#ifdef O_NOLINKS
12536 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012537 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012538#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012539#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012540 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012541 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012542#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012543
Victor Stinner8c62be82010-05-06 00:08:46 +000012544 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012545#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012546 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012547#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012548#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012549 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012550#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012551#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012552 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012553#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012554#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012556#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012557#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012559#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012560#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012561 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012562#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012563#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012564 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012565#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012566#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012568#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012569#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012571#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012572#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012573 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012574#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012575#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012576 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012577#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012597 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012598#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012600#endif /* ST_RDONLY */
12601#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012603#endif /* ST_NOSUID */
12604
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012605 /* GNU extensions */
12606#ifdef ST_NODEV
12607 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12608#endif /* ST_NODEV */
12609#ifdef ST_NOEXEC
12610 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12611#endif /* ST_NOEXEC */
12612#ifdef ST_SYNCHRONOUS
12613 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12614#endif /* ST_SYNCHRONOUS */
12615#ifdef ST_MANDLOCK
12616 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12617#endif /* ST_MANDLOCK */
12618#ifdef ST_WRITE
12619 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12620#endif /* ST_WRITE */
12621#ifdef ST_APPEND
12622 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12623#endif /* ST_APPEND */
12624#ifdef ST_NOATIME
12625 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12626#endif /* ST_NOATIME */
12627#ifdef ST_NODIRATIME
12628 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12629#endif /* ST_NODIRATIME */
12630#ifdef ST_RELATIME
12631 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12632#endif /* ST_RELATIME */
12633
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012634 /* FreeBSD sendfile() constants */
12635#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012636 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012637#endif
12638#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012639 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012640#endif
12641#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012643#endif
12644
Ross Lagerwall7807c352011-03-17 20:20:30 +020012645 /* constants for posix_fadvise */
12646#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012648#endif
12649#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012651#endif
12652#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012654#endif
12655#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012657#endif
12658#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012660#endif
12661#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012663#endif
12664
12665 /* constants for waitid */
12666#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12668 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12669 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012670#endif
12671#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012673#endif
12674#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012676#endif
12677#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012679#endif
12680#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012682#endif
12683#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012685#endif
12686#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012687 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012688#endif
12689#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012691#endif
12692
12693 /* constants for lockf */
12694#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012699#endif
12700#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012702#endif
12703#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012705#endif
12706
Guido van Rossum246bc171999-02-01 23:54:31 +000012707#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12709 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12710 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12711 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12712 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012713#endif
12714
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012715#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012716#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012718#endif
12719#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012721#endif
12722#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012724#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012725#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012727#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012728#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012730#endif
12731#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012733#endif
12734#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012736#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012737#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012739#endif
12740#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012742#endif
12743#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012745#endif
12746#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012748#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012749#endif
12750
Benjamin Peterson9428d532011-09-14 11:45:52 -040012751#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12753 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12754 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012755#endif
12756
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012757#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012759#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012760#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012762#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012763#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012764 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012765#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012766#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012768#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012769#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012771#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012772#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012774#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012775#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012777#endif
12778
Victor Stinner9b1f4742016-09-06 16:18:52 -070012779#ifdef HAVE_GETRANDOM_SYSCALL
12780 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12781 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12782#endif
12783
Victor Stinner8c62be82010-05-06 00:08:46 +000012784 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012785}
12786
12787
Martin v. Löwis1a214512008-06-11 05:26:20 +000012788static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012789 PyModuleDef_HEAD_INIT,
12790 MODNAME,
12791 posix__doc__,
12792 -1,
12793 posix_methods,
12794 NULL,
12795 NULL,
12796 NULL,
12797 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012798};
12799
12800
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012801static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012802
12803#ifdef HAVE_FACCESSAT
12804 "HAVE_FACCESSAT",
12805#endif
12806
12807#ifdef HAVE_FCHDIR
12808 "HAVE_FCHDIR",
12809#endif
12810
12811#ifdef HAVE_FCHMOD
12812 "HAVE_FCHMOD",
12813#endif
12814
12815#ifdef HAVE_FCHMODAT
12816 "HAVE_FCHMODAT",
12817#endif
12818
12819#ifdef HAVE_FCHOWN
12820 "HAVE_FCHOWN",
12821#endif
12822
Larry Hastings00964ed2013-08-12 13:49:30 -040012823#ifdef HAVE_FCHOWNAT
12824 "HAVE_FCHOWNAT",
12825#endif
12826
Larry Hastings9cf065c2012-06-22 16:30:09 -070012827#ifdef HAVE_FEXECVE
12828 "HAVE_FEXECVE",
12829#endif
12830
12831#ifdef HAVE_FDOPENDIR
12832 "HAVE_FDOPENDIR",
12833#endif
12834
Georg Brandl306336b2012-06-24 12:55:33 +020012835#ifdef HAVE_FPATHCONF
12836 "HAVE_FPATHCONF",
12837#endif
12838
Larry Hastings9cf065c2012-06-22 16:30:09 -070012839#ifdef HAVE_FSTATAT
12840 "HAVE_FSTATAT",
12841#endif
12842
12843#ifdef HAVE_FSTATVFS
12844 "HAVE_FSTATVFS",
12845#endif
12846
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012847#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012848 "HAVE_FTRUNCATE",
12849#endif
12850
Larry Hastings9cf065c2012-06-22 16:30:09 -070012851#ifdef HAVE_FUTIMENS
12852 "HAVE_FUTIMENS",
12853#endif
12854
12855#ifdef HAVE_FUTIMES
12856 "HAVE_FUTIMES",
12857#endif
12858
12859#ifdef HAVE_FUTIMESAT
12860 "HAVE_FUTIMESAT",
12861#endif
12862
12863#ifdef HAVE_LINKAT
12864 "HAVE_LINKAT",
12865#endif
12866
12867#ifdef HAVE_LCHFLAGS
12868 "HAVE_LCHFLAGS",
12869#endif
12870
12871#ifdef HAVE_LCHMOD
12872 "HAVE_LCHMOD",
12873#endif
12874
12875#ifdef HAVE_LCHOWN
12876 "HAVE_LCHOWN",
12877#endif
12878
12879#ifdef HAVE_LSTAT
12880 "HAVE_LSTAT",
12881#endif
12882
12883#ifdef HAVE_LUTIMES
12884 "HAVE_LUTIMES",
12885#endif
12886
12887#ifdef HAVE_MKDIRAT
12888 "HAVE_MKDIRAT",
12889#endif
12890
12891#ifdef HAVE_MKFIFOAT
12892 "HAVE_MKFIFOAT",
12893#endif
12894
12895#ifdef HAVE_MKNODAT
12896 "HAVE_MKNODAT",
12897#endif
12898
12899#ifdef HAVE_OPENAT
12900 "HAVE_OPENAT",
12901#endif
12902
12903#ifdef HAVE_READLINKAT
12904 "HAVE_READLINKAT",
12905#endif
12906
12907#ifdef HAVE_RENAMEAT
12908 "HAVE_RENAMEAT",
12909#endif
12910
12911#ifdef HAVE_SYMLINKAT
12912 "HAVE_SYMLINKAT",
12913#endif
12914
12915#ifdef HAVE_UNLINKAT
12916 "HAVE_UNLINKAT",
12917#endif
12918
12919#ifdef HAVE_UTIMENSAT
12920 "HAVE_UTIMENSAT",
12921#endif
12922
12923#ifdef MS_WINDOWS
12924 "MS_WINDOWS",
12925#endif
12926
12927 NULL
12928};
12929
12930
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012931PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012932INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012933{
Victor Stinner8c62be82010-05-06 00:08:46 +000012934 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012935 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012936 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012937
Brian Curtin52173d42010-12-02 18:29:18 +000012938#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012939 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012940#endif
12941
Victor Stinner8c62be82010-05-06 00:08:46 +000012942 m = PyModule_Create(&posixmodule);
12943 if (m == NULL)
12944 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012945
Victor Stinner8c62be82010-05-06 00:08:46 +000012946 /* Initialize environ dictionary */
12947 v = convertenviron();
12948 Py_XINCREF(v);
12949 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12950 return NULL;
12951 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012952
Victor Stinner8c62be82010-05-06 00:08:46 +000012953 if (all_ins(m))
12954 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012955
Victor Stinner8c62be82010-05-06 00:08:46 +000012956 if (setup_confname_tables(m))
12957 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012958
Victor Stinner8c62be82010-05-06 00:08:46 +000012959 Py_INCREF(PyExc_OSError);
12960 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012961
Guido van Rossumb3d39562000-01-31 18:41:26 +000012962#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012963 if (posix_putenv_garbage == NULL)
12964 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012965#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012966
Victor Stinner8c62be82010-05-06 00:08:46 +000012967 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012968#if defined(HAVE_WAITID) && !defined(__APPLE__)
12969 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012970 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12971 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012972#endif
12973
Christian Heimes25827622013-10-12 01:27:08 +020012974 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12976 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12977 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012978 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12979 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012980 structseq_new = StatResultType.tp_new;
12981 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012982
Christian Heimes25827622013-10-12 01:27:08 +020012983 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012984 if (PyStructSequence_InitType2(&StatVFSResultType,
12985 &statvfs_result_desc) < 0)
12986 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012987#ifdef NEED_TICKS_PER_SECOND
12988# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012990# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012991 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012992# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012993 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012994# endif
12995#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012996
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012997#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012998 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012999 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13000 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013001 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013002#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013003
13004 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013005 if (PyStructSequence_InitType2(&TerminalSizeType,
13006 &TerminalSize_desc) < 0)
13007 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013008
13009 /* initialize scandir types */
13010 if (PyType_Ready(&ScandirIteratorType) < 0)
13011 return NULL;
13012 if (PyType_Ready(&DirEntryType) < 0)
13013 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013014 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013015#if defined(HAVE_WAITID) && !defined(__APPLE__)
13016 Py_INCREF((PyObject*) &WaitidResultType);
13017 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13018#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013019 Py_INCREF((PyObject*) &StatResultType);
13020 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13021 Py_INCREF((PyObject*) &StatVFSResultType);
13022 PyModule_AddObject(m, "statvfs_result",
13023 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013024
13025#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013026 Py_INCREF(&SchedParamType);
13027 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013028#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013029
Larry Hastings605a62d2012-06-24 04:33:36 -070013030 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013031 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13032 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013033 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13034
13035 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013036 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13037 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013038 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13039
Thomas Wouters477c8d52006-05-27 19:21:47 +000013040#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013041 /*
13042 * Step 2 of weak-linking support on Mac OS X.
13043 *
13044 * The code below removes functions that are not available on the
13045 * currently active platform.
13046 *
13047 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013048 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013049 * OSX 10.4.
13050 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013051#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013052 if (fstatvfs == NULL) {
13053 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13054 return NULL;
13055 }
13056 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013057#endif /* HAVE_FSTATVFS */
13058
13059#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013060 if (statvfs == NULL) {
13061 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13062 return NULL;
13063 }
13064 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013065#endif /* HAVE_STATVFS */
13066
13067# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013068 if (lchown == NULL) {
13069 if (PyObject_DelAttrString(m, "lchown") == -1) {
13070 return NULL;
13071 }
13072 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013073#endif /* HAVE_LCHOWN */
13074
13075
13076#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013077
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013078 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013079 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13080
Larry Hastings6fe20b32012-04-19 15:07:49 -070013081 billion = PyLong_FromLong(1000000000);
13082 if (!billion)
13083 return NULL;
13084
Larry Hastings9cf065c2012-06-22 16:30:09 -070013085 /* suppress "function not used" warnings */
13086 {
13087 int ignored;
13088 fd_specified("", -1);
13089 follow_symlinks_specified("", 1);
13090 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13091 dir_fd_converter(Py_None, &ignored);
13092 dir_fd_unavailable(Py_None, &ignored);
13093 }
13094
13095 /*
13096 * provide list of locally available functions
13097 * so os.py can populate support_* lists
13098 */
13099 list = PyList_New(0);
13100 if (!list)
13101 return NULL;
13102 for (trace = have_functions; *trace; trace++) {
13103 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13104 if (!unicode)
13105 return NULL;
13106 if (PyList_Append(list, unicode))
13107 return NULL;
13108 Py_DECREF(unicode);
13109 }
13110 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013111
13112 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013113 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013114
13115 initialized = 1;
13116
Victor Stinner8c62be82010-05-06 00:08:46 +000013117 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013118}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013119
13120#ifdef __cplusplus
13121}
13122#endif