blob: a39ea651fd923d0d4e7d18fc86ce635cbfaf21cf [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,
773 * is an non-zero integer if the path was expressed as bytes.
774 * 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
788 * The original object passed in.
789 * path.cleanup
790 * For internal use only. May point to a temporary object.
791 * (Pay no attention to the man behind the curtain.)
792 *
793 * At most one of path.wide or path.narrow will be non-NULL.
794 * If path was None and path.nullable was set,
795 * or if path was an integer and path.allow_fd was set,
796 * both path.wide and path.narrow will be NULL
797 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200798 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700799 * path_converter takes care to not write to the path_t
800 * unless it's successful. However it must reset the
801 * "cleanup" field each time it's called.
802 *
803 * Use as follows:
804 * path_t path;
805 * memset(&path, 0, sizeof(path));
806 * PyArg_ParseTuple(args, "O&", path_converter, &path);
807 * // ... use values from path ...
808 * path_cleanup(&path);
809 *
810 * (Note that if PyArg_Parse fails you don't need to call
811 * path_cleanup(). However it is safe to do so.)
812 */
813typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100814 const char *function_name;
815 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816 int nullable;
817 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300818 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700819#ifdef MS_WINDOWS
820 BOOL narrow;
821#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300822 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700823#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700824 int fd;
825 Py_ssize_t length;
826 PyObject *object;
827 PyObject *cleanup;
828} path_t;
829
Steve Dowercc16be82016-09-08 10:35:16 -0700830#ifdef MS_WINDOWS
831#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
832 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
833#else
Larry Hastings2f936352014-08-05 14:04:04 +1000834#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
835 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700836#endif
Larry Hastings31826802013-10-19 00:09:25 -0700837
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838static void
839path_cleanup(path_t *path) {
840 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200841 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700842 }
843}
844
845static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300846path_converter(PyObject *o, void *p)
847{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700848 path_t *path = (path_t *)p;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700849 PyObject *bytes, *to_cleanup = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700850 Py_ssize_t length;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700851 int is_index, is_buffer, is_bytes, is_unicode;
852 /* Default to failure, forcing explicit signaling of succcess. */
853 int ret = 0;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300854 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700855#ifdef MS_WINDOWS
856 PyObject *wo;
857 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(). */
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873 path->cleanup = NULL;
874
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300875 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700877#ifdef MS_WINDOWS
878 path->narrow = FALSE;
879#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700881#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 path->length = 0;
883 path->object = o;
884 path->fd = -1;
885 return 1;
886 }
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) {
902 goto error_exit;
903 }
904
905 o = to_cleanup = PyObject_CallFunctionObjArgs(func, NULL);
906 Py_DECREF(func);
907 if (NULL == o) {
908 goto error_exit;
909 }
910 else if (PyUnicode_Check(o)) {
911 is_unicode = 1;
912 }
913 else if (PyBytes_Check(o)) {
914 is_bytes = 1;
915 }
916 else {
917 goto error_exit;
918 }
919 }
920
921 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -0700923 wide = PyUnicode_AsWideCharString(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100924 if (!wide) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700925 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700926 }
Victor Stinner59799a82013-11-13 14:17:30 +0100927 if (length > 32767) {
928 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700929 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300931 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300932 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700933 goto exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300934 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935
936 path->wide = wide;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 path->length = length;
938 path->object = o;
939 path->fd = -1;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700940 ret = 1;
941 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300943 if (!PyUnicode_FSConverter(o, &bytes)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700944 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300945 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946#endif
947 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700948 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300949 bytes = o;
950 Py_INCREF(bytes);
951 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700952 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300953 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
954 "%s%s%s should be %s, not %.200s",
955 path->function_name ? path->function_name : "",
956 path->function_name ? ": " : "",
957 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700958 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
959 "integer or None" :
960 path->allow_fd ? "string, bytes, os.PathLike or integer" :
961 path->nullable ? "string, bytes, os.PathLike or None" :
962 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300963 Py_TYPE(o)->tp_name)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700964 goto exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300965 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300966 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 if (!bytes) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700968 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 }
970 }
Steve Dowercc16be82016-09-08 10:35:16 -0700971 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300972 if (!_fd_converter(o, &path->fd)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700973 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300974 }
975 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700976#ifdef MS_WINDOWS
977 path->narrow = FALSE;
978#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300979 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700980#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300981 path->length = 0;
982 path->object = o;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700983 ret = 1;
984 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300985 }
986 else {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 error_exit:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300988 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
989 path->function_name ? path->function_name : "",
990 path->function_name ? ": " : "",
991 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700992 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
993 "integer or None" :
994 path->allow_fd ? "string, bytes, os.PathLike or integer" :
995 path->nullable ? "string, bytes, os.PathLike or None" :
996 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300997 Py_TYPE(o)->tp_name);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700998 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700999 }
1000
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001003 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001004 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001006 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 }
1008
Steve Dowercc16be82016-09-08 10:35:16 -07001009#ifdef MS_WINDOWS
1010 wo = PyUnicode_DecodeFSDefaultAndSize(
1011 narrow,
1012 length
1013 );
1014 if (!wo) {
1015 goto exit;
1016 }
1017
1018 wide = PyUnicode_AsWideCharString(wo, &length);
1019 Py_DECREF(wo);
1020
1021 if (!wide) {
1022 goto exit;
1023 }
1024 if (length > 32767) {
1025 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
1026 goto exit;
1027 }
1028 if (wcslen(wide) != length) {
1029 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
1030 goto exit;
1031 }
1032 path->wide = wide;
1033 path->narrow = TRUE;
1034#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 path->wide = NULL;
1036 path->narrow = narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001037#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 path->length = length;
1039 path->object = o;
1040 path->fd = -1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001041 if (bytes == o) {
1042 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 ret = 1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001044 }
1045 else {
1046 path->cleanup = bytes;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001047 ret = Py_CLEANUP_SUPPORTED;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001049 exit:
1050 Py_XDECREF(to_cleanup);
1051 return ret;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052}
1053
1054static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001055argument_unavailable_error(const char *function_name, const char *argument_name)
1056{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001057 PyErr_Format(PyExc_NotImplementedError,
1058 "%s%s%s unavailable on this platform",
1059 (function_name != NULL) ? function_name : "",
1060 (function_name != NULL) ? ": ": "",
1061 argument_name);
1062}
1063
1064static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001065dir_fd_unavailable(PyObject *o, void *p)
1066{
1067 int dir_fd;
1068 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001070 if (dir_fd != DEFAULT_DIR_FD) {
1071 argument_unavailable_error(NULL, "dir_fd");
1072 return 0;
1073 }
1074 *(int *)p = dir_fd;
1075 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076}
1077
1078static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001079fd_specified(const char *function_name, int fd)
1080{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 if (fd == -1)
1082 return 0;
1083
1084 argument_unavailable_error(function_name, "fd");
1085 return 1;
1086}
1087
1088static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001089follow_symlinks_specified(const char *function_name, int follow_symlinks)
1090{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 if (follow_symlinks)
1092 return 0;
1093
1094 argument_unavailable_error(function_name, "follow_symlinks");
1095 return 1;
1096}
1097
1098static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001099path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1100{
Steve Dowercc16be82016-09-08 10:35:16 -07001101 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1102#ifndef MS_WINDOWS
1103 && !path->narrow
1104#endif
1105 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106 PyErr_Format(PyExc_ValueError,
1107 "%s: can't specify dir_fd without matching path",
1108 function_name);
1109 return 1;
1110 }
1111 return 0;
1112}
1113
1114static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001115dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1116{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001117 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1118 PyErr_Format(PyExc_ValueError,
1119 "%s: can't specify both dir_fd and fd",
1120 function_name);
1121 return 1;
1122 }
1123 return 0;
1124}
1125
1126static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001127fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1128 int follow_symlinks)
1129{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001130 if ((fd > 0) && (!follow_symlinks)) {
1131 PyErr_Format(PyExc_ValueError,
1132 "%s: cannot use fd and follow_symlinks together",
1133 function_name);
1134 return 1;
1135 }
1136 return 0;
1137}
1138
1139static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001140dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1141 int follow_symlinks)
1142{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1144 PyErr_Format(PyExc_ValueError,
1145 "%s: cannot use dir_fd and follow_symlinks together",
1146 function_name);
1147 return 1;
1148 }
1149 return 0;
1150}
1151
Larry Hastings2f936352014-08-05 14:04:04 +10001152#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001153 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001154#else
Larry Hastings2f936352014-08-05 14:04:04 +10001155 typedef off_t Py_off_t;
1156#endif
1157
1158static int
1159Py_off_t_converter(PyObject *arg, void *addr)
1160{
1161#ifdef HAVE_LARGEFILE_SUPPORT
1162 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1163#else
1164 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001165#endif
1166 if (PyErr_Occurred())
1167 return 0;
1168 return 1;
1169}
Larry Hastings2f936352014-08-05 14:04:04 +10001170
1171static PyObject *
1172PyLong_FromPy_off_t(Py_off_t offset)
1173{
1174#ifdef HAVE_LARGEFILE_SUPPORT
1175 return PyLong_FromLongLong(offset);
1176#else
1177 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001178#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001179}
1180
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001181
Steve Dowerd81431f2015-03-06 14:47:02 -08001182#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1183/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1184 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001185 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001186#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001187#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001188#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001189#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001190#define _NO_CONSOLE_FILENO (intptr_t)-2
1191
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001192/* the special case of checking dup2. The target fd must be in a sensible range */
1193static int
1194_PyVerify_fd_dup2(int fd1, int fd2)
1195{
Victor Stinner8c62be82010-05-06 00:08:46 +00001196 if (!_PyVerify_fd(fd1))
1197 return 0;
1198 if (fd2 == _NO_CONSOLE_FILENO)
1199 return 0;
1200 if ((unsigned)fd2 < _NHANDLE_)
1201 return 1;
1202 else
1203 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001204}
1205#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001206#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001207#endif
1208
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001209#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001210
1211static int
Brian Curtind25aef52011-06-13 15:16:04 -05001212win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001213{
Martin Panter70214ad2016-08-04 02:38:59 +00001214 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1215 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001216 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001217
1218 if (0 == DeviceIoControl(
1219 reparse_point_handle,
1220 FSCTL_GET_REPARSE_POINT,
1221 NULL, 0, /* in buffer */
1222 target_buffer, sizeof(target_buffer),
1223 &n_bytes_returned,
1224 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001225 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001226
1227 if (reparse_tag)
1228 *reparse_tag = rdb->ReparseTag;
1229
Brian Curtind25aef52011-06-13 15:16:04 -05001230 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001231}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001232
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001233#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001234
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001235/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001236#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001237/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001238** environ directly, we must obtain it with _NSGetEnviron(). See also
1239** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001240*/
1241#include <crt_externs.h>
1242static char **environ;
1243#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001244extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001245#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246
Barry Warsaw53699e91996-12-10 23:23:01 +00001247static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001248convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249{
Victor Stinner8c62be82010-05-06 00:08:46 +00001250 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001251#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001252 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001253#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001255#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001256
Victor Stinner8c62be82010-05-06 00:08:46 +00001257 d = PyDict_New();
1258 if (d == NULL)
1259 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001260#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001261 if (environ == NULL)
1262 environ = *_NSGetEnviron();
1263#endif
1264#ifdef MS_WINDOWS
1265 /* _wenviron must be initialized in this way if the program is started
1266 through main() instead of wmain(). */
1267 _wgetenv(L"");
1268 if (_wenviron == NULL)
1269 return d;
1270 /* This part ignores errors */
1271 for (e = _wenviron; *e != NULL; e++) {
1272 PyObject *k;
1273 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001274 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 if (p == NULL)
1276 continue;
1277 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1278 if (k == NULL) {
1279 PyErr_Clear();
1280 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001281 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1283 if (v == NULL) {
1284 PyErr_Clear();
1285 Py_DECREF(k);
1286 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001287 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001288 if (PyDict_GetItem(d, k) == NULL) {
1289 if (PyDict_SetItem(d, k, v) != 0)
1290 PyErr_Clear();
1291 }
1292 Py_DECREF(k);
1293 Py_DECREF(v);
1294 }
1295#else
1296 if (environ == NULL)
1297 return d;
1298 /* This part ignores errors */
1299 for (e = environ; *e != NULL; e++) {
1300 PyObject *k;
1301 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001302 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001303 if (p == NULL)
1304 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001305 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001306 if (k == NULL) {
1307 PyErr_Clear();
1308 continue;
1309 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001310 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 if (v == NULL) {
1312 PyErr_Clear();
1313 Py_DECREF(k);
1314 continue;
1315 }
1316 if (PyDict_GetItem(d, k) == NULL) {
1317 if (PyDict_SetItem(d, k, v) != 0)
1318 PyErr_Clear();
1319 }
1320 Py_DECREF(k);
1321 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001322 }
1323#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001325}
1326
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327/* Set a POSIX-specific error from errno, and return NULL */
1328
Barry Warsawd58d7641998-07-23 16:14:40 +00001329static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001330posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001331{
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333}
Mark Hammondef8b6542001-05-13 08:04:26 +00001334
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001335#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001336static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001337win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001338{
Victor Stinner8c62be82010-05-06 00:08:46 +00001339 /* XXX We should pass the function name along in the future.
1340 (winreg.c also wants to pass the function name.)
1341 This would however require an additional param to the
1342 Windows error object, which is non-trivial.
1343 */
1344 errno = GetLastError();
1345 if (filename)
1346 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1347 else
1348 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001349}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001350
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001351static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001352win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001353{
1354 /* XXX - see win32_error for comments on 'function' */
1355 errno = GetLastError();
1356 if (filename)
1357 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001358 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001359 errno,
1360 filename);
1361 else
1362 return PyErr_SetFromWindowsErr(errno);
1363}
1364
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001365#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001366
Larry Hastings9cf065c2012-06-22 16:30:09 -07001367static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001368path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001369{
1370#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001371 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1372 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001373#else
Victor Stinner292c8352012-10-30 02:17:38 +01001374 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001375#endif
1376}
1377
Larry Hastings31826802013-10-19 00:09:25 -07001378
Larry Hastingsb0827312014-02-09 22:05:19 -08001379static PyObject *
1380path_error2(path_t *path, path_t *path2)
1381{
1382#ifdef MS_WINDOWS
1383 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1384 0, path->object, path2->object);
1385#else
1386 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1387 path->object, path2->object);
1388#endif
1389}
1390
1391
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392/* POSIX generic methods */
1393
Larry Hastings2f936352014-08-05 14:04:04 +10001394static int
1395fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001396{
Victor Stinner8c62be82010-05-06 00:08:46 +00001397 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001398 int *pointer = (int *)p;
1399 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001401 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001402 *pointer = fd;
1403 return 1;
1404}
1405
1406static PyObject *
1407posix_fildes_fd(int fd, int (*func)(int))
1408{
1409 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001410 int async_err = 0;
1411
Steve Dower8fc89802015-04-12 00:26:27 -04001412 if (!_PyVerify_fd(fd))
1413 return posix_error();
1414
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001415 do {
1416 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001417 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001418 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001419 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001420 Py_END_ALLOW_THREADS
1421 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1422 if (res != 0)
1423 return (!async_err) ? posix_error() : NULL;
1424 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001425}
Guido van Rossum21142a01999-01-08 21:05:37 +00001426
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001428#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001429/* This is a reimplementation of the C library's chdir function,
1430 but one that produces Win32 errors instead of DOS error codes.
1431 chdir is essentially a wrapper around SetCurrentDirectory; however,
1432 it also needs to set "magic" environment variables indicating
1433 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001434static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435win32_wchdir(LPCWSTR path)
1436{
Victor Stinnered537822015-12-13 21:40:26 +01001437 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 int result;
1439 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 if(!SetCurrentDirectoryW(path))
1442 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001443 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 if (!result)
1445 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001446 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001447 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 if (!new_path) {
1449 SetLastError(ERROR_OUTOFMEMORY);
1450 return FALSE;
1451 }
1452 result = GetCurrentDirectoryW(result, new_path);
1453 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001454 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 return FALSE;
1456 }
1457 }
1458 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1459 wcsncmp(new_path, L"//", 2) == 0)
1460 /* UNC path, nothing to do. */
1461 return TRUE;
1462 env[1] = new_path[0];
1463 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001464 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001465 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467}
1468#endif
1469
Martin v. Löwis14694662006-02-03 12:54:16 +00001470#ifdef MS_WINDOWS
1471/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1472 - time stamps are restricted to second resolution
1473 - file modification times suffer from forth-and-back conversions between
1474 UTC and local time
1475 Therefore, we implement our own stat, based on the Win32 API directly.
1476*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001477#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001478#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001479
Victor Stinner6036e442015-03-08 01:58:04 +01001480static void
Steve Dowercc16be82016-09-08 10:35:16 -07001481find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1482 BY_HANDLE_FILE_INFORMATION *info,
1483 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001484{
1485 memset(info, 0, sizeof(*info));
1486 info->dwFileAttributes = pFileData->dwFileAttributes;
1487 info->ftCreationTime = pFileData->ftCreationTime;
1488 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1489 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1490 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1491 info->nFileSizeLow = pFileData->nFileSizeLow;
1492/* info->nNumberOfLinks = 1; */
1493 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1494 *reparse_tag = pFileData->dwReserved0;
1495 else
1496 *reparse_tag = 0;
1497}
1498
Guido van Rossumd8faa362007-04-27 19:54:29 +00001499static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001500attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001501{
Victor Stinner8c62be82010-05-06 00:08:46 +00001502 HANDLE hFindFile;
1503 WIN32_FIND_DATAW FileData;
1504 hFindFile = FindFirstFileW(pszFile, &FileData);
1505 if (hFindFile == INVALID_HANDLE_VALUE)
1506 return FALSE;
1507 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001508 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001509 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001510}
1511
Brian Curtind25aef52011-06-13 15:16:04 -05001512static BOOL
1513get_target_path(HANDLE hdl, wchar_t **target_path)
1514{
1515 int buf_size, result_length;
1516 wchar_t *buf;
1517
1518 /* We have a good handle to the target, use it to determine
1519 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001520 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1521 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001522 if(!buf_size)
1523 return FALSE;
1524
Victor Stinnerc36674a2016-03-16 14:30:16 +01001525 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001526 if (!buf) {
1527 SetLastError(ERROR_OUTOFMEMORY);
1528 return FALSE;
1529 }
1530
Steve Dower2ea51c92015-03-20 21:49:12 -07001531 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001532 buf, buf_size, VOLUME_NAME_DOS);
1533
1534 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001535 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001536 return FALSE;
1537 }
1538
1539 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001540 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001541 return FALSE;
1542 }
1543
1544 buf[result_length] = 0;
1545
1546 *target_path = buf;
1547 return TRUE;
1548}
1549
1550static int
Steve Dowercc16be82016-09-08 10:35:16 -07001551win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001552 BOOL traverse)
1553{
Victor Stinner26de69d2011-06-17 15:15:38 +02001554 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001555 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001556 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001557 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001558 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001559 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560
Steve Dowercc16be82016-09-08 10:35:16 -07001561 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001562 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001563 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 0, /* share mode */
1565 NULL, /* security attributes */
1566 OPEN_EXISTING,
1567 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001568 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1569 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001570 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001571 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1572 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 NULL);
1574
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001575 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001576 /* Either the target doesn't exist, or we don't have access to
1577 get a handle to it. If the former, we need to return an error.
1578 If the latter, we can use attributes_from_dir. */
1579 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001580 return -1;
1581 /* Could not get attributes on open file. Fall back to
1582 reading the directory. */
1583 if (!attributes_from_dir(path, &info, &reparse_tag))
1584 /* Very strange. This should not fail now */
1585 return -1;
1586 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1587 if (traverse) {
1588 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001589 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001590 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001591 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001592 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001593 } else {
1594 if (!GetFileInformationByHandle(hFile, &info)) {
1595 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001596 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001597 }
1598 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001599 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1600 return -1;
1601
1602 /* Close the outer open file handle now that we're about to
1603 reopen it with different flags. */
1604 if (!CloseHandle(hFile))
1605 return -1;
1606
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001608 /* In order to call GetFinalPathNameByHandle we need to open
1609 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001610 hFile2 = CreateFileW(
1611 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1612 NULL, OPEN_EXISTING,
1613 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1614 NULL);
1615 if (hFile2 == INVALID_HANDLE_VALUE)
1616 return -1;
1617
1618 if (!get_target_path(hFile2, &target_path))
1619 return -1;
1620
Steve Dowercc16be82016-09-08 10:35:16 -07001621 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001622 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return code;
1624 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001625 } else
1626 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001627 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001628 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001629
1630 /* Set S_IEXEC if it is an .exe, .bat, ... */
1631 dot = wcsrchr(path, '.');
1632 if (dot) {
1633 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1634 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1635 result->st_mode |= 0111;
1636 }
1637 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001638}
1639
1640static int
Steve Dowercc16be82016-09-08 10:35:16 -07001641win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001642{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 /* Protocol violation: we explicitly clear errno, instead of
1644 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001645 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001646 errno = 0;
1647 return code;
1648}
Brian Curtind25aef52011-06-13 15:16:04 -05001649/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001650
1651 In Posix, stat automatically traverses symlinks and returns the stat
1652 structure for the target. In Windows, the equivalent GetFileAttributes by
1653 default does not traverse symlinks and instead returns attributes for
1654 the symlink.
1655
1656 Therefore, win32_lstat will get the attributes traditionally, and
1657 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001658 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001659
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001660static int
Steve Dowercc16be82016-09-08 10:35:16 -07001661win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001662{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001663 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001664}
1665
Victor Stinner8c62be82010-05-06 00:08:46 +00001666static int
Steve Dowercc16be82016-09-08 10:35:16 -07001667win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001668{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001670}
1671
Martin v. Löwis14694662006-02-03 12:54:16 +00001672#endif /* MS_WINDOWS */
1673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001674PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001675"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001676This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001677 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001678or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1679\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001680Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1681or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001682\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001683See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001684
1685static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001686 {"st_mode", "protection bits"},
1687 {"st_ino", "inode"},
1688 {"st_dev", "device"},
1689 {"st_nlink", "number of hard links"},
1690 {"st_uid", "user ID of owner"},
1691 {"st_gid", "group ID of owner"},
1692 {"st_size", "total size, in bytes"},
1693 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1694 {NULL, "integer time of last access"},
1695 {NULL, "integer time of last modification"},
1696 {NULL, "integer time of last change"},
1697 {"st_atime", "time of last access"},
1698 {"st_mtime", "time of last modification"},
1699 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001700 {"st_atime_ns", "time of last access in nanoseconds"},
1701 {"st_mtime_ns", "time of last modification in nanoseconds"},
1702 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001703#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001704 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001705#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001706#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001707 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001708#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001709#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001710 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001711#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001712#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001713 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001714#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001715#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001716 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001717#endif
1718#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001719 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001720#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001721#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1722 {"st_file_attributes", "Windows file attribute bits"},
1723#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001724 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001725};
1726
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001727#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001728#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001729#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001730#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001731#endif
1732
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001733#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001734#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1735#else
1736#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1737#endif
1738
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001739#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001740#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1741#else
1742#define ST_RDEV_IDX ST_BLOCKS_IDX
1743#endif
1744
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001745#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1746#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1747#else
1748#define ST_FLAGS_IDX ST_RDEV_IDX
1749#endif
1750
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001751#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001752#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001753#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001754#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001755#endif
1756
1757#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1758#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1759#else
1760#define ST_BIRTHTIME_IDX ST_GEN_IDX
1761#endif
1762
Zachary Ware63f277b2014-06-19 09:46:37 -05001763#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1764#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1765#else
1766#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1767#endif
1768
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001769static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 "stat_result", /* name */
1771 stat_result__doc__, /* doc */
1772 stat_result_fields,
1773 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001774};
1775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1778This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001779 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001780or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001781\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001782See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783
1784static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"f_bsize", },
1786 {"f_frsize", },
1787 {"f_blocks", },
1788 {"f_bfree", },
1789 {"f_bavail", },
1790 {"f_files", },
1791 {"f_ffree", },
1792 {"f_favail", },
1793 {"f_flag", },
1794 {"f_namemax",},
1795 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001796};
1797
1798static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001799 "statvfs_result", /* name */
1800 statvfs_result__doc__, /* doc */
1801 statvfs_result_fields,
1802 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001803};
1804
Ross Lagerwall7807c352011-03-17 20:20:30 +02001805#if defined(HAVE_WAITID) && !defined(__APPLE__)
1806PyDoc_STRVAR(waitid_result__doc__,
1807"waitid_result: Result from waitid.\n\n\
1808This object may be accessed either as a tuple of\n\
1809 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1810or via the attributes si_pid, si_uid, and so on.\n\
1811\n\
1812See os.waitid for more information.");
1813
1814static PyStructSequence_Field waitid_result_fields[] = {
1815 {"si_pid", },
1816 {"si_uid", },
1817 {"si_signo", },
1818 {"si_status", },
1819 {"si_code", },
1820 {0}
1821};
1822
1823static PyStructSequence_Desc waitid_result_desc = {
1824 "waitid_result", /* name */
1825 waitid_result__doc__, /* doc */
1826 waitid_result_fields,
1827 5
1828};
1829static PyTypeObject WaitidResultType;
1830#endif
1831
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001832static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001833static PyTypeObject StatResultType;
1834static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001835#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001836static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001837#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001838static newfunc structseq_new;
1839
1840static PyObject *
1841statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1842{
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 PyStructSequence *result;
1844 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001845
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 result = (PyStructSequence*)structseq_new(type, args, kwds);
1847 if (!result)
1848 return NULL;
1849 /* If we have been initialized from a tuple,
1850 st_?time might be set to None. Initialize it
1851 from the int slots. */
1852 for (i = 7; i <= 9; i++) {
1853 if (result->ob_item[i+3] == Py_None) {
1854 Py_DECREF(Py_None);
1855 Py_INCREF(result->ob_item[i]);
1856 result->ob_item[i+3] = result->ob_item[i];
1857 }
1858 }
1859 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001860}
1861
1862
1863
1864/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001865static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001866
1867PyDoc_STRVAR(stat_float_times__doc__,
1868"stat_float_times([newval]) -> oldval\n\n\
1869Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001870\n\
1871If value is True, future calls to stat() return floats; if it is False,\n\
1872future calls return ints.\n\
1873If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001874
Larry Hastings2f936352014-08-05 14:04:04 +10001875/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001876static PyObject*
1877stat_float_times(PyObject* self, PyObject *args)
1878{
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 int newval = -1;
1880 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1881 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001882 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1883 "stat_float_times() is deprecated",
1884 1))
1885 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001886 if (newval == -1)
1887 /* Return old value */
1888 return PyBool_FromLong(_stat_float_times);
1889 _stat_float_times = newval;
1890 Py_INCREF(Py_None);
1891 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001892}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001893
Larry Hastings6fe20b32012-04-19 15:07:49 -07001894static PyObject *billion = NULL;
1895
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001896static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001897fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001898{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001899 PyObject *s = _PyLong_FromTime_t(sec);
1900 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1901 PyObject *s_in_ns = NULL;
1902 PyObject *ns_total = NULL;
1903 PyObject *float_s = NULL;
1904
1905 if (!(s && ns_fractional))
1906 goto exit;
1907
1908 s_in_ns = PyNumber_Multiply(s, billion);
1909 if (!s_in_ns)
1910 goto exit;
1911
1912 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1913 if (!ns_total)
1914 goto exit;
1915
Victor Stinner4195b5c2012-02-08 23:03:19 +01001916 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001917 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1918 if (!float_s)
1919 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001921 else {
1922 float_s = s;
1923 Py_INCREF(float_s);
1924 }
1925
1926 PyStructSequence_SET_ITEM(v, index, s);
1927 PyStructSequence_SET_ITEM(v, index+3, float_s);
1928 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1929 s = NULL;
1930 float_s = NULL;
1931 ns_total = NULL;
1932exit:
1933 Py_XDECREF(s);
1934 Py_XDECREF(ns_fractional);
1935 Py_XDECREF(s_in_ns);
1936 Py_XDECREF(ns_total);
1937 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001938}
1939
Tim Peters5aa91602002-01-30 05:46:57 +00001940/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001941 (used by posix_stat() and posix_fstat()) */
1942static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001943_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001944{
Victor Stinner8c62be82010-05-06 00:08:46 +00001945 unsigned long ansec, mnsec, cnsec;
1946 PyObject *v = PyStructSequence_New(&StatResultType);
1947 if (v == NULL)
1948 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001949
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001951#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001953 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001954#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001956#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001957#ifdef MS_WINDOWS
1958 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001959#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001960 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001961#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001963#if defined(MS_WINDOWS)
1964 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1965 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1966#else
1967 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1968 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1969#endif
Fred Drake699f3522000-06-29 21:12:41 +00001970#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001972 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001973#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001975#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001976
Martin v. Löwis14694662006-02-03 12:54:16 +00001977#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 ansec = st->st_atim.tv_nsec;
1979 mnsec = st->st_mtim.tv_nsec;
1980 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001981#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 ansec = st->st_atimespec.tv_nsec;
1983 mnsec = st->st_mtimespec.tv_nsec;
1984 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001985#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 ansec = st->st_atime_nsec;
1987 mnsec = st->st_mtime_nsec;
1988 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001989#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001991#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001992 fill_time(v, 7, st->st_atime, ansec);
1993 fill_time(v, 8, st->st_mtime, mnsec);
1994 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001996#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1998 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001999#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002000#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2002 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002003#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002004#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2006 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002007#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002008#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2010 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002011#endif
2012#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002014 PyObject *val;
2015 unsigned long bsec,bnsec;
2016 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002017#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002018 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002019#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002020 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002022 if (_stat_float_times) {
2023 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2024 } else {
2025 val = PyLong_FromLong((long)bsec);
2026 }
2027 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2028 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002030#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002031#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2033 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002034#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002035#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2036 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2037 PyLong_FromUnsignedLong(st->st_file_attributes));
2038#endif
Fred Drake699f3522000-06-29 21:12:41 +00002039
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 if (PyErr_Occurred()) {
2041 Py_DECREF(v);
2042 return NULL;
2043 }
Fred Drake699f3522000-06-29 21:12:41 +00002044
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002046}
2047
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002048/* POSIX methods */
2049
Guido van Rossum94f6f721999-01-06 18:42:14 +00002050
2051static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002052posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002053 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002054{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002055 STRUCT_STAT st;
2056 int result;
2057
2058#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2059 if (follow_symlinks_specified(function_name, follow_symlinks))
2060 return NULL;
2061#endif
2062
2063 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2064 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2065 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2066 return NULL;
2067
2068 Py_BEGIN_ALLOW_THREADS
2069 if (path->fd != -1)
2070 result = FSTAT(path->fd, &st);
2071 else
2072#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002073 if (follow_symlinks)
2074 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075 else
Steve Dowercc16be82016-09-08 10:35:16 -07002076 result = win32_lstat(path->wide, &st);
2077#else
2078 else
2079#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002080 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2081 result = LSTAT(path->narrow, &st);
2082 else
Steve Dowercc16be82016-09-08 10:35:16 -07002083#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002084#ifdef HAVE_FSTATAT
2085 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2086 result = fstatat(dir_fd, path->narrow, &st,
2087 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2088 else
Steve Dowercc16be82016-09-08 10:35:16 -07002089#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002090 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002091#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002092 Py_END_ALLOW_THREADS
2093
Victor Stinner292c8352012-10-30 02:17:38 +01002094 if (result != 0) {
2095 return path_error(path);
2096 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002097
2098 return _pystat_fromstructstat(&st);
2099}
2100
Larry Hastings2f936352014-08-05 14:04:04 +10002101/*[python input]
2102
2103for s in """
2104
2105FACCESSAT
2106FCHMODAT
2107FCHOWNAT
2108FSTATAT
2109LINKAT
2110MKDIRAT
2111MKFIFOAT
2112MKNODAT
2113OPENAT
2114READLINKAT
2115SYMLINKAT
2116UNLINKAT
2117
2118""".strip().split():
2119 s = s.strip()
2120 print("""
2121#ifdef HAVE_{s}
2122 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002123#else
Larry Hastings2f936352014-08-05 14:04:04 +10002124 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002125#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002126""".rstrip().format(s=s))
2127
2128for s in """
2129
2130FCHDIR
2131FCHMOD
2132FCHOWN
2133FDOPENDIR
2134FEXECVE
2135FPATHCONF
2136FSTATVFS
2137FTRUNCATE
2138
2139""".strip().split():
2140 s = s.strip()
2141 print("""
2142#ifdef HAVE_{s}
2143 #define PATH_HAVE_{s} 1
2144#else
2145 #define PATH_HAVE_{s} 0
2146#endif
2147
2148""".rstrip().format(s=s))
2149[python start generated code]*/
2150
2151#ifdef HAVE_FACCESSAT
2152 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2153#else
2154 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2155#endif
2156
2157#ifdef HAVE_FCHMODAT
2158 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2159#else
2160 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2161#endif
2162
2163#ifdef HAVE_FCHOWNAT
2164 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2165#else
2166 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2167#endif
2168
2169#ifdef HAVE_FSTATAT
2170 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2171#else
2172 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2173#endif
2174
2175#ifdef HAVE_LINKAT
2176 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2177#else
2178 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2179#endif
2180
2181#ifdef HAVE_MKDIRAT
2182 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2183#else
2184 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2185#endif
2186
2187#ifdef HAVE_MKFIFOAT
2188 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2189#else
2190 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2191#endif
2192
2193#ifdef HAVE_MKNODAT
2194 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2195#else
2196 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2197#endif
2198
2199#ifdef HAVE_OPENAT
2200 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2201#else
2202 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2203#endif
2204
2205#ifdef HAVE_READLINKAT
2206 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2207#else
2208 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2209#endif
2210
2211#ifdef HAVE_SYMLINKAT
2212 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2213#else
2214 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2215#endif
2216
2217#ifdef HAVE_UNLINKAT
2218 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2219#else
2220 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2221#endif
2222
2223#ifdef HAVE_FCHDIR
2224 #define PATH_HAVE_FCHDIR 1
2225#else
2226 #define PATH_HAVE_FCHDIR 0
2227#endif
2228
2229#ifdef HAVE_FCHMOD
2230 #define PATH_HAVE_FCHMOD 1
2231#else
2232 #define PATH_HAVE_FCHMOD 0
2233#endif
2234
2235#ifdef HAVE_FCHOWN
2236 #define PATH_HAVE_FCHOWN 1
2237#else
2238 #define PATH_HAVE_FCHOWN 0
2239#endif
2240
2241#ifdef HAVE_FDOPENDIR
2242 #define PATH_HAVE_FDOPENDIR 1
2243#else
2244 #define PATH_HAVE_FDOPENDIR 0
2245#endif
2246
2247#ifdef HAVE_FEXECVE
2248 #define PATH_HAVE_FEXECVE 1
2249#else
2250 #define PATH_HAVE_FEXECVE 0
2251#endif
2252
2253#ifdef HAVE_FPATHCONF
2254 #define PATH_HAVE_FPATHCONF 1
2255#else
2256 #define PATH_HAVE_FPATHCONF 0
2257#endif
2258
2259#ifdef HAVE_FSTATVFS
2260 #define PATH_HAVE_FSTATVFS 1
2261#else
2262 #define PATH_HAVE_FSTATVFS 0
2263#endif
2264
2265#ifdef HAVE_FTRUNCATE
2266 #define PATH_HAVE_FTRUNCATE 1
2267#else
2268 #define PATH_HAVE_FTRUNCATE 0
2269#endif
2270/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002271
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002272#ifdef MS_WINDOWS
2273 #undef PATH_HAVE_FTRUNCATE
2274 #define PATH_HAVE_FTRUNCATE 1
2275#endif
Larry Hastings31826802013-10-19 00:09:25 -07002276
Larry Hastings61272b72014-01-07 12:41:53 -08002277/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002278
2279class path_t_converter(CConverter):
2280
2281 type = "path_t"
2282 impl_by_reference = True
2283 parse_by_reference = True
2284
2285 converter = 'path_converter'
2286
2287 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002288 # right now path_t doesn't support default values.
2289 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002290 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002291 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002292
Larry Hastings2f936352014-08-05 14:04:04 +10002293 if self.c_default not in (None, 'Py_None'):
2294 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002295
2296 self.nullable = nullable
2297 self.allow_fd = allow_fd
2298
Larry Hastings7726ac92014-01-31 22:03:12 -08002299 def pre_render(self):
2300 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002301 if isinstance(value, str):
2302 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002303 return str(int(bool(value)))
2304
2305 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002306 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002307 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002308 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002309 strify(self.nullable),
2310 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002311 )
2312
2313 def cleanup(self):
2314 return "path_cleanup(&" + self.name + ");\n"
2315
2316
2317class dir_fd_converter(CConverter):
2318 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002319
Larry Hastings2f936352014-08-05 14:04:04 +10002320 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002321 if self.default in (unspecified, None):
2322 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002323 if isinstance(requires, str):
2324 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2325 else:
2326 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002327
Larry Hastings2f936352014-08-05 14:04:04 +10002328class fildes_converter(CConverter):
2329 type = 'int'
2330 converter = 'fildes_converter'
2331
2332class uid_t_converter(CConverter):
2333 type = "uid_t"
2334 converter = '_Py_Uid_Converter'
2335
2336class gid_t_converter(CConverter):
2337 type = "gid_t"
2338 converter = '_Py_Gid_Converter'
2339
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002340class dev_t_converter(CConverter):
2341 type = 'dev_t'
2342 converter = '_Py_Dev_Converter'
2343
2344class dev_t_return_converter(unsigned_long_return_converter):
2345 type = 'dev_t'
2346 conversion_fn = '_PyLong_FromDev'
2347 unsigned_cast = '(dev_t)'
2348
Larry Hastings2f936352014-08-05 14:04:04 +10002349class FSConverter_converter(CConverter):
2350 type = 'PyObject *'
2351 converter = 'PyUnicode_FSConverter'
2352 def converter_init(self):
2353 if self.default is not unspecified:
2354 fail("FSConverter_converter does not support default values")
2355 self.c_default = 'NULL'
2356
2357 def cleanup(self):
2358 return "Py_XDECREF(" + self.name + ");\n"
2359
2360class pid_t_converter(CConverter):
2361 type = 'pid_t'
2362 format_unit = '" _Py_PARSE_PID "'
2363
2364class idtype_t_converter(int_converter):
2365 type = 'idtype_t'
2366
2367class id_t_converter(CConverter):
2368 type = 'id_t'
2369 format_unit = '" _Py_PARSE_PID "'
2370
Benjamin Petersonca470632016-09-06 13:47:26 -07002371class intptr_t_converter(CConverter):
2372 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002373 format_unit = '" _Py_PARSE_INTPTR "'
2374
2375class Py_off_t_converter(CConverter):
2376 type = 'Py_off_t'
2377 converter = 'Py_off_t_converter'
2378
2379class Py_off_t_return_converter(long_return_converter):
2380 type = 'Py_off_t'
2381 conversion_fn = 'PyLong_FromPy_off_t'
2382
2383class path_confname_converter(CConverter):
2384 type="int"
2385 converter="conv_path_confname"
2386
2387class confstr_confname_converter(path_confname_converter):
2388 converter='conv_confstr_confname'
2389
2390class sysconf_confname_converter(path_confname_converter):
2391 converter="conv_sysconf_confname"
2392
2393class sched_param_converter(CConverter):
2394 type = 'struct sched_param'
2395 converter = 'convert_sched_param'
2396 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002397
Larry Hastings61272b72014-01-07 12:41:53 -08002398[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002399/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002400
Larry Hastings61272b72014-01-07 12:41:53 -08002401/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002402
Larry Hastings2a727912014-01-16 11:32:01 -08002403os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002404
2405 path : path_t(allow_fd=True)
2406 Path to be examined; can be string, bytes, or open-file-descriptor int.
2407
2408 *
2409
Larry Hastings2f936352014-08-05 14:04:04 +10002410 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002411 If not None, it should be a file descriptor open to a directory,
2412 and path should be a relative string; path will then be relative to
2413 that directory.
2414
2415 follow_symlinks: bool = True
2416 If False, and the last element of the path is a symbolic link,
2417 stat will examine the symbolic link itself instead of the file
2418 the link points to.
2419
2420Perform a stat system call on the given path.
2421
2422dir_fd and follow_symlinks may not be implemented
2423 on your platform. If they are unavailable, using them will raise a
2424 NotImplementedError.
2425
2426It's an error to use dir_fd or follow_symlinks when specifying path as
2427 an open file descriptor.
2428
Larry Hastings61272b72014-01-07 12:41:53 -08002429[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002430
Larry Hastings31826802013-10-19 00:09:25 -07002431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002432os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2433/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002434{
2435 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2436}
2437
Larry Hastings2f936352014-08-05 14:04:04 +10002438
2439/*[clinic input]
2440os.lstat
2441
2442 path : path_t
2443
2444 *
2445
2446 dir_fd : dir_fd(requires='fstatat') = None
2447
2448Perform a stat system call on the given path, without following symbolic links.
2449
2450Like stat(), but do not follow symbolic links.
2451Equivalent to stat(path, follow_symlinks=False).
2452[clinic start generated code]*/
2453
Larry Hastings2f936352014-08-05 14:04:04 +10002454static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002455os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2456/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002457{
2458 int follow_symlinks = 0;
2459 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2460}
Larry Hastings31826802013-10-19 00:09:25 -07002461
Larry Hastings2f936352014-08-05 14:04:04 +10002462
Larry Hastings61272b72014-01-07 12:41:53 -08002463/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002464os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002465
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002466 path: path_t
2467 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002468
2469 mode: int
2470 Operating-system mode bitfield. Can be F_OK to test existence,
2471 or the inclusive-OR of R_OK, W_OK, and X_OK.
2472
2473 *
2474
Larry Hastings2f936352014-08-05 14:04:04 +10002475 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002476 If not None, it should be a file descriptor open to a directory,
2477 and path should be relative; path will then be relative to that
2478 directory.
2479
2480 effective_ids: bool = False
2481 If True, access will use the effective uid/gid instead of
2482 the real uid/gid.
2483
2484 follow_symlinks: bool = True
2485 If False, and the last element of the path is a symbolic link,
2486 access will examine the symbolic link itself instead of the file
2487 the link points to.
2488
2489Use the real uid/gid to test for access to a path.
2490
2491{parameters}
2492dir_fd, effective_ids, and follow_symlinks may not be implemented
2493 on your platform. If they are unavailable, using them will raise a
2494 NotImplementedError.
2495
2496Note that most operations will use the effective uid/gid, therefore this
2497 routine can be used in a suid/sgid environment to test if the invoking user
2498 has the specified access to the path.
2499
Larry Hastings61272b72014-01-07 12:41:53 -08002500[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002501
Larry Hastings2f936352014-08-05 14:04:04 +10002502static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002503os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002504 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002505/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002506{
Larry Hastings2f936352014-08-05 14:04:04 +10002507 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002508
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002509#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002510 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002511#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002512 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002513#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002514
Larry Hastings9cf065c2012-06-22 16:30:09 -07002515#ifndef HAVE_FACCESSAT
2516 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002517 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002518
2519 if (effective_ids) {
2520 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002521 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002522 }
2523#endif
2524
2525#ifdef MS_WINDOWS
2526 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002527 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002528 Py_END_ALLOW_THREADS
2529
2530 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002531 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532 * * we didn't get a -1, and
2533 * * write access wasn't requested,
2534 * * or the file isn't read-only,
2535 * * or it's a directory.
2536 * (Directories cannot be read-only on Windows.)
2537 */
Larry Hastings2f936352014-08-05 14:04:04 +10002538 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002539 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002540 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002541 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542#else
2543
2544 Py_BEGIN_ALLOW_THREADS
2545#ifdef HAVE_FACCESSAT
2546 if ((dir_fd != DEFAULT_DIR_FD) ||
2547 effective_ids ||
2548 !follow_symlinks) {
2549 int flags = 0;
2550 if (!follow_symlinks)
2551 flags |= AT_SYMLINK_NOFOLLOW;
2552 if (effective_ids)
2553 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002554 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002555 }
2556 else
2557#endif
Larry Hastings31826802013-10-19 00:09:25 -07002558 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002560 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002561#endif
2562
Larry Hastings9cf065c2012-06-22 16:30:09 -07002563 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002564}
2565
Guido van Rossumd371ff11999-01-25 16:12:23 +00002566#ifndef F_OK
2567#define F_OK 0
2568#endif
2569#ifndef R_OK
2570#define R_OK 4
2571#endif
2572#ifndef W_OK
2573#define W_OK 2
2574#endif
2575#ifndef X_OK
2576#define X_OK 1
2577#endif
2578
Larry Hastings31826802013-10-19 00:09:25 -07002579
Guido van Rossumd371ff11999-01-25 16:12:23 +00002580#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002581/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002582os.ttyname -> DecodeFSDefault
2583
2584 fd: int
2585 Integer file descriptor handle.
2586
2587 /
2588
2589Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002590[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002591
Larry Hastings31826802013-10-19 00:09:25 -07002592static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002593os_ttyname_impl(PyObject *module, int fd)
2594/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002595{
2596 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002597
Larry Hastings31826802013-10-19 00:09:25 -07002598 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002600 posix_error();
2601 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002602}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002603#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002604
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002605#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002606/*[clinic input]
2607os.ctermid
2608
2609Return the name of the controlling terminal for this process.
2610[clinic start generated code]*/
2611
Larry Hastings2f936352014-08-05 14:04:04 +10002612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002613os_ctermid_impl(PyObject *module)
2614/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002615{
Victor Stinner8c62be82010-05-06 00:08:46 +00002616 char *ret;
2617 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002618
Greg Wardb48bc172000-03-01 21:51:56 +00002619#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002620 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002621#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002622 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002623#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002624 if (ret == NULL)
2625 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002626 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002627}
Larry Hastings2f936352014-08-05 14:04:04 +10002628#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002629
Larry Hastings2f936352014-08-05 14:04:04 +10002630
2631/*[clinic input]
2632os.chdir
2633
2634 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2635
2636Change the current working directory to the specified path.
2637
2638path may always be specified as a string.
2639On some platforms, path may also be specified as an open file descriptor.
2640 If this functionality is unavailable, using it raises an exception.
2641[clinic start generated code]*/
2642
Larry Hastings2f936352014-08-05 14:04:04 +10002643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002644os_chdir_impl(PyObject *module, path_t *path)
2645/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002646{
2647 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648
2649 Py_BEGIN_ALLOW_THREADS
2650#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002651 /* on unix, success = 0, on windows, success = !0 */
2652 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653#else
2654#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002655 if (path->fd != -1)
2656 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002657 else
2658#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002659 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660#endif
2661 Py_END_ALLOW_THREADS
2662
2663 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002664 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002665 }
2666
Larry Hastings2f936352014-08-05 14:04:04 +10002667 Py_RETURN_NONE;
2668}
2669
2670
2671#ifdef HAVE_FCHDIR
2672/*[clinic input]
2673os.fchdir
2674
2675 fd: fildes
2676
2677Change to the directory of the given file descriptor.
2678
2679fd must be opened on a directory, not a file.
2680Equivalent to os.chdir(fd).
2681
2682[clinic start generated code]*/
2683
Fred Drake4d1e64b2002-04-15 19:40:07 +00002684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002685os_fchdir_impl(PyObject *module, int fd)
2686/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002687{
Larry Hastings2f936352014-08-05 14:04:04 +10002688 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002689}
2690#endif /* HAVE_FCHDIR */
2691
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002692
Larry Hastings2f936352014-08-05 14:04:04 +10002693/*[clinic input]
2694os.chmod
2695
2696 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2697 Path to be modified. May always be specified as a str or bytes.
2698 On some platforms, path may also be specified as an open file descriptor.
2699 If this functionality is unavailable, using it raises an exception.
2700
2701 mode: int
2702 Operating-system mode bitfield.
2703
2704 *
2705
2706 dir_fd : dir_fd(requires='fchmodat') = None
2707 If not None, it should be a file descriptor open to a directory,
2708 and path should be relative; path will then be relative to that
2709 directory.
2710
2711 follow_symlinks: bool = True
2712 If False, and the last element of the path is a symbolic link,
2713 chmod will modify the symbolic link itself instead of the file
2714 the link points to.
2715
2716Change the access permissions of a file.
2717
2718It is an error to use dir_fd or follow_symlinks when specifying path as
2719 an open file descriptor.
2720dir_fd and follow_symlinks may not be implemented on your platform.
2721 If they are unavailable, using them will raise a NotImplementedError.
2722
2723[clinic start generated code]*/
2724
Larry Hastings2f936352014-08-05 14:04:04 +10002725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002726os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002727 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002728/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002729{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002730 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002731
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002732#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002733 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002734#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002735
Larry Hastings9cf065c2012-06-22 16:30:09 -07002736#ifdef HAVE_FCHMODAT
2737 int fchmodat_nofollow_unsupported = 0;
2738#endif
2739
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2741 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002742 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002743#endif
2744
2745#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002746 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002747 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002748 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002749 result = 0;
2750 else {
2751 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002752 attr &= ~FILE_ATTRIBUTE_READONLY;
2753 else
2754 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002755 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002756 }
2757 Py_END_ALLOW_THREADS
2758
2759 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002760 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002761 }
2762#else /* MS_WINDOWS */
2763 Py_BEGIN_ALLOW_THREADS
2764#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002765 if (path->fd != -1)
2766 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002767 else
2768#endif
2769#ifdef HAVE_LCHMOD
2770 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002771 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002772 else
2773#endif
2774#ifdef HAVE_FCHMODAT
2775 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2776 /*
2777 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2778 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002779 * and then says it isn't implemented yet.
2780 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 *
2782 * Once it is supported, os.chmod will automatically
2783 * support dir_fd and follow_symlinks=False. (Hopefully.)
2784 * Until then, we need to be careful what exception we raise.
2785 */
Larry Hastings2f936352014-08-05 14:04:04 +10002786 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2788 /*
2789 * But wait! We can't throw the exception without allowing threads,
2790 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2791 */
2792 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002793 result &&
2794 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2795 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 }
2797 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002798#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002799 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800 Py_END_ALLOW_THREADS
2801
2802 if (result) {
2803#ifdef HAVE_FCHMODAT
2804 if (fchmodat_nofollow_unsupported) {
2805 if (dir_fd != DEFAULT_DIR_FD)
2806 dir_fd_and_follow_symlinks_invalid("chmod",
2807 dir_fd, follow_symlinks);
2808 else
2809 follow_symlinks_specified("chmod", follow_symlinks);
2810 }
2811 else
2812#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002813 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002814 }
2815#endif
2816
Larry Hastings2f936352014-08-05 14:04:04 +10002817 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002818}
2819
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820
Christian Heimes4e30a842007-11-30 22:12:06 +00002821#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002822/*[clinic input]
2823os.fchmod
2824
2825 fd: int
2826 mode: int
2827
2828Change the access permissions of the file given by file descriptor fd.
2829
2830Equivalent to os.chmod(fd, mode).
2831[clinic start generated code]*/
2832
Larry Hastings2f936352014-08-05 14:04:04 +10002833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002834os_fchmod_impl(PyObject *module, int fd, int mode)
2835/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002836{
2837 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002838 int async_err = 0;
2839
2840 do {
2841 Py_BEGIN_ALLOW_THREADS
2842 res = fchmod(fd, mode);
2843 Py_END_ALLOW_THREADS
2844 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2845 if (res != 0)
2846 return (!async_err) ? posix_error() : NULL;
2847
Victor Stinner8c62be82010-05-06 00:08:46 +00002848 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002849}
2850#endif /* HAVE_FCHMOD */
2851
Larry Hastings2f936352014-08-05 14:04:04 +10002852
Christian Heimes4e30a842007-11-30 22:12:06 +00002853#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002854/*[clinic input]
2855os.lchmod
2856
2857 path: path_t
2858 mode: int
2859
2860Change the access permissions of a file, without following symbolic links.
2861
2862If path is a symlink, this affects the link itself rather than the target.
2863Equivalent to chmod(path, mode, follow_symlinks=False)."
2864[clinic start generated code]*/
2865
Larry Hastings2f936352014-08-05 14:04:04 +10002866static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002867os_lchmod_impl(PyObject *module, path_t *path, int mode)
2868/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002869{
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002871 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002872 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002873 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002874 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002875 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002876 return NULL;
2877 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002878 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002879}
2880#endif /* HAVE_LCHMOD */
2881
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002882
Thomas Wouterscf297e42007-02-23 15:07:44 +00002883#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002884/*[clinic input]
2885os.chflags
2886
2887 path: path_t
2888 flags: unsigned_long(bitwise=True)
2889 follow_symlinks: bool=True
2890
2891Set file flags.
2892
2893If follow_symlinks is False, and the last element of the path is a symbolic
2894 link, chflags will change flags on the symbolic link itself instead of the
2895 file the link points to.
2896follow_symlinks may not be implemented on your platform. If it is
2897unavailable, using it will raise a NotImplementedError.
2898
2899[clinic start generated code]*/
2900
Larry Hastings2f936352014-08-05 14:04:04 +10002901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002902os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002903 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002904/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002905{
2906 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002907
2908#ifndef HAVE_LCHFLAGS
2909 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002910 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002911#endif
2912
Victor Stinner8c62be82010-05-06 00:08:46 +00002913 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002914#ifdef HAVE_LCHFLAGS
2915 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002916 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917 else
2918#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002919 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002920 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002921
Larry Hastings2f936352014-08-05 14:04:04 +10002922 if (result)
2923 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002924
Larry Hastings2f936352014-08-05 14:04:04 +10002925 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002926}
2927#endif /* HAVE_CHFLAGS */
2928
Larry Hastings2f936352014-08-05 14:04:04 +10002929
Thomas Wouterscf297e42007-02-23 15:07:44 +00002930#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002931/*[clinic input]
2932os.lchflags
2933
2934 path: path_t
2935 flags: unsigned_long(bitwise=True)
2936
2937Set file flags.
2938
2939This function will not follow symbolic links.
2940Equivalent to chflags(path, flags, follow_symlinks=False).
2941[clinic start generated code]*/
2942
Larry Hastings2f936352014-08-05 14:04:04 +10002943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002944os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2945/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002946{
Victor Stinner8c62be82010-05-06 00:08:46 +00002947 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002949 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002950 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002951 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002952 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002953 }
Victor Stinner292c8352012-10-30 02:17:38 +01002954 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002955}
2956#endif /* HAVE_LCHFLAGS */
2957
Larry Hastings2f936352014-08-05 14:04:04 +10002958
Martin v. Löwis244edc82001-10-04 22:44:26 +00002959#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002960/*[clinic input]
2961os.chroot
2962 path: path_t
2963
2964Change root directory to path.
2965
2966[clinic start generated code]*/
2967
Larry Hastings2f936352014-08-05 14:04:04 +10002968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002969os_chroot_impl(PyObject *module, path_t *path)
2970/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002971{
2972 int res;
2973 Py_BEGIN_ALLOW_THREADS
2974 res = chroot(path->narrow);
2975 Py_END_ALLOW_THREADS
2976 if (res < 0)
2977 return path_error(path);
2978 Py_RETURN_NONE;
2979}
2980#endif /* HAVE_CHROOT */
2981
Martin v. Löwis244edc82001-10-04 22:44:26 +00002982
Guido van Rossum21142a01999-01-08 21:05:37 +00002983#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002984/*[clinic input]
2985os.fsync
2986
2987 fd: fildes
2988
2989Force write of fd to disk.
2990[clinic start generated code]*/
2991
Larry Hastings2f936352014-08-05 14:04:04 +10002992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002993os_fsync_impl(PyObject *module, int fd)
2994/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002995{
2996 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002997}
2998#endif /* HAVE_FSYNC */
2999
Larry Hastings2f936352014-08-05 14:04:04 +10003000
Ross Lagerwall7807c352011-03-17 20:20:30 +02003001#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003002/*[clinic input]
3003os.sync
3004
3005Force write of everything to disk.
3006[clinic start generated code]*/
3007
Larry Hastings2f936352014-08-05 14:04:04 +10003008static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003009os_sync_impl(PyObject *module)
3010/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003011{
3012 Py_BEGIN_ALLOW_THREADS
3013 sync();
3014 Py_END_ALLOW_THREADS
3015 Py_RETURN_NONE;
3016}
Larry Hastings2f936352014-08-05 14:04:04 +10003017#endif /* HAVE_SYNC */
3018
Ross Lagerwall7807c352011-03-17 20:20:30 +02003019
Guido van Rossum21142a01999-01-08 21:05:37 +00003020#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003021#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003022extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3023#endif
3024
Larry Hastings2f936352014-08-05 14:04:04 +10003025/*[clinic input]
3026os.fdatasync
3027
3028 fd: fildes
3029
3030Force write of fd to disk without forcing update of metadata.
3031[clinic start generated code]*/
3032
Larry Hastings2f936352014-08-05 14:04:04 +10003033static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003034os_fdatasync_impl(PyObject *module, int fd)
3035/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003036{
3037 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003038}
3039#endif /* HAVE_FDATASYNC */
3040
3041
Fredrik Lundh10723342000-07-10 16:38:09 +00003042#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003043/*[clinic input]
3044os.chown
3045
3046 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3047 Path to be examined; can be string, bytes, or open-file-descriptor int.
3048
3049 uid: uid_t
3050
3051 gid: gid_t
3052
3053 *
3054
3055 dir_fd : dir_fd(requires='fchownat') = None
3056 If not None, it should be a file descriptor open to a directory,
3057 and path should be relative; path will then be relative to that
3058 directory.
3059
3060 follow_symlinks: bool = True
3061 If False, and the last element of the path is a symbolic link,
3062 stat will examine the symbolic link itself instead of the file
3063 the link points to.
3064
3065Change the owner and group id of path to the numeric uid and gid.\
3066
3067path may always be specified as a string.
3068On some platforms, path may also be specified as an open file descriptor.
3069 If this functionality is unavailable, using it raises an exception.
3070If dir_fd is not None, it should be a file descriptor open to a directory,
3071 and path should be relative; path will then be relative to that directory.
3072If follow_symlinks is False, and the last element of the path is a symbolic
3073 link, chown will modify the symbolic link itself instead of the file the
3074 link points to.
3075It is an error to use dir_fd or follow_symlinks when specifying path as
3076 an open file descriptor.
3077dir_fd and follow_symlinks may not be implemented on your platform.
3078 If they are unavailable, using them will raise a NotImplementedError.
3079
3080[clinic start generated code]*/
3081
Larry Hastings2f936352014-08-05 14:04:04 +10003082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003083os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003084 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003085/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003086{
3087 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088
3089#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3090 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003091 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003093 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3094 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3095 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003096
3097#ifdef __APPLE__
3098 /*
3099 * This is for Mac OS X 10.3, which doesn't have lchown.
3100 * (But we still have an lchown symbol because of weak-linking.)
3101 * It doesn't have fchownat either. So there's no possibility
3102 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003103 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003104 if ((!follow_symlinks) && (lchown == NULL)) {
3105 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003106 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003107 }
3108#endif
3109
Victor Stinner8c62be82010-05-06 00:08:46 +00003110 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003111#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003112 if (path->fd != -1)
3113 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003114 else
3115#endif
3116#ifdef HAVE_LCHOWN
3117 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003118 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003119 else
3120#endif
3121#ifdef HAVE_FCHOWNAT
3122 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003123 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3125 else
3126#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003127 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003128 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003129
Larry Hastings2f936352014-08-05 14:04:04 +10003130 if (result)
3131 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003132
Larry Hastings2f936352014-08-05 14:04:04 +10003133 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003134}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003135#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003136
Larry Hastings2f936352014-08-05 14:04:04 +10003137
Christian Heimes4e30a842007-11-30 22:12:06 +00003138#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003139/*[clinic input]
3140os.fchown
3141
3142 fd: int
3143 uid: uid_t
3144 gid: gid_t
3145
3146Change the owner and group id of the file specified by file descriptor.
3147
3148Equivalent to os.chown(fd, uid, gid).
3149
3150[clinic start generated code]*/
3151
Larry Hastings2f936352014-08-05 14:04:04 +10003152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003153os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3154/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003155{
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003157 int async_err = 0;
3158
3159 do {
3160 Py_BEGIN_ALLOW_THREADS
3161 res = fchown(fd, uid, gid);
3162 Py_END_ALLOW_THREADS
3163 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3164 if (res != 0)
3165 return (!async_err) ? posix_error() : NULL;
3166
Victor Stinner8c62be82010-05-06 00:08:46 +00003167 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003168}
3169#endif /* HAVE_FCHOWN */
3170
Larry Hastings2f936352014-08-05 14:04:04 +10003171
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003172#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003173/*[clinic input]
3174os.lchown
3175
3176 path : path_t
3177 uid: uid_t
3178 gid: gid_t
3179
3180Change the owner and group id of path to the numeric uid and gid.
3181
3182This function will not follow symbolic links.
3183Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3184[clinic start generated code]*/
3185
Larry Hastings2f936352014-08-05 14:04:04 +10003186static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003187os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3188/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003189{
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003192 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003194 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003195 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003196 }
Larry Hastings2f936352014-08-05 14:04:04 +10003197 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003198}
3199#endif /* HAVE_LCHOWN */
3200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003201
Barry Warsaw53699e91996-12-10 23:23:01 +00003202static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003203posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003204{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003205 char *buf, *tmpbuf;
3206 char *cwd;
3207 const size_t chunk = 1024;
3208 size_t buflen = 0;
3209 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003210
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003211#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003213 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003214 wchar_t *wbuf2 = wbuf;
3215 PyObject *resobj;
3216 DWORD len;
3217 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003218 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 /* If the buffer is large enough, len does not include the
3220 terminating \0. If the buffer is too small, len includes
3221 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003222 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003223 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 if (wbuf2)
3225 len = GetCurrentDirectoryW(len, wbuf2);
3226 }
3227 Py_END_ALLOW_THREADS
3228 if (!wbuf2) {
3229 PyErr_NoMemory();
3230 return NULL;
3231 }
3232 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003233 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003234 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003235 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 }
3237 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003238 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003239 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 return resobj;
3241 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003242
3243 if (win32_warn_bytes_api())
3244 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003245#endif
3246
Victor Stinner4403d7d2015-04-25 00:16:10 +02003247 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003248 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003249 do {
3250 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003251#ifdef MS_WINDOWS
3252 if (buflen > INT_MAX) {
3253 PyErr_NoMemory();
3254 break;
3255 }
3256#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003257 tmpbuf = PyMem_RawRealloc(buf, buflen);
3258 if (tmpbuf == NULL)
3259 break;
3260
3261 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003262#ifdef MS_WINDOWS
3263 cwd = getcwd(buf, (int)buflen);
3264#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003265 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003266#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003267 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003268 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003269
3270 if (cwd == NULL) {
3271 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003272 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003273 }
3274
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003276 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3277 else
3278 obj = PyUnicode_DecodeFSDefault(buf);
3279 PyMem_RawFree(buf);
3280
3281 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003282}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003283
Larry Hastings2f936352014-08-05 14:04:04 +10003284
3285/*[clinic input]
3286os.getcwd
3287
3288Return a unicode string representing the current working directory.
3289[clinic start generated code]*/
3290
Larry Hastings2f936352014-08-05 14:04:04 +10003291static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003292os_getcwd_impl(PyObject *module)
3293/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003294{
3295 return posix_getcwd(0);
3296}
3297
Larry Hastings2f936352014-08-05 14:04:04 +10003298
3299/*[clinic input]
3300os.getcwdb
3301
3302Return a bytes string representing the current working directory.
3303[clinic start generated code]*/
3304
Larry Hastings2f936352014-08-05 14:04:04 +10003305static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003306os_getcwdb_impl(PyObject *module)
3307/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003308{
3309 return posix_getcwd(1);
3310}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003311
Larry Hastings2f936352014-08-05 14:04:04 +10003312
Larry Hastings9cf065c2012-06-22 16:30:09 -07003313#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3314#define HAVE_LINK 1
3315#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003316
Guido van Rossumb6775db1994-08-01 11:34:53 +00003317#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003318/*[clinic input]
3319
3320os.link
3321
3322 src : path_t
3323 dst : path_t
3324 *
3325 src_dir_fd : dir_fd = None
3326 dst_dir_fd : dir_fd = None
3327 follow_symlinks: bool = True
3328
3329Create a hard link to a file.
3330
3331If either src_dir_fd or dst_dir_fd is not None, it should be a file
3332 descriptor open to a directory, and the respective path string (src or dst)
3333 should be relative; the path will then be relative to that directory.
3334If follow_symlinks is False, and the last element of src is a symbolic
3335 link, link will create a link to the symbolic link itself instead of the
3336 file the link points to.
3337src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3338 platform. If they are unavailable, using them will raise a
3339 NotImplementedError.
3340[clinic start generated code]*/
3341
Larry Hastings2f936352014-08-05 14:04:04 +10003342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003343os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003344 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003345/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003346{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003348 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349#else
3350 int result;
3351#endif
3352
Larry Hastings9cf065c2012-06-22 16:30:09 -07003353#ifndef HAVE_LINKAT
3354 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3355 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003356 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 }
3358#endif
3359
Steve Dowercc16be82016-09-08 10:35:16 -07003360#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003361 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362 PyErr_SetString(PyExc_NotImplementedError,
3363 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003364 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003365 }
Steve Dowercc16be82016-09-08 10:35:16 -07003366#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003367
Brian Curtin1b9df392010-11-24 20:24:31 +00003368#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003369 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003370 if (src->wide)
3371 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003373
Larry Hastings2f936352014-08-05 14:04:04 +10003374 if (!result)
3375 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376#else
3377 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003378#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3380 (dst_dir_fd != DEFAULT_DIR_FD) ||
3381 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003382 result = linkat(src_dir_fd, src->narrow,
3383 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3385 else
Steve Dowercc16be82016-09-08 10:35:16 -07003386#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003387 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003389
Larry Hastings2f936352014-08-05 14:04:04 +10003390 if (result)
3391 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003392#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003393
Larry Hastings2f936352014-08-05 14:04:04 +10003394 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003395}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396#endif
3397
Brian Curtin1b9df392010-11-24 20:24:31 +00003398
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003399#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003400static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003401_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003402{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403 PyObject *v;
3404 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3405 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003406 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003408 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410
Steve Dowercc16be82016-09-08 10:35:16 -07003411 WIN32_FIND_DATAW wFileData;
3412 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003413
Steve Dowercc16be82016-09-08 10:35:16 -07003414 if (!path->wide) { /* Default arg: "." */
3415 po_wchars = L".";
3416 len = 1;
3417 } else {
3418 po_wchars = path->wide;
3419 len = wcslen(path->wide);
3420 }
3421 /* The +5 is so we can append "\\*.*\0" */
3422 wnamebuf = PyMem_New(wchar_t, len + 5);
3423 if (!wnamebuf) {
3424 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 }
Steve Dowercc16be82016-09-08 10:35:16 -07003427 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003429 wchar_t wch = wnamebuf[len-1];
3430 if (wch != SEP && wch != ALTSEP && wch != L':')
3431 wnamebuf[len++] = SEP;
3432 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003433 }
Steve Dowercc16be82016-09-08 10:35:16 -07003434 if ((list = PyList_New(0)) == NULL) {
3435 goto exit;
3436 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003437 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003438 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003439 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 if (hFindFile == INVALID_HANDLE_VALUE) {
3441 int error = GetLastError();
3442 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 goto exit;
3444 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 }
3448 do {
3449 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003450 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3451 wcscmp(wFileData.cFileName, L"..") != 0) {
3452 v = PyUnicode_FromWideChar(wFileData.cFileName,
3453 wcslen(wFileData.cFileName));
3454 if (path->narrow && v) {
3455 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3456 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 Py_DECREF(list);
3459 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 break;
3461 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464 Py_DECREF(list);
3465 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003466 break;
3467 }
3468 Py_DECREF(v);
3469 }
3470 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003471 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 Py_END_ALLOW_THREADS
3473 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3474 it got to the end of the directory. */
3475 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003477 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003479 }
3480 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003481
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482exit:
3483 if (hFindFile != INVALID_HANDLE_VALUE) {
3484 if (FindClose(hFindFile) == FALSE) {
3485 if (list != NULL) {
3486 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003487 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003488 }
3489 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003491 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003492
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003494} /* end of _listdir_windows_no_opendir */
3495
3496#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3497
3498static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003499_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003500{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003501 PyObject *v;
3502 DIR *dirp = NULL;
3503 struct dirent *ep;
3504 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003505#ifdef HAVE_FDOPENDIR
3506 int fd = -1;
3507#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003508
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003511 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003513 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003514 if (fd == -1)
3515 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516
Larry Hastingsfdaea062012-06-25 04:42:23 -07003517 return_str = 1;
3518
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_BEGIN_ALLOW_THREADS
3520 dirp = fdopendir(fd);
3521 Py_END_ALLOW_THREADS
3522 }
3523 else
3524#endif
3525 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003526 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003527 if (path->narrow) {
3528 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003529 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003530 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003531 }
3532 else {
3533 name = ".";
3534 return_str = 1;
3535 }
3536
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_BEGIN_ALLOW_THREADS
3538 dirp = opendir(name);
3539 Py_END_ALLOW_THREADS
3540 }
3541
3542 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003543 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003544#ifdef HAVE_FDOPENDIR
3545 if (fd != -1) {
3546 Py_BEGIN_ALLOW_THREADS
3547 close(fd);
3548 Py_END_ALLOW_THREADS
3549 }
3550#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 goto exit;
3552 }
3553 if ((list = PyList_New(0)) == NULL) {
3554 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 }
3556 for (;;) {
3557 errno = 0;
3558 Py_BEGIN_ALLOW_THREADS
3559 ep = readdir(dirp);
3560 Py_END_ALLOW_THREADS
3561 if (ep == NULL) {
3562 if (errno == 0) {
3563 break;
3564 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003566 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 }
3569 }
3570 if (ep->d_name[0] == '.' &&
3571 (NAMLEN(ep) == 1 ||
3572 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3573 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003574 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003575 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3576 else
3577 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 break;
3581 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003582 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 break;
3586 }
3587 Py_DECREF(v);
3588 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003589
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590exit:
3591 if (dirp != NULL) {
3592 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003593#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 if (fd > -1)
3595 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003596#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597 closedir(dirp);
3598 Py_END_ALLOW_THREADS
3599 }
3600
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003602} /* end of _posix_listdir */
3603#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003604
Larry Hastings2f936352014-08-05 14:04:04 +10003605
3606/*[clinic input]
3607os.listdir
3608
3609 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3610
3611Return a list containing the names of the files in the directory.
3612
3613path can be specified as either str or bytes. If path is bytes,
3614 the filenames returned will also be bytes; in all other circumstances
3615 the filenames returned will be str.
3616If path is None, uses the path='.'.
3617On some platforms, path may also be specified as an open file descriptor;\
3618 the file descriptor must refer to a directory.
3619 If this functionality is unavailable, using it raises NotImplementedError.
3620
3621The list is in arbitrary order. It does not include the special
3622entries '.' and '..' even if they are present in the directory.
3623
3624
3625[clinic start generated code]*/
3626
Larry Hastings2f936352014-08-05 14:04:04 +10003627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003628os_listdir_impl(PyObject *module, path_t *path)
3629/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003630{
3631#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3632 return _listdir_windows_no_opendir(path, NULL);
3633#else
3634 return _posix_listdir(path, NULL);
3635#endif
3636}
3637
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003638#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003639/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003640/*[clinic input]
3641os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003642
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003643 path: path_t
3644 /
3645
3646[clinic start generated code]*/
3647
3648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003649os__getfullpathname_impl(PyObject *module, path_t *path)
3650/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003651{
Steve Dowercc16be82016-09-08 10:35:16 -07003652 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3653 wchar_t *wtemp;
3654 DWORD result;
3655 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003656
Steve Dowercc16be82016-09-08 10:35:16 -07003657 result = GetFullPathNameW(path->wide,
3658 Py_ARRAY_LENGTH(woutbuf),
3659 woutbuf, &wtemp);
3660 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3661 woutbufp = PyMem_New(wchar_t, result);
3662 if (!woutbufp)
3663 return PyErr_NoMemory();
3664 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 }
Steve Dowercc16be82016-09-08 10:35:16 -07003666 if (result) {
3667 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3668 if (path->narrow)
3669 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3670 } else
3671 v = win32_error_object("GetFullPathNameW", path->object);
3672 if (woutbufp != woutbuf)
3673 PyMem_Free(woutbufp);
3674 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003675}
Brian Curtind40e6f72010-07-08 21:39:08 +00003676
Brian Curtind25aef52011-06-13 15:16:04 -05003677
Larry Hastings2f936352014-08-05 14:04:04 +10003678/*[clinic input]
3679os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003680
Larry Hastings2f936352014-08-05 14:04:04 +10003681 path: unicode
3682 /
3683
3684A helper function for samepath on windows.
3685[clinic start generated code]*/
3686
Larry Hastings2f936352014-08-05 14:04:04 +10003687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003688os__getfinalpathname_impl(PyObject *module, PyObject *path)
3689/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003690{
3691 HANDLE hFile;
3692 int buf_size;
3693 wchar_t *target_path;
3694 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003695 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003696 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003697
Larry Hastings2f936352014-08-05 14:04:04 +10003698 path_wchar = PyUnicode_AsUnicode(path);
3699 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003700 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003701
Brian Curtind40e6f72010-07-08 21:39:08 +00003702 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003703 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003704 0, /* desired access */
3705 0, /* share mode */
3706 NULL, /* security attributes */
3707 OPEN_EXISTING,
3708 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3709 FILE_FLAG_BACKUP_SEMANTICS,
3710 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003711
Victor Stinnereb5657a2011-09-30 01:44:27 +02003712 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003713 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003714
3715 /* We have a good handle to the target, use it to determine the
3716 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003717 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003718
3719 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003720 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003721
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003722 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003723 if(!target_path)
3724 return PyErr_NoMemory();
3725
Steve Dower2ea51c92015-03-20 21:49:12 -07003726 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3727 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003728 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003729 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003730
3731 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003732 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003733
3734 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003735 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003736 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003737 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003738}
Brian Curtin62857742010-09-06 17:07:27 +00003739
Brian Curtin95d028f2011-06-09 09:10:38 -05003740PyDoc_STRVAR(posix__isdir__doc__,
3741"Return true if the pathname refers to an existing directory.");
3742
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003743/*[clinic input]
3744os._isdir
3745
3746 path: path_t
3747 /
3748
3749[clinic start generated code]*/
3750
Brian Curtin9c669cc2011-06-08 18:17:18 -05003751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003752os__isdir_impl(PyObject *module, path_t *path)
3753/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003754{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003755 DWORD attributes;
3756
Steve Dowerb22a6772016-07-17 20:49:38 -07003757 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003758 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003759 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003760
Brian Curtin9c669cc2011-06-08 18:17:18 -05003761 if (attributes == INVALID_FILE_ATTRIBUTES)
3762 Py_RETURN_FALSE;
3763
Brian Curtin9c669cc2011-06-08 18:17:18 -05003764 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3765 Py_RETURN_TRUE;
3766 else
3767 Py_RETURN_FALSE;
3768}
Tim Golden6b528062013-08-01 12:44:00 +01003769
Tim Golden6b528062013-08-01 12:44:00 +01003770
Larry Hastings2f936352014-08-05 14:04:04 +10003771/*[clinic input]
3772os._getvolumepathname
3773
3774 path: unicode
3775
3776A helper function for ismount on Win32.
3777[clinic start generated code]*/
3778
Larry Hastings2f936352014-08-05 14:04:04 +10003779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003780os__getvolumepathname_impl(PyObject *module, PyObject *path)
3781/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003782{
3783 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003784 const wchar_t *path_wchar;
3785 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003786 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003787 BOOL ret;
3788
Larry Hastings2f936352014-08-05 14:04:04 +10003789 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3790 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003791 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003792 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003793
3794 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003795 buflen = Py_MAX(buflen, MAX_PATH);
3796
3797 if (buflen > DWORD_MAX) {
3798 PyErr_SetString(PyExc_OverflowError, "path too long");
3799 return NULL;
3800 }
3801
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003802 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003803 if (mountpath == NULL)
3804 return PyErr_NoMemory();
3805
3806 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003807 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003808 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003809 Py_END_ALLOW_THREADS
3810
3811 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003812 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003813 goto exit;
3814 }
3815 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3816
3817exit:
3818 PyMem_Free(mountpath);
3819 return result;
3820}
Tim Golden6b528062013-08-01 12:44:00 +01003821
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003822#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003823
Larry Hastings2f936352014-08-05 14:04:04 +10003824
3825/*[clinic input]
3826os.mkdir
3827
3828 path : path_t
3829
3830 mode: int = 0o777
3831
3832 *
3833
3834 dir_fd : dir_fd(requires='mkdirat') = None
3835
3836# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3837
3838Create a directory.
3839
3840If dir_fd is not None, it should be a file descriptor open to a directory,
3841 and path should be relative; path will then be relative to that directory.
3842dir_fd may not be implemented on your platform.
3843 If it is unavailable, using it will raise a NotImplementedError.
3844
3845The mode argument is ignored on Windows.
3846[clinic start generated code]*/
3847
Larry Hastings2f936352014-08-05 14:04:04 +10003848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003849os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3850/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003851{
3852 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003853
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003854#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003856 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003857 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003858
Larry Hastings2f936352014-08-05 14:04:04 +10003859 if (!result)
3860 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003861#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003863#if HAVE_MKDIRAT
3864 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003865 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003866 else
3867#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003868#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003869 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003870#else
Larry Hastings2f936352014-08-05 14:04:04 +10003871 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003874 if (result < 0)
3875 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003876#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003877 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003878}
3879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003880
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003881/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3882#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003883#include <sys/resource.h>
3884#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003885
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003886
3887#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003888/*[clinic input]
3889os.nice
3890
3891 increment: int
3892 /
3893
3894Add increment to the priority of process and return the new priority.
3895[clinic start generated code]*/
3896
Larry Hastings2f936352014-08-05 14:04:04 +10003897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003898os_nice_impl(PyObject *module, int increment)
3899/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003900{
3901 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003902
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 /* There are two flavours of 'nice': one that returns the new
3904 priority (as required by almost all standards out there) and the
3905 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3906 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003907
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 If we are of the nice family that returns the new priority, we
3909 need to clear errno before the call, and check if errno is filled
3910 before calling posix_error() on a returnvalue of -1, because the
3911 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003912
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 errno = 0;
3914 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003915#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 if (value == 0)
3917 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003918#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 if (value == -1 && errno != 0)
3920 /* either nice() or getpriority() returned an error */
3921 return posix_error();
3922 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003923}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003924#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003925
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003926
3927#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003928/*[clinic input]
3929os.getpriority
3930
3931 which: int
3932 who: int
3933
3934Return program scheduling priority.
3935[clinic start generated code]*/
3936
Larry Hastings2f936352014-08-05 14:04:04 +10003937static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003938os_getpriority_impl(PyObject *module, int which, int who)
3939/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003940{
3941 int retval;
3942
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003943 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003944 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003945 if (errno != 0)
3946 return posix_error();
3947 return PyLong_FromLong((long)retval);
3948}
3949#endif /* HAVE_GETPRIORITY */
3950
3951
3952#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003953/*[clinic input]
3954os.setpriority
3955
3956 which: int
3957 who: int
3958 priority: int
3959
3960Set program scheduling priority.
3961[clinic start generated code]*/
3962
Larry Hastings2f936352014-08-05 14:04:04 +10003963static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003964os_setpriority_impl(PyObject *module, int which, int who, int priority)
3965/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003966{
3967 int retval;
3968
3969 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003970 if (retval == -1)
3971 return posix_error();
3972 Py_RETURN_NONE;
3973}
3974#endif /* HAVE_SETPRIORITY */
3975
3976
Barry Warsaw53699e91996-12-10 23:23:01 +00003977static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003978internal_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 +00003979{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003980 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003981 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003982
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003983#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003984 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003985 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003986#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003988#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989
Larry Hastings9cf065c2012-06-22 16:30:09 -07003990 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3991 (dst_dir_fd != DEFAULT_DIR_FD);
3992#ifndef HAVE_RENAMEAT
3993 if (dir_fd_specified) {
3994 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003995 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996 }
3997#endif
3998
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999#ifdef MS_WINDOWS
4000 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004001 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002 Py_END_ALLOW_THREADS
4003
Larry Hastings2f936352014-08-05 14:04:04 +10004004 if (!result)
4005 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006
4007#else
Steve Dowercc16be82016-09-08 10:35:16 -07004008 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4009 PyErr_Format(PyExc_ValueError,
4010 "%s: src and dst must be the same type", function_name);
4011 return NULL;
4012 }
4013
Larry Hastings9cf065c2012-06-22 16:30:09 -07004014 Py_BEGIN_ALLOW_THREADS
4015#ifdef HAVE_RENAMEAT
4016 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004017 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004018 else
4019#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004020 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004021 Py_END_ALLOW_THREADS
4022
Larry Hastings2f936352014-08-05 14:04:04 +10004023 if (result)
4024 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004025#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004026 Py_RETURN_NONE;
4027}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004028
Larry Hastings2f936352014-08-05 14:04:04 +10004029
4030/*[clinic input]
4031os.rename
4032
4033 src : path_t
4034 dst : path_t
4035 *
4036 src_dir_fd : dir_fd = None
4037 dst_dir_fd : dir_fd = None
4038
4039Rename a file or directory.
4040
4041If either src_dir_fd or dst_dir_fd is not None, it should be a file
4042 descriptor open to a directory, and the respective path string (src or dst)
4043 should be relative; the path will then be relative to that directory.
4044src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4045 If they are unavailable, using them will raise a NotImplementedError.
4046[clinic start generated code]*/
4047
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004048static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004049os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004050 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004051/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004052{
Larry Hastings2f936352014-08-05 14:04:04 +10004053 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004054}
4055
Larry Hastings2f936352014-08-05 14:04:04 +10004056
4057/*[clinic input]
4058os.replace = os.rename
4059
4060Rename a file or directory, overwriting the destination.
4061
4062If either src_dir_fd or dst_dir_fd is not None, it should be a file
4063 descriptor open to a directory, and the respective path string (src or dst)
4064 should be relative; the path will then be relative to that directory.
4065src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4066 If they are unavailable, using them will raise a NotImplementedError."
4067[clinic start generated code]*/
4068
Larry Hastings2f936352014-08-05 14:04:04 +10004069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004070os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4071 int dst_dir_fd)
4072/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004073{
4074 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4075}
4076
4077
4078/*[clinic input]
4079os.rmdir
4080
4081 path: path_t
4082 *
4083 dir_fd: dir_fd(requires='unlinkat') = None
4084
4085Remove a directory.
4086
4087If dir_fd is not None, it should be a file descriptor open to a directory,
4088 and path should be relative; path will then be relative to that directory.
4089dir_fd may not be implemented on your platform.
4090 If it is unavailable, using it will raise a NotImplementedError.
4091[clinic start generated code]*/
4092
Larry Hastings2f936352014-08-05 14:04:04 +10004093static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004094os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4095/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004096{
4097 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004098
4099 Py_BEGIN_ALLOW_THREADS
4100#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004101 /* Windows, success=1, UNIX, success=0 */
4102 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004103#else
4104#ifdef HAVE_UNLINKAT
4105 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004106 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004107 else
4108#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004109 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004110#endif
4111 Py_END_ALLOW_THREADS
4112
Larry Hastings2f936352014-08-05 14:04:04 +10004113 if (result)
4114 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004115
Larry Hastings2f936352014-08-05 14:04:04 +10004116 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004117}
4118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004119
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004120#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004121#ifdef MS_WINDOWS
4122/*[clinic input]
4123os.system -> long
4124
4125 command: Py_UNICODE
4126
4127Execute the command in a subshell.
4128[clinic start generated code]*/
4129
Larry Hastings2f936352014-08-05 14:04:04 +10004130static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004131os_system_impl(PyObject *module, Py_UNICODE *command)
4132/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004133{
4134 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004136 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004137 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004138 return result;
4139}
4140#else /* MS_WINDOWS */
4141/*[clinic input]
4142os.system -> long
4143
4144 command: FSConverter
4145
4146Execute the command in a subshell.
4147[clinic start generated code]*/
4148
Larry Hastings2f936352014-08-05 14:04:04 +10004149static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004150os_system_impl(PyObject *module, PyObject *command)
4151/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004152{
4153 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004154 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004155 Py_BEGIN_ALLOW_THREADS
4156 result = system(bytes);
4157 Py_END_ALLOW_THREADS
4158 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004159}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004160#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004161#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004163
Larry Hastings2f936352014-08-05 14:04:04 +10004164/*[clinic input]
4165os.umask
4166
4167 mask: int
4168 /
4169
4170Set the current numeric umask and return the previous umask.
4171[clinic start generated code]*/
4172
Larry Hastings2f936352014-08-05 14:04:04 +10004173static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004174os_umask_impl(PyObject *module, int mask)
4175/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004176{
4177 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 if (i < 0)
4179 return posix_error();
4180 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004181}
4182
Brian Curtind40e6f72010-07-08 21:39:08 +00004183#ifdef MS_WINDOWS
4184
4185/* override the default DeleteFileW behavior so that directory
4186symlinks can be removed with this function, the same as with
4187Unix symlinks */
4188BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4189{
4190 WIN32_FILE_ATTRIBUTE_DATA info;
4191 WIN32_FIND_DATAW find_data;
4192 HANDLE find_data_handle;
4193 int is_directory = 0;
4194 int is_link = 0;
4195
4196 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4197 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004198
Brian Curtind40e6f72010-07-08 21:39:08 +00004199 /* Get WIN32_FIND_DATA structure for the path to determine if
4200 it is a symlink */
4201 if(is_directory &&
4202 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4203 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4204
4205 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004206 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4207 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4208 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4209 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004210 FindClose(find_data_handle);
4211 }
4212 }
4213 }
4214
4215 if (is_directory && is_link)
4216 return RemoveDirectoryW(lpFileName);
4217
4218 return DeleteFileW(lpFileName);
4219}
4220#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004222
Larry Hastings2f936352014-08-05 14:04:04 +10004223/*[clinic input]
4224os.unlink
4225
4226 path: path_t
4227 *
4228 dir_fd: dir_fd(requires='unlinkat')=None
4229
4230Remove a file (same as remove()).
4231
4232If dir_fd is not None, it should be a file descriptor open to a directory,
4233 and path should be relative; path will then be relative to that directory.
4234dir_fd may not be implemented on your platform.
4235 If it is unavailable, using it will raise a NotImplementedError.
4236
4237[clinic start generated code]*/
4238
Larry Hastings2f936352014-08-05 14:04:04 +10004239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004240os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4241/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004242{
4243 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244
4245 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004246 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004247#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004248 /* Windows, success=1, UNIX, success=0 */
4249 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004250#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004251#ifdef HAVE_UNLINKAT
4252 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004253 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254 else
4255#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004256 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004257#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004258 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004259 Py_END_ALLOW_THREADS
4260
Larry Hastings2f936352014-08-05 14:04:04 +10004261 if (result)
4262 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004263
Larry Hastings2f936352014-08-05 14:04:04 +10004264 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004265}
4266
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Larry Hastings2f936352014-08-05 14:04:04 +10004268/*[clinic input]
4269os.remove = os.unlink
4270
4271Remove a file (same as unlink()).
4272
4273If dir_fd is not None, it should be a file descriptor open to a directory,
4274 and path should be relative; path will then be relative to that directory.
4275dir_fd may not be implemented on your platform.
4276 If it is unavailable, using it will raise a NotImplementedError.
4277[clinic start generated code]*/
4278
Larry Hastings2f936352014-08-05 14:04:04 +10004279static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004280os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4281/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004282{
4283 return os_unlink_impl(module, path, dir_fd);
4284}
4285
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004286
Larry Hastings605a62d2012-06-24 04:33:36 -07004287static PyStructSequence_Field uname_result_fields[] = {
4288 {"sysname", "operating system name"},
4289 {"nodename", "name of machine on network (implementation-defined)"},
4290 {"release", "operating system release"},
4291 {"version", "operating system version"},
4292 {"machine", "hardware identifier"},
4293 {NULL}
4294};
4295
4296PyDoc_STRVAR(uname_result__doc__,
4297"uname_result: Result from os.uname().\n\n\
4298This object may be accessed either as a tuple of\n\
4299 (sysname, nodename, release, version, machine),\n\
4300or via the attributes sysname, nodename, release, version, and machine.\n\
4301\n\
4302See os.uname for more information.");
4303
4304static PyStructSequence_Desc uname_result_desc = {
4305 "uname_result", /* name */
4306 uname_result__doc__, /* doc */
4307 uname_result_fields,
4308 5
4309};
4310
4311static PyTypeObject UnameResultType;
4312
4313
4314#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004315/*[clinic input]
4316os.uname
4317
4318Return an object identifying the current operating system.
4319
4320The object behaves like a named tuple with the following fields:
4321 (sysname, nodename, release, version, machine)
4322
4323[clinic start generated code]*/
4324
Larry Hastings2f936352014-08-05 14:04:04 +10004325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004326os_uname_impl(PyObject *module)
4327/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004328{
Victor Stinner8c62be82010-05-06 00:08:46 +00004329 struct utsname u;
4330 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004331 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004332
Victor Stinner8c62be82010-05-06 00:08:46 +00004333 Py_BEGIN_ALLOW_THREADS
4334 res = uname(&u);
4335 Py_END_ALLOW_THREADS
4336 if (res < 0)
4337 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004338
4339 value = PyStructSequence_New(&UnameResultType);
4340 if (value == NULL)
4341 return NULL;
4342
4343#define SET(i, field) \
4344 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004345 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004346 if (!o) { \
4347 Py_DECREF(value); \
4348 return NULL; \
4349 } \
4350 PyStructSequence_SET_ITEM(value, i, o); \
4351 } \
4352
4353 SET(0, u.sysname);
4354 SET(1, u.nodename);
4355 SET(2, u.release);
4356 SET(3, u.version);
4357 SET(4, u.machine);
4358
4359#undef SET
4360
4361 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004362}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004363#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004364
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004365
Larry Hastings9cf065c2012-06-22 16:30:09 -07004366
4367typedef struct {
4368 int now;
4369 time_t atime_s;
4370 long atime_ns;
4371 time_t mtime_s;
4372 long mtime_ns;
4373} utime_t;
4374
4375/*
Victor Stinner484df002014-10-09 13:52:31 +02004376 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377 * they also intentionally leak the declaration of a pointer named "time"
4378 */
4379#define UTIME_TO_TIMESPEC \
4380 struct timespec ts[2]; \
4381 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004382 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004383 time = NULL; \
4384 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004385 ts[0].tv_sec = ut->atime_s; \
4386 ts[0].tv_nsec = ut->atime_ns; \
4387 ts[1].tv_sec = ut->mtime_s; \
4388 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 time = ts; \
4390 } \
4391
4392#define UTIME_TO_TIMEVAL \
4393 struct timeval tv[2]; \
4394 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004395 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396 time = NULL; \
4397 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004398 tv[0].tv_sec = ut->atime_s; \
4399 tv[0].tv_usec = ut->atime_ns / 1000; \
4400 tv[1].tv_sec = ut->mtime_s; \
4401 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402 time = tv; \
4403 } \
4404
4405#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004406 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004407 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004408 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409 time = NULL; \
4410 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004411 u.actime = ut->atime_s; \
4412 u.modtime = ut->mtime_s; \
4413 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004414 }
4415
4416#define UTIME_TO_TIME_T \
4417 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004418 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004419 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004420 time = NULL; \
4421 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004422 timet[0] = ut->atime_s; \
4423 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004424 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004425 } \
4426
4427
Victor Stinner528a9ab2015-09-03 21:30:26 +02004428#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004429
4430static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004431utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432{
4433#ifdef HAVE_UTIMENSAT
4434 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4435 UTIME_TO_TIMESPEC;
4436 return utimensat(dir_fd, path, time, flags);
4437#elif defined(HAVE_FUTIMESAT)
4438 UTIME_TO_TIMEVAL;
4439 /*
4440 * follow_symlinks will never be false here;
4441 * we only allow !follow_symlinks and dir_fd together
4442 * if we have utimensat()
4443 */
4444 assert(follow_symlinks);
4445 return futimesat(dir_fd, path, time);
4446#endif
4447}
4448
Larry Hastings2f936352014-08-05 14:04:04 +10004449 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4450#else
4451 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004452#endif
4453
Victor Stinner528a9ab2015-09-03 21:30:26 +02004454#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004455
4456static int
Victor Stinner484df002014-10-09 13:52:31 +02004457utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004458{
4459#ifdef HAVE_FUTIMENS
4460 UTIME_TO_TIMESPEC;
4461 return futimens(fd, time);
4462#else
4463 UTIME_TO_TIMEVAL;
4464 return futimes(fd, time);
4465#endif
4466}
4467
Larry Hastings2f936352014-08-05 14:04:04 +10004468 #define PATH_UTIME_HAVE_FD 1
4469#else
4470 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004471#endif
4472
Victor Stinner5ebae872015-09-22 01:29:33 +02004473#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4474# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4475#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476
Victor Stinner4552ced2015-09-21 22:37:15 +02004477#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004478
4479static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004480utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004481{
4482#ifdef HAVE_UTIMENSAT
4483 UTIME_TO_TIMESPEC;
4484 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4485#else
4486 UTIME_TO_TIMEVAL;
4487 return lutimes(path, time);
4488#endif
4489}
4490
4491#endif
4492
4493#ifndef MS_WINDOWS
4494
4495static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004496utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497{
4498#ifdef HAVE_UTIMENSAT
4499 UTIME_TO_TIMESPEC;
4500 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4501#elif defined(HAVE_UTIMES)
4502 UTIME_TO_TIMEVAL;
4503 return utimes(path, time);
4504#elif defined(HAVE_UTIME_H)
4505 UTIME_TO_UTIMBUF;
4506 return utime(path, time);
4507#else
4508 UTIME_TO_TIME_T;
4509 return utime(path, time);
4510#endif
4511}
4512
4513#endif
4514
Larry Hastings76ad59b2012-05-03 00:30:07 -07004515static int
4516split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4517{
4518 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004519 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004520 divmod = PyNumber_Divmod(py_long, billion);
4521 if (!divmod)
4522 goto exit;
4523 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4524 if ((*s == -1) && PyErr_Occurred())
4525 goto exit;
4526 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004527 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004528 goto exit;
4529
4530 result = 1;
4531exit:
4532 Py_XDECREF(divmod);
4533 return result;
4534}
4535
Larry Hastings2f936352014-08-05 14:04:04 +10004536
4537/*[clinic input]
4538os.utime
4539
4540 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4541 times: object = NULL
4542 *
4543 ns: object = NULL
4544 dir_fd: dir_fd(requires='futimensat') = None
4545 follow_symlinks: bool=True
4546
Martin Panter0ff89092015-09-09 01:56:53 +00004547# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004548
4549Set the access and modified time of path.
4550
4551path may always be specified as a string.
4552On some platforms, path may also be specified as an open file descriptor.
4553 If this functionality is unavailable, using it raises an exception.
4554
4555If times is not None, it must be a tuple (atime, mtime);
4556 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004557If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004558 atime_ns and mtime_ns should be expressed as integer nanoseconds
4559 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004560If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004561Specifying tuples for both times and ns is an error.
4562
4563If dir_fd is not None, it should be a file descriptor open to a directory,
4564 and path should be relative; path will then be relative to that directory.
4565If follow_symlinks is False, and the last element of the path is a symbolic
4566 link, utime will modify the symbolic link itself instead of the file the
4567 link points to.
4568It is an error to use dir_fd or follow_symlinks when specifying path
4569 as an open file descriptor.
4570dir_fd and follow_symlinks may not be available on your platform.
4571 If they are unavailable, using them will raise a NotImplementedError.
4572
4573[clinic start generated code]*/
4574
Larry Hastings2f936352014-08-05 14:04:04 +10004575static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004576os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4577 int dir_fd, int follow_symlinks)
4578/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004579{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004580#ifdef MS_WINDOWS
4581 HANDLE hFile;
4582 FILETIME atime, mtime;
4583#else
4584 int result;
4585#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004586
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004588 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004589
Christian Heimesb3c87242013-08-01 00:08:16 +02004590 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004591
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 if (times && (times != Py_None) && ns) {
4593 PyErr_SetString(PyExc_ValueError,
4594 "utime: you may specify either 'times'"
4595 " or 'ns' but not both");
4596 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004597 }
4598
4599 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004600 time_t a_sec, m_sec;
4601 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004602 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 PyErr_SetString(PyExc_TypeError,
4604 "utime: 'times' must be either"
4605 " a tuple of two ints or None");
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 (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004610 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004611 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004612 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004614 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004615 utime.atime_s = a_sec;
4616 utime.atime_ns = a_nsec;
4617 utime.mtime_s = m_sec;
4618 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004619 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004621 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004622 PyErr_SetString(PyExc_TypeError,
4623 "utime: 'ns' must be a tuple of two ints");
4624 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004625 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004627 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004629 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 &utime.mtime_s, &utime.mtime_ns)) {
4631 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004632 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633 }
4634 else {
4635 /* times and ns are both None/unspecified. use "now". */
4636 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004637 }
4638
Victor Stinner4552ced2015-09-21 22:37:15 +02004639#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640 if (follow_symlinks_specified("utime", follow_symlinks))
4641 goto exit;
4642#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004643
Larry Hastings2f936352014-08-05 14:04:04 +10004644 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4645 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4646 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004648
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649#if !defined(HAVE_UTIMENSAT)
4650 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004651 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 "utime: cannot use dir_fd and follow_symlinks "
4653 "together on this platform");
4654 goto exit;
4655 }
4656#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004657
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004658#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004660 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4661 NULL, OPEN_EXISTING,
4662 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 Py_END_ALLOW_THREADS
4664 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004665 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004666 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004667 }
4668
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004670 GetSystemTimeAsFileTime(&mtime);
4671 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004672 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004673 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004674 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4675 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004676 }
4677 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4678 /* Avoid putting the file name into the error here,
4679 as that may confuse the user into believing that
4680 something is wrong with the file, when it also
4681 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004682 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004684 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004685#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004687
Victor Stinner4552ced2015-09-21 22:37:15 +02004688#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004690 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004691 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004692#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693
Victor Stinner528a9ab2015-09-03 21:30:26 +02004694#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004696 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697 else
4698#endif
4699
Victor Stinner528a9ab2015-09-03 21:30:26 +02004700#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004701 if (path->fd != -1)
4702 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 else
4704#endif
4705
Larry Hastings2f936352014-08-05 14:04:04 +10004706 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707
4708 Py_END_ALLOW_THREADS
4709
4710 if (result < 0) {
4711 /* see previous comment about not putting filename in error here */
4712 return_value = posix_error();
4713 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004714 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004715
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004716#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717
4718 Py_INCREF(Py_None);
4719 return_value = Py_None;
4720
4721exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722#ifdef MS_WINDOWS
4723 if (hFile != INVALID_HANDLE_VALUE)
4724 CloseHandle(hFile);
4725#endif
4726 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004727}
4728
Guido van Rossum3b066191991-06-04 19:40:25 +00004729/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004730
Larry Hastings2f936352014-08-05 14:04:04 +10004731
4732/*[clinic input]
4733os._exit
4734
4735 status: int
4736
4737Exit to the system with specified status, without normal exit processing.
4738[clinic start generated code]*/
4739
Larry Hastings2f936352014-08-05 14:04:04 +10004740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004741os__exit_impl(PyObject *module, int status)
4742/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004743{
4744 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004746}
4747
Steve Dowercc16be82016-09-08 10:35:16 -07004748#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4749#define EXECV_CHAR wchar_t
4750#else
4751#define EXECV_CHAR char
4752#endif
4753
Martin v. Löwis114619e2002-10-07 06:44:21 +00004754#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4755static void
Steve Dowercc16be82016-09-08 10:35:16 -07004756free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004757{
Victor Stinner8c62be82010-05-06 00:08:46 +00004758 Py_ssize_t i;
4759 for (i = 0; i < count; i++)
4760 PyMem_Free(array[i]);
4761 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004762}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004763
Antoine Pitrou69f71142009-05-24 21:25:49 +00004764static
Steve Dowercc16be82016-09-08 10:35:16 -07004765int fsconvert_strdup(PyObject *o, EXECV_CHAR**out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004766{
Victor Stinner8c62be82010-05-06 00:08:46 +00004767 Py_ssize_t size;
Steve Dowercc16be82016-09-08 10:35:16 -07004768#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4769 *out = PyUnicode_AsWideCharString(o, &size);
4770 if (!*out)
4771 return 0;
4772#else
4773 PyObject *bytes;
Victor Stinner8c62be82010-05-06 00:08:46 +00004774 if (!PyUnicode_FSConverter(o, &bytes))
4775 return 0;
4776 size = PyBytes_GET_SIZE(bytes);
4777 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004778 if (!*out) {
4779 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004781 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 memcpy(*out, PyBytes_AsString(bytes), size+1);
4783 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07004784#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004786}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004787#endif
4788
Ross Lagerwall7807c352011-03-17 20:20:30 +02004789#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004790static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004791parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4792{
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 Py_ssize_t i, pos, envc;
4794 PyObject *keys=NULL, *vals=NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004795 PyObject *key, *val, *keyval;
4796 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004797
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 i = PyMapping_Size(env);
4799 if (i < 0)
4800 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004801 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 if (envlist == NULL) {
4803 PyErr_NoMemory();
4804 return NULL;
4805 }
4806 envc = 0;
4807 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004808 if (!keys)
4809 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004811 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 goto error;
4813 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4814 PyErr_Format(PyExc_TypeError,
4815 "env.keys() or env.values() is not a list");
4816 goto error;
4817 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004818
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 for (pos = 0; pos < i; pos++) {
4820 key = PyList_GetItem(keys, pos);
4821 val = PyList_GetItem(vals, pos);
4822 if (!key || !val)
4823 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004824
Steve Dowercc16be82016-09-08 10:35:16 -07004825 keyval = PyUnicode_FromFormat("%U=%U", key, val);
4826 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004827 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004828
4829 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4830 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 goto error;
4832 }
Steve Dowercc16be82016-09-08 10:35:16 -07004833
4834 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 }
4836 Py_DECREF(vals);
4837 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004838
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 envlist[envc] = 0;
4840 *envc_ptr = envc;
4841 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004842
4843error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004844 Py_XDECREF(keys);
4845 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004846 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004848}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004849
Steve Dowercc16be82016-09-08 10:35:16 -07004850static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004851parse_arglist(PyObject* argv, Py_ssize_t *argc)
4852{
4853 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004854 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004855 if (argvlist == NULL) {
4856 PyErr_NoMemory();
4857 return NULL;
4858 }
4859 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004860 PyObject* item = PySequence_ITEM(argv, i);
4861 if (item == NULL)
4862 goto fail;
4863 if (!fsconvert_strdup(item, &argvlist[i])) {
4864 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004865 goto fail;
4866 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004867 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004868 }
4869 argvlist[*argc] = NULL;
4870 return argvlist;
4871fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004872 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004873 free_string_array(argvlist, *argc);
4874 return NULL;
4875}
Steve Dowercc16be82016-09-08 10:35:16 -07004876
Ross Lagerwall7807c352011-03-17 20:20:30 +02004877#endif
4878
Larry Hastings2f936352014-08-05 14:04:04 +10004879
Ross Lagerwall7807c352011-03-17 20:20:30 +02004880#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004881/*[clinic input]
4882os.execv
4883
Steve Dowercc16be82016-09-08 10:35:16 -07004884 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004885 Path of executable file.
4886 argv: object
4887 Tuple or list of strings.
4888 /
4889
4890Execute an executable path with arguments, replacing current process.
4891[clinic start generated code]*/
4892
Larry Hastings2f936352014-08-05 14:04:04 +10004893static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004894os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4895/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004896{
Steve Dowercc16be82016-09-08 10:35:16 -07004897 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898 Py_ssize_t argc;
4899
4900 /* execv has two arguments: (path, argv), where
4901 argv is a list or tuple of strings. */
4902
Ross Lagerwall7807c352011-03-17 20:20:30 +02004903 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4904 PyErr_SetString(PyExc_TypeError,
4905 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004906 return NULL;
4907 }
4908 argc = PySequence_Size(argv);
4909 if (argc < 1) {
4910 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004911 return NULL;
4912 }
4913
4914 argvlist = parse_arglist(argv, &argc);
4915 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004916 return NULL;
4917 }
4918
Steve Dowercc16be82016-09-08 10:35:16 -07004919#ifdef HAVE_WEXECV
4920 _wexecv(path->wide, argvlist);
4921#else
4922 execv(path->narrow, argvlist);
4923#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004924
4925 /* If we get here it's definitely an error */
4926
4927 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004928 return posix_error();
4929}
4930
Larry Hastings2f936352014-08-05 14:04:04 +10004931
4932/*[clinic input]
4933os.execve
4934
4935 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4936 Path of executable file.
4937 argv: object
4938 Tuple or list of strings.
4939 env: object
4940 Dictionary of strings mapping to strings.
4941
4942Execute an executable path with arguments, replacing current process.
4943[clinic start generated code]*/
4944
Larry Hastings2f936352014-08-05 14:04:04 +10004945static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004946os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4947/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004948{
Steve Dowercc16be82016-09-08 10:35:16 -07004949 EXECV_CHAR **argvlist = NULL;
4950 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004951 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004952
Victor Stinner8c62be82010-05-06 00:08:46 +00004953 /* execve has three arguments: (path, argv, env), where
4954 argv is a list or tuple of strings and env is a dictionary
4955 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004956
Ross Lagerwall7807c352011-03-17 20:20:30 +02004957 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004958 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004959 "execve: argv must be a tuple or list");
4960 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004963 if (!PyMapping_Check(env)) {
4964 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965 "execve: environment must be a mapping object");
4966 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004968
Ross Lagerwall7807c352011-03-17 20:20:30 +02004969 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004973
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 envlist = parse_envlist(env, &envc);
4975 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004976 goto fail;
4977
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10004979 if (path->fd > -1)
4980 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004981 else
4982#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004983#ifdef HAVE_WEXECV
4984 _wexecve(path->wide, argvlist, envlist);
4985#else
Larry Hastings2f936352014-08-05 14:04:04 +10004986 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07004987#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004988
4989 /* If we get here it's definitely an error */
4990
Larry Hastings2f936352014-08-05 14:04:04 +10004991 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004992
Steve Dowercc16be82016-09-08 10:35:16 -07004993 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004994 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004995 if (argvlist)
4996 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 return NULL;
4998}
Steve Dowercc16be82016-09-08 10:35:16 -07004999
Larry Hastings9cf065c2012-06-22 16:30:09 -07005000#endif /* HAVE_EXECV */
5001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005002
Steve Dowercc16be82016-09-08 10:35:16 -07005003#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005004/*[clinic input]
5005os.spawnv
5006
5007 mode: int
5008 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005009 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005010 Path of executable file.
5011 argv: object
5012 Tuple or list of strings.
5013 /
5014
5015Execute the program specified by path in a new process.
5016[clinic start generated code]*/
5017
Larry Hastings2f936352014-08-05 14:04:04 +10005018static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005019os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5020/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005021{
Steve Dowercc16be82016-09-08 10:35:16 -07005022 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005023 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005025 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005026 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005027
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 /* spawnv has three arguments: (mode, path, argv), where
5029 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005030
Victor Stinner8c62be82010-05-06 00:08:46 +00005031 if (PyList_Check(argv)) {
5032 argc = PyList_Size(argv);
5033 getitem = PyList_GetItem;
5034 }
5035 else if (PyTuple_Check(argv)) {
5036 argc = PyTuple_Size(argv);
5037 getitem = PyTuple_GetItem;
5038 }
5039 else {
5040 PyErr_SetString(PyExc_TypeError,
5041 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005042 return NULL;
5043 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005044
Steve Dowercc16be82016-09-08 10:35:16 -07005045 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005047 return PyErr_NoMemory();
5048 }
5049 for (i = 0; i < argc; i++) {
5050 if (!fsconvert_strdup((*getitem)(argv, i),
5051 &argvlist[i])) {
5052 free_string_array(argvlist, i);
5053 PyErr_SetString(
5054 PyExc_TypeError,
5055 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005056 return NULL;
5057 }
5058 }
5059 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005060
Victor Stinner8c62be82010-05-06 00:08:46 +00005061 if (mode == _OLD_P_OVERLAY)
5062 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005063
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005065#ifdef HAVE_WSPAWNV
5066 spawnval = _wspawnv(mode, path->wide, argvlist);
5067#else
5068 spawnval = _spawnv(mode, path->narrow, argvlist);
5069#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005071
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005073
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 if (spawnval == -1)
5075 return posix_error();
5076 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005077 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005078}
5079
5080
Larry Hastings2f936352014-08-05 14:04:04 +10005081/*[clinic input]
5082os.spawnve
5083
5084 mode: int
5085 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005086 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005087 Path of executable file.
5088 argv: object
5089 Tuple or list of strings.
5090 env: object
5091 Dictionary of strings mapping to strings.
5092 /
5093
5094Execute the program specified by path in a new process.
5095[clinic start generated code]*/
5096
Larry Hastings2f936352014-08-05 14:04:04 +10005097static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005098os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005099 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005100/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005101{
Steve Dowercc16be82016-09-08 10:35:16 -07005102 EXECV_CHAR **argvlist;
5103 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005105 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005106 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5108 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005109
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 /* spawnve has four arguments: (mode, path, argv, env), where
5111 argv is a list or tuple of strings and env is a dictionary
5112 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 if (PyList_Check(argv)) {
5115 argc = PyList_Size(argv);
5116 getitem = PyList_GetItem;
5117 }
5118 else if (PyTuple_Check(argv)) {
5119 argc = PyTuple_Size(argv);
5120 getitem = PyTuple_GetItem;
5121 }
5122 else {
5123 PyErr_SetString(PyExc_TypeError,
5124 "spawnve() arg 2 must be a tuple or list");
5125 goto fail_0;
5126 }
5127 if (!PyMapping_Check(env)) {
5128 PyErr_SetString(PyExc_TypeError,
5129 "spawnve() arg 3 must be a mapping object");
5130 goto fail_0;
5131 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005132
Steve Dowercc16be82016-09-08 10:35:16 -07005133 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 if (argvlist == NULL) {
5135 PyErr_NoMemory();
5136 goto fail_0;
5137 }
5138 for (i = 0; i < argc; i++) {
5139 if (!fsconvert_strdup((*getitem)(argv, i),
5140 &argvlist[i]))
5141 {
5142 lastarg = i;
5143 goto fail_1;
5144 }
5145 }
5146 lastarg = argc;
5147 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005148
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 envlist = parse_envlist(env, &envc);
5150 if (envlist == NULL)
5151 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005152
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (mode == _OLD_P_OVERLAY)
5154 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005155
Victor Stinner8c62be82010-05-06 00:08:46 +00005156 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005157#ifdef HAVE_WSPAWNV
5158 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5159#else
5160 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5161#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005163
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 if (spawnval == -1)
5165 (void) posix_error();
5166 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005167 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005168
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 while (--envc >= 0)
5170 PyMem_DEL(envlist[envc]);
5171 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005172 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005174 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005176}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005177
Guido van Rossuma1065681999-01-25 23:20:23 +00005178#endif /* HAVE_SPAWNV */
5179
5180
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005181#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005182/*[clinic input]
5183os.fork1
5184
5185Fork a child process with a single multiplexed (i.e., not bound) thread.
5186
5187Return 0 to child process and PID of child to parent process.
5188[clinic start generated code]*/
5189
Larry Hastings2f936352014-08-05 14:04:04 +10005190static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005191os_fork1_impl(PyObject *module)
5192/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005193{
Victor Stinner8c62be82010-05-06 00:08:46 +00005194 pid_t pid;
5195 int result = 0;
5196 _PyImport_AcquireLock();
5197 pid = fork1();
5198 if (pid == 0) {
5199 /* child: this clobbers and resets the import lock. */
5200 PyOS_AfterFork();
5201 } else {
5202 /* parent: release the import lock. */
5203 result = _PyImport_ReleaseLock();
5204 }
5205 if (pid == -1)
5206 return posix_error();
5207 if (result < 0) {
5208 /* Don't clobber the OSError if the fork failed. */
5209 PyErr_SetString(PyExc_RuntimeError,
5210 "not holding the import lock");
5211 return NULL;
5212 }
5213 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005214}
Larry Hastings2f936352014-08-05 14:04:04 +10005215#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005216
5217
Guido van Rossumad0ee831995-03-01 10:34:45 +00005218#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005219/*[clinic input]
5220os.fork
5221
5222Fork a child process.
5223
5224Return 0 to child process and PID of child to parent process.
5225[clinic start generated code]*/
5226
Larry Hastings2f936352014-08-05 14:04:04 +10005227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005228os_fork_impl(PyObject *module)
5229/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005230{
Victor Stinner8c62be82010-05-06 00:08:46 +00005231 pid_t pid;
5232 int result = 0;
5233 _PyImport_AcquireLock();
5234 pid = fork();
5235 if (pid == 0) {
5236 /* child: this clobbers and resets the import lock. */
5237 PyOS_AfterFork();
5238 } else {
5239 /* parent: release the import lock. */
5240 result = _PyImport_ReleaseLock();
5241 }
5242 if (pid == -1)
5243 return posix_error();
5244 if (result < 0) {
5245 /* Don't clobber the OSError if the fork failed. */
5246 PyErr_SetString(PyExc_RuntimeError,
5247 "not holding the import lock");
5248 return NULL;
5249 }
5250 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005251}
Larry Hastings2f936352014-08-05 14:04:04 +10005252#endif /* HAVE_FORK */
5253
Guido van Rossum85e3b011991-06-03 12:42:10 +00005254
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005255#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005256#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005257/*[clinic input]
5258os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005259
Larry Hastings2f936352014-08-05 14:04:04 +10005260 policy: int
5261
5262Get the maximum scheduling priority for policy.
5263[clinic start generated code]*/
5264
Larry Hastings2f936352014-08-05 14:04:04 +10005265static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005266os_sched_get_priority_max_impl(PyObject *module, int policy)
5267/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005268{
5269 int max;
5270
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005271 max = sched_get_priority_max(policy);
5272 if (max < 0)
5273 return posix_error();
5274 return PyLong_FromLong(max);
5275}
5276
Larry Hastings2f936352014-08-05 14:04:04 +10005277
5278/*[clinic input]
5279os.sched_get_priority_min
5280
5281 policy: int
5282
5283Get the minimum scheduling priority for policy.
5284[clinic start generated code]*/
5285
Larry Hastings2f936352014-08-05 14:04:04 +10005286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005287os_sched_get_priority_min_impl(PyObject *module, int policy)
5288/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005289{
5290 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005291 if (min < 0)
5292 return posix_error();
5293 return PyLong_FromLong(min);
5294}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005295#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5296
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005297
Larry Hastings2f936352014-08-05 14:04:04 +10005298#ifdef HAVE_SCHED_SETSCHEDULER
5299/*[clinic input]
5300os.sched_getscheduler
5301 pid: pid_t
5302 /
5303
5304Get the scheduling policy for the process identifiedy by pid.
5305
5306Passing 0 for pid returns the scheduling policy for the calling process.
5307[clinic start generated code]*/
5308
Larry Hastings2f936352014-08-05 14:04:04 +10005309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005310os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5311/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005312{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005313 int policy;
5314
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005315 policy = sched_getscheduler(pid);
5316 if (policy < 0)
5317 return posix_error();
5318 return PyLong_FromLong(policy);
5319}
Larry Hastings2f936352014-08-05 14:04:04 +10005320#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005321
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005322
5323#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005324/*[clinic input]
5325class os.sched_param "PyObject *" "&SchedParamType"
5326
5327@classmethod
5328os.sched_param.__new__
5329
5330 sched_priority: object
5331 A scheduling parameter.
5332
5333Current has only one field: sched_priority");
5334[clinic start generated code]*/
5335
Larry Hastings2f936352014-08-05 14:04:04 +10005336static PyObject *
5337os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005338/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005339{
5340 PyObject *res;
5341
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005342 res = PyStructSequence_New(type);
5343 if (!res)
5344 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005345 Py_INCREF(sched_priority);
5346 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005347 return res;
5348}
5349
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005350
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005351PyDoc_VAR(os_sched_param__doc__);
5352
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005353static PyStructSequence_Field sched_param_fields[] = {
5354 {"sched_priority", "the scheduling priority"},
5355 {0}
5356};
5357
5358static PyStructSequence_Desc sched_param_desc = {
5359 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005360 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005361 sched_param_fields,
5362 1
5363};
5364
5365static int
5366convert_sched_param(PyObject *param, struct sched_param *res)
5367{
5368 long priority;
5369
5370 if (Py_TYPE(param) != &SchedParamType) {
5371 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5372 return 0;
5373 }
5374 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5375 if (priority == -1 && PyErr_Occurred())
5376 return 0;
5377 if (priority > INT_MAX || priority < INT_MIN) {
5378 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5379 return 0;
5380 }
5381 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5382 return 1;
5383}
Larry Hastings2f936352014-08-05 14:04:04 +10005384#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005385
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005386
5387#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005388/*[clinic input]
5389os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005390
Larry Hastings2f936352014-08-05 14:04:04 +10005391 pid: pid_t
5392 policy: int
5393 param: sched_param
5394 /
5395
5396Set the scheduling policy for the process identified by pid.
5397
5398If pid is 0, the calling process is changed.
5399param is an instance of sched_param.
5400[clinic start generated code]*/
5401
Larry Hastings2f936352014-08-05 14:04:04 +10005402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005403os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005404 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005405/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005406{
Jesus Cea9c822272011-09-10 01:40:52 +02005407 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005408 ** sched_setscheduler() returns 0 in Linux, but the previous
5409 ** scheduling policy under Solaris/Illumos, and others.
5410 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005411 */
Larry Hastings2f936352014-08-05 14:04:04 +10005412 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005413 return posix_error();
5414 Py_RETURN_NONE;
5415}
Larry Hastings2f936352014-08-05 14:04:04 +10005416#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005417
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005418
5419#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005420/*[clinic input]
5421os.sched_getparam
5422 pid: pid_t
5423 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005424
Larry Hastings2f936352014-08-05 14:04:04 +10005425Returns scheduling parameters for the process identified by pid.
5426
5427If pid is 0, returns parameters for the calling process.
5428Return value is an instance of sched_param.
5429[clinic start generated code]*/
5430
Larry Hastings2f936352014-08-05 14:04:04 +10005431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005432os_sched_getparam_impl(PyObject *module, pid_t pid)
5433/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005434{
5435 struct sched_param param;
5436 PyObject *result;
5437 PyObject *priority;
5438
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005439 if (sched_getparam(pid, &param))
5440 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005441 result = PyStructSequence_New(&SchedParamType);
5442 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005443 return NULL;
5444 priority = PyLong_FromLong(param.sched_priority);
5445 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005446 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005447 return NULL;
5448 }
Larry Hastings2f936352014-08-05 14:04:04 +10005449 PyStructSequence_SET_ITEM(result, 0, priority);
5450 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005451}
5452
Larry Hastings2f936352014-08-05 14:04:04 +10005453
5454/*[clinic input]
5455os.sched_setparam
5456 pid: pid_t
5457 param: sched_param
5458 /
5459
5460Set scheduling parameters for the process identified by pid.
5461
5462If pid is 0, sets parameters for the calling process.
5463param should be an instance of sched_param.
5464[clinic start generated code]*/
5465
Larry Hastings2f936352014-08-05 14:04:04 +10005466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005467os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005468 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005469/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005470{
5471 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005472 return posix_error();
5473 Py_RETURN_NONE;
5474}
Larry Hastings2f936352014-08-05 14:04:04 +10005475#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005476
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005477
5478#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005479/*[clinic input]
5480os.sched_rr_get_interval -> double
5481 pid: pid_t
5482 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005483
Larry Hastings2f936352014-08-05 14:04:04 +10005484Return the round-robin quantum for the process identified by pid, in seconds.
5485
5486Value returned is a float.
5487[clinic start generated code]*/
5488
Larry Hastings2f936352014-08-05 14:04:04 +10005489static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005490os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5491/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005492{
5493 struct timespec interval;
5494 if (sched_rr_get_interval(pid, &interval)) {
5495 posix_error();
5496 return -1.0;
5497 }
5498 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5499}
5500#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005501
Larry Hastings2f936352014-08-05 14:04:04 +10005502
5503/*[clinic input]
5504os.sched_yield
5505
5506Voluntarily relinquish the CPU.
5507[clinic start generated code]*/
5508
Larry Hastings2f936352014-08-05 14:04:04 +10005509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005510os_sched_yield_impl(PyObject *module)
5511/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005512{
5513 if (sched_yield())
5514 return posix_error();
5515 Py_RETURN_NONE;
5516}
5517
Benjamin Peterson2740af82011-08-02 17:41:34 -05005518#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005519/* The minimum number of CPUs allocated in a cpu_set_t */
5520static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005521
Larry Hastings2f936352014-08-05 14:04:04 +10005522/*[clinic input]
5523os.sched_setaffinity
5524 pid: pid_t
5525 mask : object
5526 /
5527
5528Set the CPU affinity of the process identified by pid to mask.
5529
5530mask should be an iterable of integers identifying CPUs.
5531[clinic start generated code]*/
5532
Larry Hastings2f936352014-08-05 14:04:04 +10005533static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005534os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5535/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005536{
Antoine Pitrou84869872012-08-04 16:16:35 +02005537 int ncpus;
5538 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005539 cpu_set_t *cpu_set = NULL;
5540 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005541
Larry Hastings2f936352014-08-05 14:04:04 +10005542 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005543 if (iterator == NULL)
5544 return NULL;
5545
5546 ncpus = NCPUS_START;
5547 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005548 cpu_set = CPU_ALLOC(ncpus);
5549 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005550 PyErr_NoMemory();
5551 goto error;
5552 }
Larry Hastings2f936352014-08-05 14:04:04 +10005553 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005554
5555 while ((item = PyIter_Next(iterator))) {
5556 long cpu;
5557 if (!PyLong_Check(item)) {
5558 PyErr_Format(PyExc_TypeError,
5559 "expected an iterator of ints, "
5560 "but iterator yielded %R",
5561 Py_TYPE(item));
5562 Py_DECREF(item);
5563 goto error;
5564 }
5565 cpu = PyLong_AsLong(item);
5566 Py_DECREF(item);
5567 if (cpu < 0) {
5568 if (!PyErr_Occurred())
5569 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5570 goto error;
5571 }
5572 if (cpu > INT_MAX - 1) {
5573 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5574 goto error;
5575 }
5576 if (cpu >= ncpus) {
5577 /* Grow CPU mask to fit the CPU number */
5578 int newncpus = ncpus;
5579 cpu_set_t *newmask;
5580 size_t newsetsize;
5581 while (newncpus <= cpu) {
5582 if (newncpus > INT_MAX / 2)
5583 newncpus = cpu + 1;
5584 else
5585 newncpus = newncpus * 2;
5586 }
5587 newmask = CPU_ALLOC(newncpus);
5588 if (newmask == NULL) {
5589 PyErr_NoMemory();
5590 goto error;
5591 }
5592 newsetsize = CPU_ALLOC_SIZE(newncpus);
5593 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005594 memcpy(newmask, cpu_set, setsize);
5595 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005596 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005597 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005598 ncpus = newncpus;
5599 }
Larry Hastings2f936352014-08-05 14:04:04 +10005600 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005601 }
5602 Py_CLEAR(iterator);
5603
Larry Hastings2f936352014-08-05 14:04:04 +10005604 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005605 posix_error();
5606 goto error;
5607 }
Larry Hastings2f936352014-08-05 14:04:04 +10005608 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005609 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005610
5611error:
Larry Hastings2f936352014-08-05 14:04:04 +10005612 if (cpu_set)
5613 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005614 Py_XDECREF(iterator);
5615 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005616}
5617
Larry Hastings2f936352014-08-05 14:04:04 +10005618
5619/*[clinic input]
5620os.sched_getaffinity
5621 pid: pid_t
5622 /
5623
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005624Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005625
5626The affinity is returned as a set of CPU identifiers.
5627[clinic start generated code]*/
5628
Larry Hastings2f936352014-08-05 14:04:04 +10005629static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005630os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005631/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005632{
Antoine Pitrou84869872012-08-04 16:16:35 +02005633 int cpu, ncpus, count;
5634 size_t setsize;
5635 cpu_set_t *mask = NULL;
5636 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637
Antoine Pitrou84869872012-08-04 16:16:35 +02005638 ncpus = NCPUS_START;
5639 while (1) {
5640 setsize = CPU_ALLOC_SIZE(ncpus);
5641 mask = CPU_ALLOC(ncpus);
5642 if (mask == NULL)
5643 return PyErr_NoMemory();
5644 if (sched_getaffinity(pid, setsize, mask) == 0)
5645 break;
5646 CPU_FREE(mask);
5647 if (errno != EINVAL)
5648 return posix_error();
5649 if (ncpus > INT_MAX / 2) {
5650 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5651 "a large enough CPU set");
5652 return NULL;
5653 }
5654 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005655 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005656
5657 res = PySet_New(NULL);
5658 if (res == NULL)
5659 goto error;
5660 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5661 if (CPU_ISSET_S(cpu, setsize, mask)) {
5662 PyObject *cpu_num = PyLong_FromLong(cpu);
5663 --count;
5664 if (cpu_num == NULL)
5665 goto error;
5666 if (PySet_Add(res, cpu_num)) {
5667 Py_DECREF(cpu_num);
5668 goto error;
5669 }
5670 Py_DECREF(cpu_num);
5671 }
5672 }
5673 CPU_FREE(mask);
5674 return res;
5675
5676error:
5677 if (mask)
5678 CPU_FREE(mask);
5679 Py_XDECREF(res);
5680 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005681}
5682
Benjamin Peterson2740af82011-08-02 17:41:34 -05005683#endif /* HAVE_SCHED_SETAFFINITY */
5684
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005685#endif /* HAVE_SCHED_H */
5686
Larry Hastings2f936352014-08-05 14:04:04 +10005687
Neal Norwitzb59798b2003-03-21 01:43:31 +00005688/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005689/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5690#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005691#define DEV_PTY_FILE "/dev/ptc"
5692#define HAVE_DEV_PTMX
5693#else
5694#define DEV_PTY_FILE "/dev/ptmx"
5695#endif
5696
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005697#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005698#ifdef HAVE_PTY_H
5699#include <pty.h>
5700#else
5701#ifdef HAVE_LIBUTIL_H
5702#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005703#else
5704#ifdef HAVE_UTIL_H
5705#include <util.h>
5706#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005707#endif /* HAVE_LIBUTIL_H */
5708#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005709#ifdef HAVE_STROPTS_H
5710#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005711#endif
5712#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005713
Larry Hastings2f936352014-08-05 14:04:04 +10005714
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005715#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005716/*[clinic input]
5717os.openpty
5718
5719Open a pseudo-terminal.
5720
5721Return a tuple of (master_fd, slave_fd) containing open file descriptors
5722for both the master and slave ends.
5723[clinic start generated code]*/
5724
Larry Hastings2f936352014-08-05 14:04:04 +10005725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005726os_openpty_impl(PyObject *module)
5727/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005728{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005729 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005730#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005731 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005732#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005733#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005734 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005735#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005737#endif
5738#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005739
Thomas Wouters70c21a12000-07-14 14:28:33 +00005740#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005742 goto posix_error;
5743
5744 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5745 goto error;
5746 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5747 goto error;
5748
Neal Norwitzb59798b2003-03-21 01:43:31 +00005749#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005750 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5751 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005752 goto posix_error;
5753 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5754 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005755
Victor Stinnerdaf45552013-08-28 00:53:59 +02005756 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005757 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005758 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005759
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005760#else
Victor Stinner000de532013-11-25 23:19:58 +01005761 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005762 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005763 goto posix_error;
5764
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005766
Victor Stinner8c62be82010-05-06 00:08:46 +00005767 /* change permission of slave */
5768 if (grantpt(master_fd) < 0) {
5769 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005770 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005771 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005772
Victor Stinner8c62be82010-05-06 00:08:46 +00005773 /* unlock slave */
5774 if (unlockpt(master_fd) < 0) {
5775 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005776 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005777 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005778
Victor Stinner8c62be82010-05-06 00:08:46 +00005779 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005780
Victor Stinner8c62be82010-05-06 00:08:46 +00005781 slave_name = ptsname(master_fd); /* get name of slave */
5782 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005783 goto posix_error;
5784
5785 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005786 if (slave_fd == -1)
5787 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005788
5789 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5790 goto posix_error;
5791
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005792#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005793 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5794 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005795#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005797#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005798#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005799#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005800
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005802
Victor Stinnerdaf45552013-08-28 00:53:59 +02005803posix_error:
5804 posix_error();
5805error:
5806 if (master_fd != -1)
5807 close(master_fd);
5808 if (slave_fd != -1)
5809 close(slave_fd);
5810 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005811}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005812#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005813
Larry Hastings2f936352014-08-05 14:04:04 +10005814
Fred Drake8cef4cf2000-06-28 16:40:38 +00005815#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005816/*[clinic input]
5817os.forkpty
5818
5819Fork a new process with a new pseudo-terminal as controlling tty.
5820
5821Returns a tuple of (pid, master_fd).
5822Like fork(), return pid of 0 to the child process,
5823and pid of child to the parent process.
5824To both, return fd of newly opened pseudo-terminal.
5825[clinic start generated code]*/
5826
Larry Hastings2f936352014-08-05 14:04:04 +10005827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005828os_forkpty_impl(PyObject *module)
5829/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005830{
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 int master_fd = -1, result = 0;
5832 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005833
Victor Stinner8c62be82010-05-06 00:08:46 +00005834 _PyImport_AcquireLock();
5835 pid = forkpty(&master_fd, NULL, NULL, NULL);
5836 if (pid == 0) {
5837 /* child: this clobbers and resets the import lock. */
5838 PyOS_AfterFork();
5839 } else {
5840 /* parent: release the import lock. */
5841 result = _PyImport_ReleaseLock();
5842 }
5843 if (pid == -1)
5844 return posix_error();
5845 if (result < 0) {
5846 /* Don't clobber the OSError if the fork failed. */
5847 PyErr_SetString(PyExc_RuntimeError,
5848 "not holding the import lock");
5849 return NULL;
5850 }
5851 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005852}
Larry Hastings2f936352014-08-05 14:04:04 +10005853#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005854
Ross Lagerwall7807c352011-03-17 20:20:30 +02005855
Guido van Rossumad0ee831995-03-01 10:34:45 +00005856#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005857/*[clinic input]
5858os.getegid
5859
5860Return the current process's effective group id.
5861[clinic start generated code]*/
5862
Larry Hastings2f936352014-08-05 14:04:04 +10005863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005864os_getegid_impl(PyObject *module)
5865/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005866{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005867 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005868}
Larry Hastings2f936352014-08-05 14:04:04 +10005869#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005871
Guido van Rossumad0ee831995-03-01 10:34:45 +00005872#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005873/*[clinic input]
5874os.geteuid
5875
5876Return the current process's effective user id.
5877[clinic start generated code]*/
5878
Larry Hastings2f936352014-08-05 14:04:04 +10005879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005880os_geteuid_impl(PyObject *module)
5881/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005882{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005883 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005884}
Larry Hastings2f936352014-08-05 14:04:04 +10005885#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005887
Guido van Rossumad0ee831995-03-01 10:34:45 +00005888#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005889/*[clinic input]
5890os.getgid
5891
5892Return the current process's group id.
5893[clinic start generated code]*/
5894
Larry Hastings2f936352014-08-05 14:04:04 +10005895static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005896os_getgid_impl(PyObject *module)
5897/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005898{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005899 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005900}
Larry Hastings2f936352014-08-05 14:04:04 +10005901#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005903
Larry Hastings2f936352014-08-05 14:04:04 +10005904/*[clinic input]
5905os.getpid
5906
5907Return the current process id.
5908[clinic start generated code]*/
5909
Larry Hastings2f936352014-08-05 14:04:04 +10005910static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005911os_getpid_impl(PyObject *module)
5912/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005913{
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005915}
5916
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005917#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005918
5919/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005920PyDoc_STRVAR(posix_getgrouplist__doc__,
5921"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5922Returns a list of groups to which a user belongs.\n\n\
5923 user: username to lookup\n\
5924 group: base group id of the user");
5925
5926static PyObject *
5927posix_getgrouplist(PyObject *self, PyObject *args)
5928{
5929#ifdef NGROUPS_MAX
5930#define MAX_GROUPS NGROUPS_MAX
5931#else
5932 /* defined to be 16 on Solaris7, so this should be a small number */
5933#define MAX_GROUPS 64
5934#endif
5935
5936 const char *user;
5937 int i, ngroups;
5938 PyObject *list;
5939#ifdef __APPLE__
5940 int *groups, basegid;
5941#else
5942 gid_t *groups, basegid;
5943#endif
5944 ngroups = MAX_GROUPS;
5945
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005946#ifdef __APPLE__
5947 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005948 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005949#else
5950 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5951 _Py_Gid_Converter, &basegid))
5952 return NULL;
5953#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005954
5955#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005956 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005957#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005958 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005959#endif
5960 if (groups == NULL)
5961 return PyErr_NoMemory();
5962
5963 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5964 PyMem_Del(groups);
5965 return posix_error();
5966 }
5967
5968 list = PyList_New(ngroups);
5969 if (list == NULL) {
5970 PyMem_Del(groups);
5971 return NULL;
5972 }
5973
5974 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005975#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005976 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005977#else
5978 PyObject *o = _PyLong_FromGid(groups[i]);
5979#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005980 if (o == NULL) {
5981 Py_DECREF(list);
5982 PyMem_Del(groups);
5983 return NULL;
5984 }
5985 PyList_SET_ITEM(list, i, o);
5986 }
5987
5988 PyMem_Del(groups);
5989
5990 return list;
5991}
Larry Hastings2f936352014-08-05 14:04:04 +10005992#endif /* HAVE_GETGROUPLIST */
5993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005994
Fred Drakec9680921999-12-13 16:37:25 +00005995#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10005996/*[clinic input]
5997os.getgroups
5998
5999Return list of supplemental group IDs for the process.
6000[clinic start generated code]*/
6001
Larry Hastings2f936352014-08-05 14:04:04 +10006002static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006003os_getgroups_impl(PyObject *module)
6004/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006005{
6006 PyObject *result = NULL;
6007
Fred Drakec9680921999-12-13 16:37:25 +00006008#ifdef NGROUPS_MAX
6009#define MAX_GROUPS NGROUPS_MAX
6010#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006012#define MAX_GROUPS 64
6013#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006015
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006016 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006017 * This is a helper variable to store the intermediate result when
6018 * that happens.
6019 *
6020 * To keep the code readable the OSX behaviour is unconditional,
6021 * according to the POSIX spec this should be safe on all unix-y
6022 * systems.
6023 */
6024 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006026
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006027#ifdef __APPLE__
6028 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6029 * there are more groups than can fit in grouplist. Therefore, on OS X
6030 * always first call getgroups with length 0 to get the actual number
6031 * of groups.
6032 */
6033 n = getgroups(0, NULL);
6034 if (n < 0) {
6035 return posix_error();
6036 } else if (n <= MAX_GROUPS) {
6037 /* groups will fit in existing array */
6038 alt_grouplist = grouplist;
6039 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006040 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006041 if (alt_grouplist == NULL) {
6042 errno = EINVAL;
6043 return posix_error();
6044 }
6045 }
6046
6047 n = getgroups(n, alt_grouplist);
6048 if (n == -1) {
6049 if (alt_grouplist != grouplist) {
6050 PyMem_Free(alt_grouplist);
6051 }
6052 return posix_error();
6053 }
6054#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006056 if (n < 0) {
6057 if (errno == EINVAL) {
6058 n = getgroups(0, NULL);
6059 if (n == -1) {
6060 return posix_error();
6061 }
6062 if (n == 0) {
6063 /* Avoid malloc(0) */
6064 alt_grouplist = grouplist;
6065 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006066 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006067 if (alt_grouplist == NULL) {
6068 errno = EINVAL;
6069 return posix_error();
6070 }
6071 n = getgroups(n, alt_grouplist);
6072 if (n == -1) {
6073 PyMem_Free(alt_grouplist);
6074 return posix_error();
6075 }
6076 }
6077 } else {
6078 return posix_error();
6079 }
6080 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006081#endif
6082
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006083 result = PyList_New(n);
6084 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 int i;
6086 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006087 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006088 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006089 Py_DECREF(result);
6090 result = NULL;
6091 break;
Fred Drakec9680921999-12-13 16:37:25 +00006092 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006094 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006095 }
6096
6097 if (alt_grouplist != grouplist) {
6098 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006099 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006100
Fred Drakec9680921999-12-13 16:37:25 +00006101 return result;
6102}
Larry Hastings2f936352014-08-05 14:04:04 +10006103#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006104
Antoine Pitroub7572f02009-12-02 20:46:48 +00006105#ifdef HAVE_INITGROUPS
6106PyDoc_STRVAR(posix_initgroups__doc__,
6107"initgroups(username, gid) -> None\n\n\
6108Call the system initgroups() to initialize the group access list with all of\n\
6109the groups of which the specified username is a member, plus the specified\n\
6110group id.");
6111
Larry Hastings2f936352014-08-05 14:04:04 +10006112/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006113static PyObject *
6114posix_initgroups(PyObject *self, PyObject *args)
6115{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006116 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006117 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006118 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006119#ifdef __APPLE__
6120 int gid;
6121#else
6122 gid_t gid;
6123#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006124
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006125#ifdef __APPLE__
6126 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6127 PyUnicode_FSConverter, &oname,
6128 &gid))
6129#else
6130 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6131 PyUnicode_FSConverter, &oname,
6132 _Py_Gid_Converter, &gid))
6133#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006135 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006136
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006137 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006138 Py_DECREF(oname);
6139 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006141
Victor Stinner8c62be82010-05-06 00:08:46 +00006142 Py_INCREF(Py_None);
6143 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006144}
Larry Hastings2f936352014-08-05 14:04:04 +10006145#endif /* HAVE_INITGROUPS */
6146
Antoine Pitroub7572f02009-12-02 20:46:48 +00006147
Martin v. Löwis606edc12002-06-13 21:09:11 +00006148#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006149/*[clinic input]
6150os.getpgid
6151
6152 pid: pid_t
6153
6154Call the system call getpgid(), and return the result.
6155[clinic start generated code]*/
6156
Larry Hastings2f936352014-08-05 14:04:04 +10006157static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006158os_getpgid_impl(PyObject *module, pid_t pid)
6159/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006160{
6161 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006162 if (pgid < 0)
6163 return posix_error();
6164 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006165}
6166#endif /* HAVE_GETPGID */
6167
6168
Guido van Rossumb6775db1994-08-01 11:34:53 +00006169#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006170/*[clinic input]
6171os.getpgrp
6172
6173Return the current process group id.
6174[clinic start generated code]*/
6175
Larry Hastings2f936352014-08-05 14:04:04 +10006176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006177os_getpgrp_impl(PyObject *module)
6178/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006179{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006180#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006182#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006184#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006185}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006186#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006188
Guido van Rossumb6775db1994-08-01 11:34:53 +00006189#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006190/*[clinic input]
6191os.setpgrp
6192
6193Make the current process the leader of its process group.
6194[clinic start generated code]*/
6195
Larry Hastings2f936352014-08-05 14:04:04 +10006196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006197os_setpgrp_impl(PyObject *module)
6198/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006199{
Guido van Rossum64933891994-10-20 21:56:42 +00006200#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006202#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006203 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006204#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 return posix_error();
6206 Py_INCREF(Py_None);
6207 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006208}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006209#endif /* HAVE_SETPGRP */
6210
Guido van Rossumad0ee831995-03-01 10:34:45 +00006211#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006212
6213#ifdef MS_WINDOWS
6214#include <tlhelp32.h>
6215
6216static PyObject*
6217win32_getppid()
6218{
6219 HANDLE snapshot;
6220 pid_t mypid;
6221 PyObject* result = NULL;
6222 BOOL have_record;
6223 PROCESSENTRY32 pe;
6224
6225 mypid = getpid(); /* This function never fails */
6226
6227 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6228 if (snapshot == INVALID_HANDLE_VALUE)
6229 return PyErr_SetFromWindowsErr(GetLastError());
6230
6231 pe.dwSize = sizeof(pe);
6232 have_record = Process32First(snapshot, &pe);
6233 while (have_record) {
6234 if (mypid == (pid_t)pe.th32ProcessID) {
6235 /* We could cache the ulong value in a static variable. */
6236 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6237 break;
6238 }
6239
6240 have_record = Process32Next(snapshot, &pe);
6241 }
6242
6243 /* If our loop exits and our pid was not found (result will be NULL)
6244 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6245 * error anyway, so let's raise it. */
6246 if (!result)
6247 result = PyErr_SetFromWindowsErr(GetLastError());
6248
6249 CloseHandle(snapshot);
6250
6251 return result;
6252}
6253#endif /*MS_WINDOWS*/
6254
Larry Hastings2f936352014-08-05 14:04:04 +10006255
6256/*[clinic input]
6257os.getppid
6258
6259Return the parent's process id.
6260
6261If the parent process has already exited, Windows machines will still
6262return its id; others systems will return the id of the 'init' process (1).
6263[clinic start generated code]*/
6264
Larry Hastings2f936352014-08-05 14:04:04 +10006265static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006266os_getppid_impl(PyObject *module)
6267/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006268{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006269#ifdef MS_WINDOWS
6270 return win32_getppid();
6271#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006273#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006274}
6275#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006277
Fred Drake12c6e2d1999-12-14 21:25:03 +00006278#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006279/*[clinic input]
6280os.getlogin
6281
6282Return the actual login name.
6283[clinic start generated code]*/
6284
Larry Hastings2f936352014-08-05 14:04:04 +10006285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006286os_getlogin_impl(PyObject *module)
6287/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006288{
Victor Stinner8c62be82010-05-06 00:08:46 +00006289 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006290#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006291 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006292 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006293
6294 if (GetUserNameW(user_name, &num_chars)) {
6295 /* num_chars is the number of unicode chars plus null terminator */
6296 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006297 }
6298 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006299 result = PyErr_SetFromWindowsErr(GetLastError());
6300#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 char *name;
6302 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006303
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 errno = 0;
6305 name = getlogin();
6306 if (name == NULL) {
6307 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006308 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006309 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006310 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 }
6312 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006313 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006315#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006316 return result;
6317}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006318#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006319
Larry Hastings2f936352014-08-05 14:04:04 +10006320
Guido van Rossumad0ee831995-03-01 10:34:45 +00006321#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006322/*[clinic input]
6323os.getuid
6324
6325Return the current process's user id.
6326[clinic start generated code]*/
6327
Larry Hastings2f936352014-08-05 14:04:04 +10006328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006329os_getuid_impl(PyObject *module)
6330/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006331{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006332 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006333}
Larry Hastings2f936352014-08-05 14:04:04 +10006334#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006335
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006336
Brian Curtineb24d742010-04-12 17:16:38 +00006337#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006338#define HAVE_KILL
6339#endif /* MS_WINDOWS */
6340
6341#ifdef HAVE_KILL
6342/*[clinic input]
6343os.kill
6344
6345 pid: pid_t
6346 signal: Py_ssize_t
6347 /
6348
6349Kill a process with a signal.
6350[clinic start generated code]*/
6351
Larry Hastings2f936352014-08-05 14:04:04 +10006352static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006353os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6354/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006355#ifndef MS_WINDOWS
6356{
6357 if (kill(pid, (int)signal) == -1)
6358 return posix_error();
6359 Py_RETURN_NONE;
6360}
6361#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006362{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006363 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006364 DWORD sig = (DWORD)signal;
6365 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006367
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 /* Console processes which share a common console can be sent CTRL+C or
6369 CTRL+BREAK events, provided they handle said events. */
6370 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006371 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 err = GetLastError();
6373 PyErr_SetFromWindowsErr(err);
6374 }
6375 else
6376 Py_RETURN_NONE;
6377 }
Brian Curtineb24d742010-04-12 17:16:38 +00006378
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6380 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006381 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 if (handle == NULL) {
6383 err = GetLastError();
6384 return PyErr_SetFromWindowsErr(err);
6385 }
Brian Curtineb24d742010-04-12 17:16:38 +00006386
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 if (TerminateProcess(handle, sig) == 0) {
6388 err = GetLastError();
6389 result = PyErr_SetFromWindowsErr(err);
6390 } else {
6391 Py_INCREF(Py_None);
6392 result = Py_None;
6393 }
Brian Curtineb24d742010-04-12 17:16:38 +00006394
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 CloseHandle(handle);
6396 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006397}
Larry Hastings2f936352014-08-05 14:04:04 +10006398#endif /* !MS_WINDOWS */
6399#endif /* HAVE_KILL */
6400
6401
6402#ifdef HAVE_KILLPG
6403/*[clinic input]
6404os.killpg
6405
6406 pgid: pid_t
6407 signal: int
6408 /
6409
6410Kill a process group with a signal.
6411[clinic start generated code]*/
6412
Larry Hastings2f936352014-08-05 14:04:04 +10006413static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006414os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6415/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006416{
6417 /* XXX some man pages make the `pgid` parameter an int, others
6418 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6419 take the same type. Moreover, pid_t is always at least as wide as
6420 int (else compilation of this module fails), which is safe. */
6421 if (killpg(pgid, signal) == -1)
6422 return posix_error();
6423 Py_RETURN_NONE;
6424}
6425#endif /* HAVE_KILLPG */
6426
Brian Curtineb24d742010-04-12 17:16:38 +00006427
Guido van Rossumc0125471996-06-28 18:55:32 +00006428#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006429#ifdef HAVE_SYS_LOCK_H
6430#include <sys/lock.h>
6431#endif
6432
Larry Hastings2f936352014-08-05 14:04:04 +10006433/*[clinic input]
6434os.plock
6435 op: int
6436 /
6437
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006438Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006439[clinic start generated code]*/
6440
Larry Hastings2f936352014-08-05 14:04:04 +10006441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006442os_plock_impl(PyObject *module, int op)
6443/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006444{
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 if (plock(op) == -1)
6446 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006447 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006448}
Larry Hastings2f936352014-08-05 14:04:04 +10006449#endif /* HAVE_PLOCK */
6450
Guido van Rossumc0125471996-06-28 18:55:32 +00006451
Guido van Rossumb6775db1994-08-01 11:34:53 +00006452#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006453/*[clinic input]
6454os.setuid
6455
6456 uid: uid_t
6457 /
6458
6459Set the current process's user id.
6460[clinic start generated code]*/
6461
Larry Hastings2f936352014-08-05 14:04:04 +10006462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006463os_setuid_impl(PyObject *module, uid_t uid)
6464/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006465{
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 if (setuid(uid) < 0)
6467 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006468 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006469}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006470#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006473#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006474/*[clinic input]
6475os.seteuid
6476
6477 euid: uid_t
6478 /
6479
6480Set the current process's effective user id.
6481[clinic start generated code]*/
6482
Larry Hastings2f936352014-08-05 14:04:04 +10006483static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006484os_seteuid_impl(PyObject *module, uid_t euid)
6485/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006486{
6487 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006489 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006490}
6491#endif /* HAVE_SETEUID */
6492
Larry Hastings2f936352014-08-05 14:04:04 +10006493
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006494#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006495/*[clinic input]
6496os.setegid
6497
6498 egid: gid_t
6499 /
6500
6501Set the current process's effective group id.
6502[clinic start generated code]*/
6503
Larry Hastings2f936352014-08-05 14:04:04 +10006504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006505os_setegid_impl(PyObject *module, gid_t egid)
6506/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006507{
6508 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006510 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006511}
6512#endif /* HAVE_SETEGID */
6513
Larry Hastings2f936352014-08-05 14:04:04 +10006514
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006515#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006516/*[clinic input]
6517os.setreuid
6518
6519 ruid: uid_t
6520 euid: uid_t
6521 /
6522
6523Set the current process's real and effective user ids.
6524[clinic start generated code]*/
6525
Larry Hastings2f936352014-08-05 14:04:04 +10006526static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006527os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6528/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006529{
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 if (setreuid(ruid, euid) < 0) {
6531 return posix_error();
6532 } else {
6533 Py_INCREF(Py_None);
6534 return Py_None;
6535 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006536}
6537#endif /* HAVE_SETREUID */
6538
Larry Hastings2f936352014-08-05 14:04:04 +10006539
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006540#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006541/*[clinic input]
6542os.setregid
6543
6544 rgid: gid_t
6545 egid: gid_t
6546 /
6547
6548Set the current process's real and effective group ids.
6549[clinic start generated code]*/
6550
Larry Hastings2f936352014-08-05 14:04:04 +10006551static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006552os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6553/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006554{
6555 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006557 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006558}
6559#endif /* HAVE_SETREGID */
6560
Larry Hastings2f936352014-08-05 14:04:04 +10006561
Guido van Rossumb6775db1994-08-01 11:34:53 +00006562#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006563/*[clinic input]
6564os.setgid
6565 gid: gid_t
6566 /
6567
6568Set the current process's group id.
6569[clinic start generated code]*/
6570
Larry Hastings2f936352014-08-05 14:04:04 +10006571static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006572os_setgid_impl(PyObject *module, gid_t gid)
6573/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006574{
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 if (setgid(gid) < 0)
6576 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006577 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006578}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006579#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006580
Larry Hastings2f936352014-08-05 14:04:04 +10006581
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006582#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006583/*[clinic input]
6584os.setgroups
6585
6586 groups: object
6587 /
6588
6589Set the groups of the current process to list.
6590[clinic start generated code]*/
6591
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006593os_setgroups(PyObject *module, PyObject *groups)
6594/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006595{
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 int i, len;
6597 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006598
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 if (!PySequence_Check(groups)) {
6600 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6601 return NULL;
6602 }
6603 len = PySequence_Size(groups);
6604 if (len > MAX_GROUPS) {
6605 PyErr_SetString(PyExc_ValueError, "too many groups");
6606 return NULL;
6607 }
6608 for(i = 0; i < len; i++) {
6609 PyObject *elem;
6610 elem = PySequence_GetItem(groups, i);
6611 if (!elem)
6612 return NULL;
6613 if (!PyLong_Check(elem)) {
6614 PyErr_SetString(PyExc_TypeError,
6615 "groups must be integers");
6616 Py_DECREF(elem);
6617 return NULL;
6618 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006619 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 Py_DECREF(elem);
6621 return NULL;
6622 }
6623 }
6624 Py_DECREF(elem);
6625 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006626
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 if (setgroups(len, grouplist) < 0)
6628 return posix_error();
6629 Py_INCREF(Py_None);
6630 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006631}
6632#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006633
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006634#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6635static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006636wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006637{
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 PyObject *result;
6639 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006640 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006641
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 if (pid == -1)
6643 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006644
Victor Stinner8c62be82010-05-06 00:08:46 +00006645 if (struct_rusage == NULL) {
6646 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6647 if (m == NULL)
6648 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006649 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 Py_DECREF(m);
6651 if (struct_rusage == NULL)
6652 return NULL;
6653 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006654
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6656 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6657 if (!result)
6658 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006659
6660#ifndef doubletime
6661#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6662#endif
6663
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006665 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006666 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006667 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006668#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6670 SET_INT(result, 2, ru->ru_maxrss);
6671 SET_INT(result, 3, ru->ru_ixrss);
6672 SET_INT(result, 4, ru->ru_idrss);
6673 SET_INT(result, 5, ru->ru_isrss);
6674 SET_INT(result, 6, ru->ru_minflt);
6675 SET_INT(result, 7, ru->ru_majflt);
6676 SET_INT(result, 8, ru->ru_nswap);
6677 SET_INT(result, 9, ru->ru_inblock);
6678 SET_INT(result, 10, ru->ru_oublock);
6679 SET_INT(result, 11, ru->ru_msgsnd);
6680 SET_INT(result, 12, ru->ru_msgrcv);
6681 SET_INT(result, 13, ru->ru_nsignals);
6682 SET_INT(result, 14, ru->ru_nvcsw);
6683 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006684#undef SET_INT
6685
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 if (PyErr_Occurred()) {
6687 Py_DECREF(result);
6688 return NULL;
6689 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006690
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006692}
6693#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6694
Larry Hastings2f936352014-08-05 14:04:04 +10006695
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006696#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006697/*[clinic input]
6698os.wait3
6699
6700 options: int
6701Wait for completion of a child process.
6702
6703Returns a tuple of information about the child process:
6704 (pid, status, rusage)
6705[clinic start generated code]*/
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006708os_wait3_impl(PyObject *module, int options)
6709/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006710{
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006713 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 WAIT_TYPE status;
6715 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006716
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006717 do {
6718 Py_BEGIN_ALLOW_THREADS
6719 pid = wait3(&status, options, &ru);
6720 Py_END_ALLOW_THREADS
6721 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6722 if (pid < 0)
6723 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006724
Victor Stinner4195b5c2012-02-08 23:03:19 +01006725 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006726}
6727#endif /* HAVE_WAIT3 */
6728
Larry Hastings2f936352014-08-05 14:04:04 +10006729
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006730#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006731/*[clinic input]
6732
6733os.wait4
6734
6735 pid: pid_t
6736 options: int
6737
6738Wait for completion of a specific child process.
6739
6740Returns a tuple of information about the child process:
6741 (pid, status, rusage)
6742[clinic start generated code]*/
6743
Larry Hastings2f936352014-08-05 14:04:04 +10006744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006745os_wait4_impl(PyObject *module, pid_t pid, int options)
6746/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006747{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006748 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006750 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 WAIT_TYPE status;
6752 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006753
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006754 do {
6755 Py_BEGIN_ALLOW_THREADS
6756 res = wait4(pid, &status, options, &ru);
6757 Py_END_ALLOW_THREADS
6758 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6759 if (res < 0)
6760 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006761
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006762 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006763}
6764#endif /* HAVE_WAIT4 */
6765
Larry Hastings2f936352014-08-05 14:04:04 +10006766
Ross Lagerwall7807c352011-03-17 20:20:30 +02006767#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006768/*[clinic input]
6769os.waitid
6770
6771 idtype: idtype_t
6772 Must be one of be P_PID, P_PGID or P_ALL.
6773 id: id_t
6774 The id to wait on.
6775 options: int
6776 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6777 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6778 /
6779
6780Returns the result of waiting for a process or processes.
6781
6782Returns either waitid_result or None if WNOHANG is specified and there are
6783no children in a waitable state.
6784[clinic start generated code]*/
6785
Larry Hastings2f936352014-08-05 14:04:04 +10006786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006787os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6788/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006789{
6790 PyObject *result;
6791 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006792 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006793 siginfo_t si;
6794 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006795
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006796 do {
6797 Py_BEGIN_ALLOW_THREADS
6798 res = waitid(idtype, id, &si, options);
6799 Py_END_ALLOW_THREADS
6800 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6801 if (res < 0)
6802 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006803
6804 if (si.si_pid == 0)
6805 Py_RETURN_NONE;
6806
6807 result = PyStructSequence_New(&WaitidResultType);
6808 if (!result)
6809 return NULL;
6810
6811 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006812 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006813 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6814 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6815 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6816 if (PyErr_Occurred()) {
6817 Py_DECREF(result);
6818 return NULL;
6819 }
6820
6821 return result;
6822}
Larry Hastings2f936352014-08-05 14:04:04 +10006823#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006824
Larry Hastings2f936352014-08-05 14:04:04 +10006825
6826#if defined(HAVE_WAITPID)
6827/*[clinic input]
6828os.waitpid
6829 pid: pid_t
6830 options: int
6831 /
6832
6833Wait for completion of a given child process.
6834
6835Returns a tuple of information regarding the child process:
6836 (pid, status)
6837
6838The options argument is ignored on Windows.
6839[clinic start generated code]*/
6840
Larry Hastings2f936352014-08-05 14:04:04 +10006841static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006842os_waitpid_impl(PyObject *module, pid_t pid, int options)
6843/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006844{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006845 pid_t res;
6846 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 WAIT_TYPE status;
6848 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006849
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006850 do {
6851 Py_BEGIN_ALLOW_THREADS
6852 res = waitpid(pid, &status, options);
6853 Py_END_ALLOW_THREADS
6854 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6855 if (res < 0)
6856 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006858 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006859}
Tim Petersab034fa2002-02-01 11:27:43 +00006860#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006861/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006862/*[clinic input]
6863os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006864 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006865 options: int
6866 /
6867
6868Wait for completion of a given process.
6869
6870Returns a tuple of information regarding the process:
6871 (pid, status << 8)
6872
6873The options argument is ignored on Windows.
6874[clinic start generated code]*/
6875
Larry Hastings2f936352014-08-05 14:04:04 +10006876static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006877os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006878/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006879{
6880 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006881 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006882 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006883
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006884 do {
6885 Py_BEGIN_ALLOW_THREADS
6886 res = _cwait(&status, pid, options);
6887 Py_END_ALLOW_THREADS
6888 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006889 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006890 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006893 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006894}
Larry Hastings2f936352014-08-05 14:04:04 +10006895#endif
6896
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006897
Guido van Rossumad0ee831995-03-01 10:34:45 +00006898#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006899/*[clinic input]
6900os.wait
6901
6902Wait for completion of a child process.
6903
6904Returns a tuple of information about the child process:
6905 (pid, status)
6906[clinic start generated code]*/
6907
Larry Hastings2f936352014-08-05 14:04:04 +10006908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006909os_wait_impl(PyObject *module)
6910/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006911{
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006913 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 WAIT_TYPE status;
6915 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006916
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006917 do {
6918 Py_BEGIN_ALLOW_THREADS
6919 pid = wait(&status);
6920 Py_END_ALLOW_THREADS
6921 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6922 if (pid < 0)
6923 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006926}
Larry Hastings2f936352014-08-05 14:04:04 +10006927#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006928
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006929
Larry Hastings9cf065c2012-06-22 16:30:09 -07006930#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6931PyDoc_STRVAR(readlink__doc__,
6932"readlink(path, *, dir_fd=None) -> path\n\n\
6933Return a string representing the path to which the symbolic link points.\n\
6934\n\
6935If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6936 and path should be relative; path will then be relative to that directory.\n\
6937dir_fd may not be implemented on your platform.\n\
6938 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006939#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006940
Guido van Rossumb6775db1994-08-01 11:34:53 +00006941#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006942
Larry Hastings2f936352014-08-05 14:04:04 +10006943/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006944static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006945posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006946{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006947 path_t path;
6948 int dir_fd = DEFAULT_DIR_FD;
6949 char buffer[MAXPATHLEN];
6950 ssize_t length;
6951 PyObject *return_value = NULL;
6952 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006953
Larry Hastings9cf065c2012-06-22 16:30:09 -07006954 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006955 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006956 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6957 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10006958 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006960
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006962#ifdef HAVE_READLINKAT
6963 if (dir_fd != DEFAULT_DIR_FD)
6964 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006965 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006966#endif
6967 length = readlink(path.narrow, buffer, sizeof(buffer));
6968 Py_END_ALLOW_THREADS
6969
6970 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006971 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006972 goto exit;
6973 }
6974
6975 if (PyUnicode_Check(path.object))
6976 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6977 else
6978 return_value = PyBytes_FromStringAndSize(buffer, length);
6979exit:
6980 path_cleanup(&path);
6981 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006982}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006983
Guido van Rossumb6775db1994-08-01 11:34:53 +00006984#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006985
Larry Hastings2f936352014-08-05 14:04:04 +10006986#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6987
6988static PyObject *
6989win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
6990{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006991 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10006992 DWORD n_bytes_returned;
6993 DWORD io_result;
6994 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006995 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10006996 HANDLE reparse_point_handle;
6997
Martin Panter70214ad2016-08-04 02:38:59 +00006998 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6999 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007000 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007001
7002 static char *keywords[] = {"path", "dir_fd", NULL};
7003
7004 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7005 &po,
7006 dir_fd_unavailable, &dir_fd
7007 ))
7008 return NULL;
7009
7010 path = PyUnicode_AsUnicode(po);
7011 if (path == NULL)
7012 return NULL;
7013
7014 /* First get a handle to the reparse point */
7015 Py_BEGIN_ALLOW_THREADS
7016 reparse_point_handle = CreateFileW(
7017 path,
7018 0,
7019 0,
7020 0,
7021 OPEN_EXISTING,
7022 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7023 0);
7024 Py_END_ALLOW_THREADS
7025
7026 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7027 return win32_error_object("readlink", po);
7028
7029 Py_BEGIN_ALLOW_THREADS
7030 /* New call DeviceIoControl to read the reparse point */
7031 io_result = DeviceIoControl(
7032 reparse_point_handle,
7033 FSCTL_GET_REPARSE_POINT,
7034 0, 0, /* in buffer */
7035 target_buffer, sizeof(target_buffer),
7036 &n_bytes_returned,
7037 0 /* we're not using OVERLAPPED_IO */
7038 );
7039 CloseHandle(reparse_point_handle);
7040 Py_END_ALLOW_THREADS
7041
7042 if (io_result==0)
7043 return win32_error_object("readlink", po);
7044
7045 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7046 {
7047 PyErr_SetString(PyExc_ValueError,
7048 "not a symbolic link");
7049 return NULL;
7050 }
7051 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7052 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7053
7054 result = PyUnicode_FromWideChar(print_name,
7055 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7056 return result;
7057}
7058
7059#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7060
7061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007062
Larry Hastings9cf065c2012-06-22 16:30:09 -07007063#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007064
7065#if defined(MS_WINDOWS)
7066
7067/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007068static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007069
Larry Hastings9cf065c2012-06-22 16:30:09 -07007070static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007071check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007072{
7073 HINSTANCE hKernel32;
7074 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007075 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007076 return 1;
7077 hKernel32 = GetModuleHandleW(L"KERNEL32");
7078 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7079 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007080 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007081}
7082
Victor Stinner31b3b922013-06-05 01:49:17 +02007083/* Remove the last portion of the path */
7084static void
7085_dirnameW(WCHAR *path)
7086{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007087 WCHAR *ptr;
7088
7089 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007090 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007091 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007092 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007093 }
7094 *ptr = 0;
7095}
7096
Victor Stinner31b3b922013-06-05 01:49:17 +02007097/* Is this path absolute? */
7098static int
7099_is_absW(const WCHAR *path)
7100{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007101 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7102
7103}
7104
Victor Stinner31b3b922013-06-05 01:49:17 +02007105/* join root and rest with a backslash */
7106static void
7107_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7108{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007109 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007110
Victor Stinner31b3b922013-06-05 01:49:17 +02007111 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007112 wcscpy(dest_path, rest);
7113 return;
7114 }
7115
7116 root_len = wcslen(root);
7117
7118 wcscpy(dest_path, root);
7119 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007120 dest_path[root_len] = L'\\';
7121 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007122 }
7123 wcscpy(dest_path+root_len, rest);
7124}
7125
Victor Stinner31b3b922013-06-05 01:49:17 +02007126/* Return True if the path at src relative to dest is a directory */
7127static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007128_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007129{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007130 WIN32_FILE_ATTRIBUTE_DATA src_info;
7131 WCHAR dest_parent[MAX_PATH];
7132 WCHAR src_resolved[MAX_PATH] = L"";
7133
7134 /* dest_parent = os.path.dirname(dest) */
7135 wcscpy(dest_parent, dest);
7136 _dirnameW(dest_parent);
7137 /* src_resolved = os.path.join(dest_parent, src) */
7138 _joinW(src_resolved, dest_parent, src);
7139 return (
7140 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7141 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7142 );
7143}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007144#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007145
Larry Hastings2f936352014-08-05 14:04:04 +10007146
7147/*[clinic input]
7148os.symlink
7149 src: path_t
7150 dst: path_t
7151 target_is_directory: bool = False
7152 *
7153 dir_fd: dir_fd(requires='symlinkat')=None
7154
7155# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7156
7157Create a symbolic link pointing to src named dst.
7158
7159target_is_directory is required on Windows if the target is to be
7160 interpreted as a directory. (On Windows, symlink requires
7161 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7162 target_is_directory is ignored on non-Windows platforms.
7163
7164If dir_fd is not None, it should be a file descriptor open to a directory,
7165 and path should be relative; path will then be relative to that directory.
7166dir_fd may not be implemented on your platform.
7167 If it is unavailable, using it will raise a NotImplementedError.
7168
7169[clinic start generated code]*/
7170
Larry Hastings2f936352014-08-05 14:04:04 +10007171static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007172os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007173 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007174/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007175{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007176#ifdef MS_WINDOWS
7177 DWORD result;
7178#else
7179 int result;
7180#endif
7181
Larry Hastings9cf065c2012-06-22 16:30:09 -07007182#ifdef MS_WINDOWS
7183 if (!check_CreateSymbolicLink()) {
7184 PyErr_SetString(PyExc_NotImplementedError,
7185 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007186 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007187 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007188 if (!win32_can_symlink) {
7189 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007190 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007191 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007192#endif
7193
Larry Hastings2f936352014-08-05 14:04:04 +10007194 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007195 PyErr_SetString(PyExc_ValueError,
7196 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007197 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007198 }
7199
7200#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007201
Larry Hastings9cf065c2012-06-22 16:30:09 -07007202 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007203 /* if src is a directory, ensure target_is_directory==1 */
7204 target_is_directory |= _check_dirW(src->wide, dst->wide);
7205 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7206 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007207 Py_END_ALLOW_THREADS
7208
Larry Hastings2f936352014-08-05 14:04:04 +10007209 if (!result)
7210 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007211
7212#else
7213
7214 Py_BEGIN_ALLOW_THREADS
7215#if HAVE_SYMLINKAT
7216 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007217 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007218 else
7219#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007220 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007221 Py_END_ALLOW_THREADS
7222
Larry Hastings2f936352014-08-05 14:04:04 +10007223 if (result)
7224 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007225#endif
7226
Larry Hastings2f936352014-08-05 14:04:04 +10007227 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007228}
7229#endif /* HAVE_SYMLINK */
7230
Larry Hastings9cf065c2012-06-22 16:30:09 -07007231
Brian Curtind40e6f72010-07-08 21:39:08 +00007232
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007233
Larry Hastings605a62d2012-06-24 04:33:36 -07007234static PyStructSequence_Field times_result_fields[] = {
7235 {"user", "user time"},
7236 {"system", "system time"},
7237 {"children_user", "user time of children"},
7238 {"children_system", "system time of children"},
7239 {"elapsed", "elapsed time since an arbitrary point in the past"},
7240 {NULL}
7241};
7242
7243PyDoc_STRVAR(times_result__doc__,
7244"times_result: Result from os.times().\n\n\
7245This object may be accessed either as a tuple of\n\
7246 (user, system, children_user, children_system, elapsed),\n\
7247or via the attributes user, system, children_user, children_system,\n\
7248and elapsed.\n\
7249\n\
7250See os.times for more information.");
7251
7252static PyStructSequence_Desc times_result_desc = {
7253 "times_result", /* name */
7254 times_result__doc__, /* doc */
7255 times_result_fields,
7256 5
7257};
7258
7259static PyTypeObject TimesResultType;
7260
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007261#ifdef MS_WINDOWS
7262#define HAVE_TIMES /* mandatory, for the method table */
7263#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007264
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007265#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007266
7267static PyObject *
7268build_times_result(double user, double system,
7269 double children_user, double children_system,
7270 double elapsed)
7271{
7272 PyObject *value = PyStructSequence_New(&TimesResultType);
7273 if (value == NULL)
7274 return NULL;
7275
7276#define SET(i, field) \
7277 { \
7278 PyObject *o = PyFloat_FromDouble(field); \
7279 if (!o) { \
7280 Py_DECREF(value); \
7281 return NULL; \
7282 } \
7283 PyStructSequence_SET_ITEM(value, i, o); \
7284 } \
7285
7286 SET(0, user);
7287 SET(1, system);
7288 SET(2, children_user);
7289 SET(3, children_system);
7290 SET(4, elapsed);
7291
7292#undef SET
7293
7294 return value;
7295}
7296
Larry Hastings605a62d2012-06-24 04:33:36 -07007297
Larry Hastings2f936352014-08-05 14:04:04 +10007298#ifndef MS_WINDOWS
7299#define NEED_TICKS_PER_SECOND
7300static long ticks_per_second = -1;
7301#endif /* MS_WINDOWS */
7302
7303/*[clinic input]
7304os.times
7305
7306Return a collection containing process timing information.
7307
7308The object returned behaves like a named tuple with these fields:
7309 (utime, stime, cutime, cstime, elapsed_time)
7310All fields are floating point numbers.
7311[clinic start generated code]*/
7312
Larry Hastings2f936352014-08-05 14:04:04 +10007313static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007314os_times_impl(PyObject *module)
7315/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007316#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007317{
Victor Stinner8c62be82010-05-06 00:08:46 +00007318 FILETIME create, exit, kernel, user;
7319 HANDLE hProc;
7320 hProc = GetCurrentProcess();
7321 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7322 /* The fields of a FILETIME structure are the hi and lo part
7323 of a 64-bit value expressed in 100 nanosecond units.
7324 1e7 is one second in such units; 1e-7 the inverse.
7325 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7326 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007327 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007328 (double)(user.dwHighDateTime*429.4967296 +
7329 user.dwLowDateTime*1e-7),
7330 (double)(kernel.dwHighDateTime*429.4967296 +
7331 kernel.dwLowDateTime*1e-7),
7332 (double)0,
7333 (double)0,
7334 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007335}
Larry Hastings2f936352014-08-05 14:04:04 +10007336#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007337{
Larry Hastings2f936352014-08-05 14:04:04 +10007338
7339
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007340 struct tms t;
7341 clock_t c;
7342 errno = 0;
7343 c = times(&t);
7344 if (c == (clock_t) -1)
7345 return posix_error();
7346 return build_times_result(
7347 (double)t.tms_utime / ticks_per_second,
7348 (double)t.tms_stime / ticks_per_second,
7349 (double)t.tms_cutime / ticks_per_second,
7350 (double)t.tms_cstime / ticks_per_second,
7351 (double)c / ticks_per_second);
7352}
Larry Hastings2f936352014-08-05 14:04:04 +10007353#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007354#endif /* HAVE_TIMES */
7355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007356
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007357#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007358/*[clinic input]
7359os.getsid
7360
7361 pid: pid_t
7362 /
7363
7364Call the system call getsid(pid) and return the result.
7365[clinic start generated code]*/
7366
Larry Hastings2f936352014-08-05 14:04:04 +10007367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007368os_getsid_impl(PyObject *module, pid_t pid)
7369/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007370{
Victor Stinner8c62be82010-05-06 00:08:46 +00007371 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007372 sid = getsid(pid);
7373 if (sid < 0)
7374 return posix_error();
7375 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007376}
7377#endif /* HAVE_GETSID */
7378
7379
Guido van Rossumb6775db1994-08-01 11:34:53 +00007380#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007381/*[clinic input]
7382os.setsid
7383
7384Call the system call setsid().
7385[clinic start generated code]*/
7386
Larry Hastings2f936352014-08-05 14:04:04 +10007387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007388os_setsid_impl(PyObject *module)
7389/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007390{
Victor Stinner8c62be82010-05-06 00:08:46 +00007391 if (setsid() < 0)
7392 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007393 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007394}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007395#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007396
Larry Hastings2f936352014-08-05 14:04:04 +10007397
Guido van Rossumb6775db1994-08-01 11:34:53 +00007398#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007399/*[clinic input]
7400os.setpgid
7401
7402 pid: pid_t
7403 pgrp: pid_t
7404 /
7405
7406Call the system call setpgid(pid, pgrp).
7407[clinic start generated code]*/
7408
Larry Hastings2f936352014-08-05 14:04:04 +10007409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007410os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7411/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007412{
Victor Stinner8c62be82010-05-06 00:08:46 +00007413 if (setpgid(pid, pgrp) < 0)
7414 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007415 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007416}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007417#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007419
Guido van Rossumb6775db1994-08-01 11:34:53 +00007420#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007421/*[clinic input]
7422os.tcgetpgrp
7423
7424 fd: int
7425 /
7426
7427Return the process group associated with the terminal specified by fd.
7428[clinic start generated code]*/
7429
Larry Hastings2f936352014-08-05 14:04:04 +10007430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007431os_tcgetpgrp_impl(PyObject *module, int fd)
7432/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007433{
7434 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 if (pgid < 0)
7436 return posix_error();
7437 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007438}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007439#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007441
Guido van Rossumb6775db1994-08-01 11:34:53 +00007442#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007443/*[clinic input]
7444os.tcsetpgrp
7445
7446 fd: int
7447 pgid: pid_t
7448 /
7449
7450Set the process group associated with the terminal specified by fd.
7451[clinic start generated code]*/
7452
Larry Hastings2f936352014-08-05 14:04:04 +10007453static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007454os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7455/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007456{
Victor Stinner8c62be82010-05-06 00:08:46 +00007457 if (tcsetpgrp(fd, pgid) < 0)
7458 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007459 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007460}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007461#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007462
Guido van Rossum687dd131993-05-17 08:34:16 +00007463/* Functions acting on file descriptors */
7464
Victor Stinnerdaf45552013-08-28 00:53:59 +02007465#ifdef O_CLOEXEC
7466extern int _Py_open_cloexec_works;
7467#endif
7468
Larry Hastings2f936352014-08-05 14:04:04 +10007469
7470/*[clinic input]
7471os.open -> int
7472 path: path_t
7473 flags: int
7474 mode: int = 0o777
7475 *
7476 dir_fd: dir_fd(requires='openat') = None
7477
7478# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7479
7480Open a file for low level IO. Returns a file descriptor (integer).
7481
7482If dir_fd is not None, it should be a file descriptor open to a directory,
7483 and path should be relative; path will then be relative to that directory.
7484dir_fd may not be implemented on your platform.
7485 If it is unavailable, using it will raise a NotImplementedError.
7486[clinic start generated code]*/
7487
Larry Hastings2f936352014-08-05 14:04:04 +10007488static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007489os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7490/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007491{
7492 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007493 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007494
Victor Stinnerdaf45552013-08-28 00:53:59 +02007495#ifdef O_CLOEXEC
7496 int *atomic_flag_works = &_Py_open_cloexec_works;
7497#elif !defined(MS_WINDOWS)
7498 int *atomic_flag_works = NULL;
7499#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007500
Victor Stinnerdaf45552013-08-28 00:53:59 +02007501#ifdef MS_WINDOWS
7502 flags |= O_NOINHERIT;
7503#elif defined(O_CLOEXEC)
7504 flags |= O_CLOEXEC;
7505#endif
7506
Steve Dower8fc89802015-04-12 00:26:27 -04007507 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007508 do {
7509 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007510#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007511 fd = _wopen(path->wide, flags, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007512#endif
7513#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007514 if (dir_fd != DEFAULT_DIR_FD)
7515 fd = openat(dir_fd, path->narrow, flags, mode);
7516 else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007517 fd = open(path->narrow, flags, mode);
Steve Dowercc16be82016-09-08 10:35:16 -07007518#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007519 Py_END_ALLOW_THREADS
7520 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007521 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007522
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007523 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007524 if (!async_err)
7525 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007526 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007527 }
7528
Victor Stinnerdaf45552013-08-28 00:53:59 +02007529#ifndef MS_WINDOWS
7530 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7531 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007532 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007533 }
7534#endif
7535
Larry Hastings2f936352014-08-05 14:04:04 +10007536 return fd;
7537}
7538
7539
7540/*[clinic input]
7541os.close
7542
7543 fd: int
7544
7545Close a file descriptor.
7546[clinic start generated code]*/
7547
Barry Warsaw53699e91996-12-10 23:23:01 +00007548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007549os_close_impl(PyObject *module, int fd)
7550/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007551{
Larry Hastings2f936352014-08-05 14:04:04 +10007552 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 if (!_PyVerify_fd(fd))
7554 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007555 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7556 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7557 * for more details.
7558 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007559 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007560 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007561 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007562 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 Py_END_ALLOW_THREADS
7564 if (res < 0)
7565 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007566 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007567}
7568
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007569
Larry Hastings2f936352014-08-05 14:04:04 +10007570/*[clinic input]
7571os.closerange
7572
7573 fd_low: int
7574 fd_high: int
7575 /
7576
7577Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7578[clinic start generated code]*/
7579
Larry Hastings2f936352014-08-05 14:04:04 +10007580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007581os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7582/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007583{
7584 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007585 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007586 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007587 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007588 if (_PyVerify_fd(i))
7589 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007590 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007591 Py_END_ALLOW_THREADS
7592 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007593}
7594
7595
Larry Hastings2f936352014-08-05 14:04:04 +10007596/*[clinic input]
7597os.dup -> int
7598
7599 fd: int
7600 /
7601
7602Return a duplicate of a file descriptor.
7603[clinic start generated code]*/
7604
Larry Hastings2f936352014-08-05 14:04:04 +10007605static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007606os_dup_impl(PyObject *module, int fd)
7607/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007608{
7609 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007610}
7611
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007612
Larry Hastings2f936352014-08-05 14:04:04 +10007613/*[clinic input]
7614os.dup2
7615 fd: int
7616 fd2: int
7617 inheritable: bool=True
7618
7619Duplicate file descriptor.
7620[clinic start generated code]*/
7621
Larry Hastings2f936352014-08-05 14:04:04 +10007622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007623os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7624/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007625{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007626 int res;
7627#if defined(HAVE_DUP3) && \
7628 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7629 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7630 int dup3_works = -1;
7631#endif
7632
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 if (!_PyVerify_fd_dup2(fd, fd2))
7634 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007635
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007636 /* dup2() can fail with EINTR if the target FD is already open, because it
7637 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7638 * upon close(), and therefore below.
7639 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007640#ifdef MS_WINDOWS
7641 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007642 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007644 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007645 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007646 if (res < 0)
7647 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007648
7649 /* Character files like console cannot be make non-inheritable */
7650 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7651 close(fd2);
7652 return NULL;
7653 }
7654
7655#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7656 Py_BEGIN_ALLOW_THREADS
7657 if (!inheritable)
7658 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7659 else
7660 res = dup2(fd, fd2);
7661 Py_END_ALLOW_THREADS
7662 if (res < 0)
7663 return posix_error();
7664
7665#else
7666
7667#ifdef HAVE_DUP3
7668 if (!inheritable && dup3_works != 0) {
7669 Py_BEGIN_ALLOW_THREADS
7670 res = dup3(fd, fd2, O_CLOEXEC);
7671 Py_END_ALLOW_THREADS
7672 if (res < 0) {
7673 if (dup3_works == -1)
7674 dup3_works = (errno != ENOSYS);
7675 if (dup3_works)
7676 return posix_error();
7677 }
7678 }
7679
7680 if (inheritable || dup3_works == 0)
7681 {
7682#endif
7683 Py_BEGIN_ALLOW_THREADS
7684 res = dup2(fd, fd2);
7685 Py_END_ALLOW_THREADS
7686 if (res < 0)
7687 return posix_error();
7688
7689 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7690 close(fd2);
7691 return NULL;
7692 }
7693#ifdef HAVE_DUP3
7694 }
7695#endif
7696
7697#endif
7698
Larry Hastings2f936352014-08-05 14:04:04 +10007699 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007700}
7701
Larry Hastings2f936352014-08-05 14:04:04 +10007702
Ross Lagerwall7807c352011-03-17 20:20:30 +02007703#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007704/*[clinic input]
7705os.lockf
7706
7707 fd: int
7708 An open file descriptor.
7709 command: int
7710 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7711 length: Py_off_t
7712 The number of bytes to lock, starting at the current position.
7713 /
7714
7715Apply, test or remove a POSIX lock on an open file descriptor.
7716
7717[clinic start generated code]*/
7718
Larry Hastings2f936352014-08-05 14:04:04 +10007719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007720os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7721/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007722{
7723 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007724
7725 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007726 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007727 Py_END_ALLOW_THREADS
7728
7729 if (res < 0)
7730 return posix_error();
7731
7732 Py_RETURN_NONE;
7733}
Larry Hastings2f936352014-08-05 14:04:04 +10007734#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007736
Larry Hastings2f936352014-08-05 14:04:04 +10007737/*[clinic input]
7738os.lseek -> Py_off_t
7739
7740 fd: int
7741 position: Py_off_t
7742 how: int
7743 /
7744
7745Set the position of a file descriptor. Return the new position.
7746
7747Return the new cursor position in number of bytes
7748relative to the beginning of the file.
7749[clinic start generated code]*/
7750
Larry Hastings2f936352014-08-05 14:04:04 +10007751static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007752os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7753/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007754{
7755 Py_off_t result;
7756
7757 if (!_PyVerify_fd(fd)) {
7758 posix_error();
7759 return -1;
7760 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007761#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7763 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007764 case 0: how = SEEK_SET; break;
7765 case 1: how = SEEK_CUR; break;
7766 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007768#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007769
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007771 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007772
Larry Hastings2f936352014-08-05 14:04:04 +10007773 if (!_PyVerify_fd(fd)) {
7774 posix_error();
7775 return -1;
7776 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007778 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007779#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007780 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007781#else
Larry Hastings2f936352014-08-05 14:04:04 +10007782 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007783#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007784 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007786 if (result < 0)
7787 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007788
Larry Hastings2f936352014-08-05 14:04:04 +10007789 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007790}
7791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007792
Larry Hastings2f936352014-08-05 14:04:04 +10007793/*[clinic input]
7794os.read
7795 fd: int
7796 length: Py_ssize_t
7797 /
7798
7799Read from a file descriptor. Returns a bytes object.
7800[clinic start generated code]*/
7801
Larry Hastings2f936352014-08-05 14:04:04 +10007802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007803os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7804/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007805{
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 Py_ssize_t n;
7807 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007808
7809 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 errno = EINVAL;
7811 return posix_error();
7812 }
Larry Hastings2f936352014-08-05 14:04:04 +10007813
7814#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007815 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007816 if (length > INT_MAX)
7817 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007818#endif
7819
7820 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 if (buffer == NULL)
7822 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007823
Victor Stinner66aab0c2015-03-19 22:53:20 +01007824 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7825 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007827 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 }
Larry Hastings2f936352014-08-05 14:04:04 +10007829
7830 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007832
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007834}
7835
Ross Lagerwall7807c352011-03-17 20:20:30 +02007836#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7837 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007838static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007839iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7840{
7841 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007842 Py_ssize_t blen, total = 0;
7843
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007844 *iov = PyMem_New(struct iovec, cnt);
7845 if (*iov == NULL) {
7846 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007847 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007848 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007849
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007850 *buf = PyMem_New(Py_buffer, cnt);
7851 if (*buf == NULL) {
7852 PyMem_Del(*iov);
7853 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007854 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007855 }
7856
7857 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007858 PyObject *item = PySequence_GetItem(seq, i);
7859 if (item == NULL)
7860 goto fail;
7861 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7862 Py_DECREF(item);
7863 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007864 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007865 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007866 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007867 blen = (*buf)[i].len;
7868 (*iov)[i].iov_len = blen;
7869 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007870 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007871 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007872
7873fail:
7874 PyMem_Del(*iov);
7875 for (j = 0; j < i; j++) {
7876 PyBuffer_Release(&(*buf)[j]);
7877 }
7878 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007879 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007880}
7881
7882static void
7883iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7884{
7885 int i;
7886 PyMem_Del(iov);
7887 for (i = 0; i < cnt; i++) {
7888 PyBuffer_Release(&buf[i]);
7889 }
7890 PyMem_Del(buf);
7891}
7892#endif
7893
Larry Hastings2f936352014-08-05 14:04:04 +10007894
Ross Lagerwall7807c352011-03-17 20:20:30 +02007895#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007896/*[clinic input]
7897os.readv -> Py_ssize_t
7898
7899 fd: int
7900 buffers: object
7901 /
7902
7903Read from a file descriptor fd into an iterable of buffers.
7904
7905The buffers should be mutable buffers accepting bytes.
7906readv will transfer data into each buffer until it is full
7907and then move on to the next buffer in the sequence to hold
7908the rest of the data.
7909
7910readv returns the total number of bytes read,
7911which may be less than the total capacity of all the buffers.
7912[clinic start generated code]*/
7913
Larry Hastings2f936352014-08-05 14:04:04 +10007914static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007915os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7916/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007917{
7918 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007919 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007920 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007921 struct iovec *iov;
7922 Py_buffer *buf;
7923
Larry Hastings2f936352014-08-05 14:04:04 +10007924 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007925 PyErr_SetString(PyExc_TypeError,
7926 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007927 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007928 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007929
Larry Hastings2f936352014-08-05 14:04:04 +10007930 cnt = PySequence_Size(buffers);
7931
7932 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7933 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007935 do {
7936 Py_BEGIN_ALLOW_THREADS
7937 n = readv(fd, iov, cnt);
7938 Py_END_ALLOW_THREADS
7939 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940
7941 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007942 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007943 if (!async_err)
7944 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007945 return -1;
7946 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007947
Larry Hastings2f936352014-08-05 14:04:04 +10007948 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007949}
Larry Hastings2f936352014-08-05 14:04:04 +10007950#endif /* HAVE_READV */
7951
Ross Lagerwall7807c352011-03-17 20:20:30 +02007952
7953#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007954/*[clinic input]
7955# TODO length should be size_t! but Python doesn't support parsing size_t yet.
7956os.pread
7957
7958 fd: int
7959 length: int
7960 offset: Py_off_t
7961 /
7962
7963Read a number of bytes from a file descriptor starting at a particular offset.
7964
7965Read length bytes from file descriptor fd, starting at offset bytes from
7966the beginning of the file. The file offset remains unchanged.
7967[clinic start generated code]*/
7968
Larry Hastings2f936352014-08-05 14:04:04 +10007969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007970os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
7971/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007972{
Ross Lagerwall7807c352011-03-17 20:20:30 +02007973 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007974 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007975 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007976
Larry Hastings2f936352014-08-05 14:04:04 +10007977 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007978 errno = EINVAL;
7979 return posix_error();
7980 }
Larry Hastings2f936352014-08-05 14:04:04 +10007981 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007982 if (buffer == NULL)
7983 return NULL;
7984 if (!_PyVerify_fd(fd)) {
7985 Py_DECREF(buffer);
7986 return posix_error();
7987 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007988
7989 do {
7990 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007991 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007992 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04007993 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007994 Py_END_ALLOW_THREADS
7995 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7996
Ross Lagerwall7807c352011-03-17 20:20:30 +02007997 if (n < 0) {
7998 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007999 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008000 }
Larry Hastings2f936352014-08-05 14:04:04 +10008001 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008002 _PyBytes_Resize(&buffer, n);
8003 return buffer;
8004}
Larry Hastings2f936352014-08-05 14:04:04 +10008005#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008006
Larry Hastings2f936352014-08-05 14:04:04 +10008007
8008/*[clinic input]
8009os.write -> Py_ssize_t
8010
8011 fd: int
8012 data: Py_buffer
8013 /
8014
8015Write a bytes object to a file descriptor.
8016[clinic start generated code]*/
8017
Larry Hastings2f936352014-08-05 14:04:04 +10008018static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008019os_write_impl(PyObject *module, int fd, Py_buffer *data)
8020/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008021{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008022 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023}
8024
8025#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008026PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008027"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008028sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008029 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008030Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008031
Larry Hastings2f936352014-08-05 14:04:04 +10008032/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008033static PyObject *
8034posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8035{
8036 int in, out;
8037 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008038 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008039 off_t offset;
8040
8041#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8042#ifndef __APPLE__
8043 Py_ssize_t len;
8044#endif
8045 PyObject *headers = NULL, *trailers = NULL;
8046 Py_buffer *hbuf, *tbuf;
8047 off_t sbytes;
8048 struct sf_hdtr sf;
8049 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008050 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008051 static char *keywords[] = {"out", "in",
8052 "offset", "count",
8053 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008055 sf.headers = NULL;
8056 sf.trailers = NULL;
8057
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008058#ifdef __APPLE__
8059 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008060 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061#else
8062 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008063 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064#endif
8065 &headers, &trailers, &flags))
8066 return NULL;
8067 if (headers != NULL) {
8068 if (!PySequence_Check(headers)) {
8069 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008070 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071 return NULL;
8072 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008073 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008075 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008076 (i = iov_setup(&(sf.headers), &hbuf,
8077 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008078 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008079#ifdef __APPLE__
8080 sbytes += i;
8081#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008082 }
8083 }
8084 if (trailers != NULL) {
8085 if (!PySequence_Check(trailers)) {
8086 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008087 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008088 return NULL;
8089 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008090 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008092 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008093 (i = iov_setup(&(sf.trailers), &tbuf,
8094 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008096#ifdef __APPLE__
8097 sbytes += i;
8098#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008099 }
8100 }
8101
Steve Dower8fc89802015-04-12 00:26:27 -04008102 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008103 do {
8104 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008105#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008106 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008107#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008108 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008109#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008110 Py_END_ALLOW_THREADS
8111 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008112 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008113
8114 if (sf.headers != NULL)
8115 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8116 if (sf.trailers != NULL)
8117 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8118
8119 if (ret < 0) {
8120 if ((errno == EAGAIN) || (errno == EBUSY)) {
8121 if (sbytes != 0) {
8122 // some data has been sent
8123 goto done;
8124 }
8125 else {
8126 // no data has been sent; upper application is supposed
8127 // to retry on EAGAIN or EBUSY
8128 return posix_error();
8129 }
8130 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008131 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008132 }
8133 goto done;
8134
8135done:
8136 #if !defined(HAVE_LARGEFILE_SUPPORT)
8137 return Py_BuildValue("l", sbytes);
8138 #else
8139 return Py_BuildValue("L", sbytes);
8140 #endif
8141
8142#else
8143 Py_ssize_t count;
8144 PyObject *offobj;
8145 static char *keywords[] = {"out", "in",
8146 "offset", "count", NULL};
8147 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8148 keywords, &out, &in, &offobj, &count))
8149 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008150#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008151 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008152 do {
8153 Py_BEGIN_ALLOW_THREADS
8154 ret = sendfile(out, in, NULL, count);
8155 Py_END_ALLOW_THREADS
8156 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008157 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008158 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008159 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008160 }
8161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008162 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008163 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008164
8165 do {
8166 Py_BEGIN_ALLOW_THREADS
8167 ret = sendfile(out, in, &offset, count);
8168 Py_END_ALLOW_THREADS
8169 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008170 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008171 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008172 return Py_BuildValue("n", ret);
8173#endif
8174}
Larry Hastings2f936352014-08-05 14:04:04 +10008175#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008176
Larry Hastings2f936352014-08-05 14:04:04 +10008177
8178/*[clinic input]
8179os.fstat
8180
8181 fd : int
8182
8183Perform a stat system call on the given file descriptor.
8184
8185Like stat(), but for an open file descriptor.
8186Equivalent to os.stat(fd).
8187[clinic start generated code]*/
8188
Larry Hastings2f936352014-08-05 14:04:04 +10008189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008190os_fstat_impl(PyObject *module, int fd)
8191/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008192{
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 STRUCT_STAT st;
8194 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008195 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008196
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008197 do {
8198 Py_BEGIN_ALLOW_THREADS
8199 res = FSTAT(fd, &st);
8200 Py_END_ALLOW_THREADS
8201 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008203#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008204 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008205#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008206 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008207#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 }
Tim Peters5aa91602002-01-30 05:46:57 +00008209
Victor Stinner4195b5c2012-02-08 23:03:19 +01008210 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008211}
8212
Larry Hastings2f936352014-08-05 14:04:04 +10008213
8214/*[clinic input]
8215os.isatty -> bool
8216 fd: int
8217 /
8218
8219Return True if the fd is connected to a terminal.
8220
8221Return True if the file descriptor is an open file descriptor
8222connected to the slave end of a terminal.
8223[clinic start generated code]*/
8224
Larry Hastings2f936352014-08-05 14:04:04 +10008225static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008226os_isatty_impl(PyObject *module, int fd)
8227/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008228{
Steve Dower8fc89802015-04-12 00:26:27 -04008229 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008230 if (!_PyVerify_fd(fd))
8231 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008232 _Py_BEGIN_SUPPRESS_IPH
8233 return_value = isatty(fd);
8234 _Py_END_SUPPRESS_IPH
8235 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008236}
8237
8238
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008239#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008240/*[clinic input]
8241os.pipe
8242
8243Create a pipe.
8244
8245Returns a tuple of two file descriptors:
8246 (read_fd, write_fd)
8247[clinic start generated code]*/
8248
Larry Hastings2f936352014-08-05 14:04:04 +10008249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008250os_pipe_impl(PyObject *module)
8251/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008252{
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008254#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008255 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008256 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008257 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008258#else
8259 int res;
8260#endif
8261
8262#ifdef MS_WINDOWS
8263 attr.nLength = sizeof(attr);
8264 attr.lpSecurityDescriptor = NULL;
8265 attr.bInheritHandle = FALSE;
8266
8267 Py_BEGIN_ALLOW_THREADS
8268 ok = CreatePipe(&read, &write, &attr, 0);
8269 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008270 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8271 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008272 if (fds[0] == -1 || fds[1] == -1) {
8273 CloseHandle(read);
8274 CloseHandle(write);
8275 ok = 0;
8276 }
8277 }
8278 Py_END_ALLOW_THREADS
8279
Victor Stinner8c62be82010-05-06 00:08:46 +00008280 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008281 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008282#else
8283
8284#ifdef HAVE_PIPE2
8285 Py_BEGIN_ALLOW_THREADS
8286 res = pipe2(fds, O_CLOEXEC);
8287 Py_END_ALLOW_THREADS
8288
8289 if (res != 0 && errno == ENOSYS)
8290 {
8291#endif
8292 Py_BEGIN_ALLOW_THREADS
8293 res = pipe(fds);
8294 Py_END_ALLOW_THREADS
8295
8296 if (res == 0) {
8297 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8298 close(fds[0]);
8299 close(fds[1]);
8300 return NULL;
8301 }
8302 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8303 close(fds[0]);
8304 close(fds[1]);
8305 return NULL;
8306 }
8307 }
8308#ifdef HAVE_PIPE2
8309 }
8310#endif
8311
8312 if (res != 0)
8313 return PyErr_SetFromErrno(PyExc_OSError);
8314#endif /* !MS_WINDOWS */
8315 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008316}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008317#endif /* HAVE_PIPE */
8318
Larry Hastings2f936352014-08-05 14:04:04 +10008319
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008320#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008321/*[clinic input]
8322os.pipe2
8323
8324 flags: int
8325 /
8326
8327Create a pipe with flags set atomically.
8328
8329Returns a tuple of two file descriptors:
8330 (read_fd, write_fd)
8331
8332flags can be constructed by ORing together one or more of these values:
8333O_NONBLOCK, O_CLOEXEC.
8334[clinic start generated code]*/
8335
Larry Hastings2f936352014-08-05 14:04:04 +10008336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008337os_pipe2_impl(PyObject *module, int flags)
8338/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008339{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008340 int fds[2];
8341 int res;
8342
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008343 res = pipe2(fds, flags);
8344 if (res != 0)
8345 return posix_error();
8346 return Py_BuildValue("(ii)", fds[0], fds[1]);
8347}
8348#endif /* HAVE_PIPE2 */
8349
Larry Hastings2f936352014-08-05 14:04:04 +10008350
Ross Lagerwall7807c352011-03-17 20:20:30 +02008351#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008352/*[clinic input]
8353os.writev -> Py_ssize_t
8354 fd: int
8355 buffers: object
8356 /
8357
8358Iterate over buffers, and write the contents of each to a file descriptor.
8359
8360Returns the total number of bytes written.
8361buffers must be a sequence of bytes-like objects.
8362[clinic start generated code]*/
8363
Larry Hastings2f936352014-08-05 14:04:04 +10008364static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008365os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8366/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008367{
8368 int cnt;
8369 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008370 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008371 struct iovec *iov;
8372 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008373
8374 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008375 PyErr_SetString(PyExc_TypeError,
8376 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008377 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008378 }
Larry Hastings2f936352014-08-05 14:04:04 +10008379 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008380
Larry Hastings2f936352014-08-05 14:04:04 +10008381 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8382 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008383 }
8384
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008385 do {
8386 Py_BEGIN_ALLOW_THREADS
8387 result = writev(fd, iov, cnt);
8388 Py_END_ALLOW_THREADS
8389 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008390
8391 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008392 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008393 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008394
Georg Brandl306336b2012-06-24 12:55:33 +02008395 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008396}
Larry Hastings2f936352014-08-05 14:04:04 +10008397#endif /* HAVE_WRITEV */
8398
8399
8400#ifdef HAVE_PWRITE
8401/*[clinic input]
8402os.pwrite -> Py_ssize_t
8403
8404 fd: int
8405 buffer: Py_buffer
8406 offset: Py_off_t
8407 /
8408
8409Write bytes to a file descriptor starting at a particular offset.
8410
8411Write buffer to fd, starting at offset bytes from the beginning of
8412the file. Returns the number of bytes writte. Does not change the
8413current file offset.
8414[clinic start generated code]*/
8415
Larry Hastings2f936352014-08-05 14:04:04 +10008416static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008417os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8418/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008419{
8420 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008421 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008422
8423 if (!_PyVerify_fd(fd)) {
8424 posix_error();
8425 return -1;
8426 }
8427
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008428 do {
8429 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008430 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008431 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008432 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008433 Py_END_ALLOW_THREADS
8434 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008435
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008436 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008437 posix_error();
8438 return size;
8439}
8440#endif /* HAVE_PWRITE */
8441
8442
8443#ifdef HAVE_MKFIFO
8444/*[clinic input]
8445os.mkfifo
8446
8447 path: path_t
8448 mode: int=0o666
8449 *
8450 dir_fd: dir_fd(requires='mkfifoat')=None
8451
8452Create a "fifo" (a POSIX named pipe).
8453
8454If dir_fd is not None, it should be a file descriptor open to a directory,
8455 and path should be relative; path will then be relative to that directory.
8456dir_fd may not be implemented on your platform.
8457 If it is unavailable, using it will raise a NotImplementedError.
8458[clinic start generated code]*/
8459
Larry Hastings2f936352014-08-05 14:04:04 +10008460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008461os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8462/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008463{
8464 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008465 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008466
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008467 do {
8468 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008469#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008470 if (dir_fd != DEFAULT_DIR_FD)
8471 result = mkfifoat(dir_fd, path->narrow, mode);
8472 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008473#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008474 result = mkfifo(path->narrow, mode);
8475 Py_END_ALLOW_THREADS
8476 } while (result != 0 && errno == EINTR &&
8477 !(async_err = PyErr_CheckSignals()));
8478 if (result != 0)
8479 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008480
8481 Py_RETURN_NONE;
8482}
8483#endif /* HAVE_MKFIFO */
8484
8485
8486#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8487/*[clinic input]
8488os.mknod
8489
8490 path: path_t
8491 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008492 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008493 *
8494 dir_fd: dir_fd(requires='mknodat')=None
8495
8496Create a node in the file system.
8497
8498Create a node in the file system (file, device special file or named pipe)
8499at path. mode specifies both the permissions to use and the
8500type of node to be created, being combined (bitwise OR) with one of
8501S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8502device defines the newly created device special file (probably using
8503os.makedev()). Otherwise device is ignored.
8504
8505If dir_fd is not None, it should be a file descriptor open to a directory,
8506 and path should be relative; path will then be relative to that directory.
8507dir_fd may not be implemented on your platform.
8508 If it is unavailable, using it will raise a NotImplementedError.
8509[clinic start generated code]*/
8510
Larry Hastings2f936352014-08-05 14:04:04 +10008511static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008512os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008513 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008514/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008515{
8516 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008517 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008518
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008519 do {
8520 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008521#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008522 if (dir_fd != DEFAULT_DIR_FD)
8523 result = mknodat(dir_fd, path->narrow, mode, device);
8524 else
Larry Hastings2f936352014-08-05 14:04:04 +10008525#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008526 result = mknod(path->narrow, mode, device);
8527 Py_END_ALLOW_THREADS
8528 } while (result != 0 && errno == EINTR &&
8529 !(async_err = PyErr_CheckSignals()));
8530 if (result != 0)
8531 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008532
8533 Py_RETURN_NONE;
8534}
8535#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8536
8537
8538#ifdef HAVE_DEVICE_MACROS
8539/*[clinic input]
8540os.major -> unsigned_int
8541
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008542 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008543 /
8544
8545Extracts a device major number from a raw device number.
8546[clinic start generated code]*/
8547
Larry Hastings2f936352014-08-05 14:04:04 +10008548static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008549os_major_impl(PyObject *module, dev_t device)
8550/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008551{
8552 return major(device);
8553}
8554
8555
8556/*[clinic input]
8557os.minor -> unsigned_int
8558
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008559 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008560 /
8561
8562Extracts a device minor number from a raw device number.
8563[clinic start generated code]*/
8564
Larry Hastings2f936352014-08-05 14:04:04 +10008565static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008566os_minor_impl(PyObject *module, dev_t device)
8567/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008568{
8569 return minor(device);
8570}
8571
8572
8573/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008574os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008575
8576 major: int
8577 minor: int
8578 /
8579
8580Composes a raw device number from the major and minor device numbers.
8581[clinic start generated code]*/
8582
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008583static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008584os_makedev_impl(PyObject *module, int major, int minor)
8585/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008586{
8587 return makedev(major, minor);
8588}
8589#endif /* HAVE_DEVICE_MACROS */
8590
8591
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008592#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008593/*[clinic input]
8594os.ftruncate
8595
8596 fd: int
8597 length: Py_off_t
8598 /
8599
8600Truncate a file, specified by file descriptor, to a specific length.
8601[clinic start generated code]*/
8602
Larry Hastings2f936352014-08-05 14:04:04 +10008603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008604os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8605/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008606{
8607 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008608 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008609
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008610 if (!_PyVerify_fd(fd))
8611 return posix_error();
8612
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008613 do {
8614 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008615 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008616#ifdef MS_WINDOWS
8617 result = _chsize_s(fd, length);
8618#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008619 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008620#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008621 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008622 Py_END_ALLOW_THREADS
8623 } while (result != 0 && errno == EINTR &&
8624 !(async_err = PyErr_CheckSignals()));
8625 if (result != 0)
8626 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008627 Py_RETURN_NONE;
8628}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008629#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008630
8631
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008632#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008633/*[clinic input]
8634os.truncate
8635 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8636 length: Py_off_t
8637
8638Truncate a file, specified by path, to a specific length.
8639
8640On some platforms, path may also be specified as an open file descriptor.
8641 If this functionality is unavailable, using it raises an exception.
8642[clinic start generated code]*/
8643
Larry Hastings2f936352014-08-05 14:04:04 +10008644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008645os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8646/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008647{
8648 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008649#ifdef MS_WINDOWS
8650 int fd;
8651#endif
8652
8653 if (path->fd != -1)
8654 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008655
8656 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008657 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008658#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008659 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008660 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008661 result = -1;
8662 else {
8663 result = _chsize_s(fd, length);
8664 close(fd);
8665 if (result < 0)
8666 errno = result;
8667 }
8668#else
8669 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008670#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008671 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008672 Py_END_ALLOW_THREADS
8673 if (result < 0)
8674 return path_error(path);
8675
8676 Py_RETURN_NONE;
8677}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008678#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008679
Ross Lagerwall7807c352011-03-17 20:20:30 +02008680
Victor Stinnerd6b17692014-09-30 12:20:05 +02008681/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8682 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8683 defined, which is the case in Python on AIX. AIX bug report:
8684 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8685#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8686# define POSIX_FADVISE_AIX_BUG
8687#endif
8688
Victor Stinnerec39e262014-09-30 12:35:58 +02008689
Victor Stinnerd6b17692014-09-30 12:20:05 +02008690#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008691/*[clinic input]
8692os.posix_fallocate
8693
8694 fd: int
8695 offset: Py_off_t
8696 length: Py_off_t
8697 /
8698
8699Ensure a file has allocated at least a particular number of bytes on disk.
8700
8701Ensure that the file specified by fd encompasses a range of bytes
8702starting at offset bytes from the beginning and continuing for length bytes.
8703[clinic start generated code]*/
8704
Larry Hastings2f936352014-08-05 14:04:04 +10008705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008706os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008707 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008708/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008709{
8710 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008711 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008712
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008713 do {
8714 Py_BEGIN_ALLOW_THREADS
8715 result = posix_fallocate(fd, offset, length);
8716 Py_END_ALLOW_THREADS
8717 } while (result != 0 && errno == EINTR &&
8718 !(async_err = PyErr_CheckSignals()));
8719 if (result != 0)
8720 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008721 Py_RETURN_NONE;
8722}
Victor Stinnerec39e262014-09-30 12:35:58 +02008723#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008724
Ross Lagerwall7807c352011-03-17 20:20:30 +02008725
Victor Stinnerd6b17692014-09-30 12:20:05 +02008726#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008727/*[clinic input]
8728os.posix_fadvise
8729
8730 fd: int
8731 offset: Py_off_t
8732 length: Py_off_t
8733 advice: int
8734 /
8735
8736Announce an intention to access data in a specific pattern.
8737
8738Announce an intention to access data in a specific pattern, thus allowing
8739the kernel to make optimizations.
8740The advice applies to the region of the file specified by fd starting at
8741offset and continuing for length bytes.
8742advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8743POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8744POSIX_FADV_DONTNEED.
8745[clinic start generated code]*/
8746
Larry Hastings2f936352014-08-05 14:04:04 +10008747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008748os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008749 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008750/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008751{
8752 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008753 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008754
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008755 do {
8756 Py_BEGIN_ALLOW_THREADS
8757 result = posix_fadvise(fd, offset, length, advice);
8758 Py_END_ALLOW_THREADS
8759 } while (result != 0 && errno == EINTR &&
8760 !(async_err = PyErr_CheckSignals()));
8761 if (result != 0)
8762 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008763 Py_RETURN_NONE;
8764}
Victor Stinnerec39e262014-09-30 12:35:58 +02008765#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008766
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008767#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008768
Fred Drake762e2061999-08-26 17:23:54 +00008769/* Save putenv() parameters as values here, so we can collect them when they
8770 * get re-set with another call for the same key. */
8771static PyObject *posix_putenv_garbage;
8772
Larry Hastings2f936352014-08-05 14:04:04 +10008773static void
8774posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008775{
Larry Hastings2f936352014-08-05 14:04:04 +10008776 /* Install the first arg and newstr in posix_putenv_garbage;
8777 * this will cause previous value to be collected. This has to
8778 * happen after the real putenv() call because the old value
8779 * was still accessible until then. */
8780 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8781 /* really not much we can do; just leak */
8782 PyErr_Clear();
8783 else
8784 Py_DECREF(value);
8785}
8786
8787
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008788#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008789/*[clinic input]
8790os.putenv
8791
8792 name: unicode
8793 value: unicode
8794 /
8795
8796Change or add an environment variable.
8797[clinic start generated code]*/
8798
Larry Hastings2f936352014-08-05 14:04:04 +10008799static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008800os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8801/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008802{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008803 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008804
8805 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8806 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008807 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008808 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008809 }
Larry Hastings2f936352014-08-05 14:04:04 +10008810 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008811 PyErr_Format(PyExc_ValueError,
8812 "the environment variable is longer than %u characters",
8813 _MAX_ENV);
8814 goto error;
8815 }
8816
Larry Hastings2f936352014-08-05 14:04:04 +10008817 env = PyUnicode_AsUnicode(unicode);
8818 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008819 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008820 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008822 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008824
Larry Hastings2f936352014-08-05 14:04:04 +10008825 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008826 Py_RETURN_NONE;
8827
8828error:
Larry Hastings2f936352014-08-05 14:04:04 +10008829 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008830 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008831}
Larry Hastings2f936352014-08-05 14:04:04 +10008832#else /* MS_WINDOWS */
8833/*[clinic input]
8834os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008835
Larry Hastings2f936352014-08-05 14:04:04 +10008836 name: FSConverter
8837 value: FSConverter
8838 /
8839
8840Change or add an environment variable.
8841[clinic start generated code]*/
8842
Larry Hastings2f936352014-08-05 14:04:04 +10008843static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008844os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8845/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008846{
8847 PyObject *bytes = NULL;
8848 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008849 const char *name_string = PyBytes_AsString(name);
8850 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008851
8852 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8853 if (bytes == NULL) {
8854 PyErr_NoMemory();
8855 return NULL;
8856 }
8857
8858 env = PyBytes_AS_STRING(bytes);
8859 if (putenv(env)) {
8860 Py_DECREF(bytes);
8861 return posix_error();
8862 }
8863
8864 posix_putenv_garbage_setitem(name, bytes);
8865 Py_RETURN_NONE;
8866}
8867#endif /* MS_WINDOWS */
8868#endif /* HAVE_PUTENV */
8869
8870
8871#ifdef HAVE_UNSETENV
8872/*[clinic input]
8873os.unsetenv
8874 name: FSConverter
8875 /
8876
8877Delete an environment variable.
8878[clinic start generated code]*/
8879
Larry Hastings2f936352014-08-05 14:04:04 +10008880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008881os_unsetenv_impl(PyObject *module, PyObject *name)
8882/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008883{
Victor Stinner984890f2011-11-24 13:53:38 +01008884#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008885 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008886#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008887
Victor Stinner984890f2011-11-24 13:53:38 +01008888#ifdef HAVE_BROKEN_UNSETENV
8889 unsetenv(PyBytes_AS_STRING(name));
8890#else
Victor Stinner65170952011-11-22 22:16:17 +01008891 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008892 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008893 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008894#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008895
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 /* Remove the key from posix_putenv_garbage;
8897 * this will cause it to be collected. This has to
8898 * happen after the real unsetenv() call because the
8899 * old value was still accessible until then.
8900 */
Victor Stinner65170952011-11-22 22:16:17 +01008901 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008902 /* really not much we can do; just leak */
8903 PyErr_Clear();
8904 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008905 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008906}
Larry Hastings2f936352014-08-05 14:04:04 +10008907#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008908
Larry Hastings2f936352014-08-05 14:04:04 +10008909
8910/*[clinic input]
8911os.strerror
8912
8913 code: int
8914 /
8915
8916Translate an error code to a message string.
8917[clinic start generated code]*/
8918
Larry Hastings2f936352014-08-05 14:04:04 +10008919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008920os_strerror_impl(PyObject *module, int code)
8921/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008922{
8923 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 if (message == NULL) {
8925 PyErr_SetString(PyExc_ValueError,
8926 "strerror() argument out of range");
8927 return NULL;
8928 }
Victor Stinner1b579672011-12-17 05:47:23 +01008929 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008930}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008931
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008932
Guido van Rossumc9641791998-08-04 15:26:23 +00008933#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008934#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008935/*[clinic input]
8936os.WCOREDUMP -> bool
8937
8938 status: int
8939 /
8940
8941Return True if the process returning status was dumped to a core file.
8942[clinic start generated code]*/
8943
Larry Hastings2f936352014-08-05 14:04:04 +10008944static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008945os_WCOREDUMP_impl(PyObject *module, int status)
8946/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008947{
8948 WAIT_TYPE wait_status;
8949 WAIT_STATUS_INT(wait_status) = status;
8950 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008951}
8952#endif /* WCOREDUMP */
8953
Larry Hastings2f936352014-08-05 14:04:04 +10008954
Fred Drake106c1a02002-04-23 15:58:02 +00008955#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008956/*[clinic input]
8957os.WIFCONTINUED -> bool
8958
8959 status: int
8960
8961Return True if a particular process was continued from a job control stop.
8962
8963Return True if the process returning status was continued from a
8964job control stop.
8965[clinic start generated code]*/
8966
Larry Hastings2f936352014-08-05 14:04:04 +10008967static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008968os_WIFCONTINUED_impl(PyObject *module, int status)
8969/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008970{
8971 WAIT_TYPE wait_status;
8972 WAIT_STATUS_INT(wait_status) = status;
8973 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008974}
8975#endif /* WIFCONTINUED */
8976
Larry Hastings2f936352014-08-05 14:04:04 +10008977
Guido van Rossumc9641791998-08-04 15:26:23 +00008978#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10008979/*[clinic input]
8980os.WIFSTOPPED -> bool
8981
8982 status: int
8983
8984Return True if the process returning status was stopped.
8985[clinic start generated code]*/
8986
Larry Hastings2f936352014-08-05 14:04:04 +10008987static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008988os_WIFSTOPPED_impl(PyObject *module, int status)
8989/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008990{
8991 WAIT_TYPE wait_status;
8992 WAIT_STATUS_INT(wait_status) = status;
8993 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008994}
8995#endif /* WIFSTOPPED */
8996
Larry Hastings2f936352014-08-05 14:04:04 +10008997
Guido van Rossumc9641791998-08-04 15:26:23 +00008998#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10008999/*[clinic input]
9000os.WIFSIGNALED -> bool
9001
9002 status: int
9003
9004Return True if the process returning status was terminated by a signal.
9005[clinic start generated code]*/
9006
Larry Hastings2f936352014-08-05 14:04:04 +10009007static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009008os_WIFSIGNALED_impl(PyObject *module, int status)
9009/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009010{
9011 WAIT_TYPE wait_status;
9012 WAIT_STATUS_INT(wait_status) = status;
9013 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009014}
9015#endif /* WIFSIGNALED */
9016
Larry Hastings2f936352014-08-05 14:04:04 +10009017
Guido van Rossumc9641791998-08-04 15:26:23 +00009018#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009019/*[clinic input]
9020os.WIFEXITED -> bool
9021
9022 status: int
9023
9024Return True if the process returning status exited via the exit() system call.
9025[clinic start generated code]*/
9026
Larry Hastings2f936352014-08-05 14:04:04 +10009027static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009028os_WIFEXITED_impl(PyObject *module, int status)
9029/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009030{
9031 WAIT_TYPE wait_status;
9032 WAIT_STATUS_INT(wait_status) = status;
9033 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009034}
9035#endif /* WIFEXITED */
9036
Larry Hastings2f936352014-08-05 14:04:04 +10009037
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009038#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009039/*[clinic input]
9040os.WEXITSTATUS -> int
9041
9042 status: int
9043
9044Return the process return code from status.
9045[clinic start generated code]*/
9046
Larry Hastings2f936352014-08-05 14:04:04 +10009047static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009048os_WEXITSTATUS_impl(PyObject *module, int status)
9049/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009050{
9051 WAIT_TYPE wait_status;
9052 WAIT_STATUS_INT(wait_status) = status;
9053 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009054}
9055#endif /* WEXITSTATUS */
9056
Larry Hastings2f936352014-08-05 14:04:04 +10009057
Guido van Rossumc9641791998-08-04 15:26:23 +00009058#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009059/*[clinic input]
9060os.WTERMSIG -> int
9061
9062 status: int
9063
9064Return the signal that terminated the process that provided the status value.
9065[clinic start generated code]*/
9066
Larry Hastings2f936352014-08-05 14:04:04 +10009067static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009068os_WTERMSIG_impl(PyObject *module, int status)
9069/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009070{
9071 WAIT_TYPE wait_status;
9072 WAIT_STATUS_INT(wait_status) = status;
9073 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009074}
9075#endif /* WTERMSIG */
9076
Larry Hastings2f936352014-08-05 14:04:04 +10009077
Guido van Rossumc9641791998-08-04 15:26:23 +00009078#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009079/*[clinic input]
9080os.WSTOPSIG -> int
9081
9082 status: int
9083
9084Return the signal that stopped the process that provided the status value.
9085[clinic start generated code]*/
9086
Larry Hastings2f936352014-08-05 14:04:04 +10009087static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009088os_WSTOPSIG_impl(PyObject *module, int status)
9089/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009090{
9091 WAIT_TYPE wait_status;
9092 WAIT_STATUS_INT(wait_status) = status;
9093 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009094}
9095#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009096#endif /* HAVE_SYS_WAIT_H */
9097
9098
Thomas Wouters477c8d52006-05-27 19:21:47 +00009099#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009100#ifdef _SCO_DS
9101/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9102 needed definitions in sys/statvfs.h */
9103#define _SVID3
9104#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009105#include <sys/statvfs.h>
9106
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009107static PyObject*
9108_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9110 if (v == NULL)
9111 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009112
9113#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9115 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9116 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9117 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9118 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9119 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9120 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9121 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9122 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9123 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009124#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9126 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9127 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009128 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009130 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009132 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009133 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009134 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009136 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009137 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009138 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9140 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009141#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009142 if (PyErr_Occurred()) {
9143 Py_DECREF(v);
9144 return NULL;
9145 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009146
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009148}
9149
Larry Hastings2f936352014-08-05 14:04:04 +10009150
9151/*[clinic input]
9152os.fstatvfs
9153 fd: int
9154 /
9155
9156Perform an fstatvfs system call on the given fd.
9157
9158Equivalent to statvfs(fd).
9159[clinic start generated code]*/
9160
Larry Hastings2f936352014-08-05 14:04:04 +10009161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009162os_fstatvfs_impl(PyObject *module, int fd)
9163/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009164{
9165 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009166 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009168
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009169 do {
9170 Py_BEGIN_ALLOW_THREADS
9171 result = fstatvfs(fd, &st);
9172 Py_END_ALLOW_THREADS
9173 } while (result != 0 && errno == EINTR &&
9174 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009175 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009176 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009177
Victor Stinner8c62be82010-05-06 00:08:46 +00009178 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009179}
Larry Hastings2f936352014-08-05 14:04:04 +10009180#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009181
9182
Thomas Wouters477c8d52006-05-27 19:21:47 +00009183#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009184#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009185/*[clinic input]
9186os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009187
Larry Hastings2f936352014-08-05 14:04:04 +10009188 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9189
9190Perform a statvfs system call on the given path.
9191
9192path may always be specified as a string.
9193On some platforms, path may also be specified as an open file descriptor.
9194 If this functionality is unavailable, using it raises an exception.
9195[clinic start generated code]*/
9196
Larry Hastings2f936352014-08-05 14:04:04 +10009197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009198os_statvfs_impl(PyObject *module, path_t *path)
9199/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009200{
9201 int result;
9202 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009203
9204 Py_BEGIN_ALLOW_THREADS
9205#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009206 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009207#ifdef __APPLE__
9208 /* handle weak-linking on Mac OS X 10.3 */
9209 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009210 fd_specified("statvfs", path->fd);
9211 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009212 }
9213#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009214 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009215 }
9216 else
9217#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009218 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009219 Py_END_ALLOW_THREADS
9220
9221 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009222 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009223 }
9224
Larry Hastings2f936352014-08-05 14:04:04 +10009225 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009226}
Larry Hastings2f936352014-08-05 14:04:04 +10009227#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9228
Guido van Rossum94f6f721999-01-06 18:42:14 +00009229
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009230#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009231/*[clinic input]
9232os._getdiskusage
9233
9234 path: Py_UNICODE
9235
9236Return disk usage statistics about the given path as a (total, free) tuple.
9237[clinic start generated code]*/
9238
Larry Hastings2f936352014-08-05 14:04:04 +10009239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009240os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9241/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009242{
9243 BOOL retval;
9244 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009245
9246 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009247 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009248 Py_END_ALLOW_THREADS
9249 if (retval == 0)
9250 return PyErr_SetFromWindowsErr(0);
9251
9252 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9253}
Larry Hastings2f936352014-08-05 14:04:04 +10009254#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009255
9256
Fred Drakec9680921999-12-13 16:37:25 +00009257/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9258 * It maps strings representing configuration variable names to
9259 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009260 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009261 * rarely-used constants. There are three separate tables that use
9262 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009263 *
9264 * This code is always included, even if none of the interfaces that
9265 * need it are included. The #if hackery needed to avoid it would be
9266 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009267 */
9268struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009269 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009270 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009271};
9272
Fred Drake12c6e2d1999-12-14 21:25:03 +00009273static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009274conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009275 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009276{
Christian Heimes217cfd12007-12-02 14:31:20 +00009277 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009278 int value = _PyLong_AsInt(arg);
9279 if (value == -1 && PyErr_Occurred())
9280 return 0;
9281 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009282 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009283 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009284 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009285 /* look up the value in the table using a binary search */
9286 size_t lo = 0;
9287 size_t mid;
9288 size_t hi = tablesize;
9289 int cmp;
9290 const char *confname;
9291 if (!PyUnicode_Check(arg)) {
9292 PyErr_SetString(PyExc_TypeError,
9293 "configuration names must be strings or integers");
9294 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009296 confname = _PyUnicode_AsString(arg);
9297 if (confname == NULL)
9298 return 0;
9299 while (lo < hi) {
9300 mid = (lo + hi) / 2;
9301 cmp = strcmp(confname, table[mid].name);
9302 if (cmp < 0)
9303 hi = mid;
9304 else if (cmp > 0)
9305 lo = mid + 1;
9306 else {
9307 *valuep = table[mid].value;
9308 return 1;
9309 }
9310 }
9311 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9312 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009314}
9315
9316
9317#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9318static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009319#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009321#endif
9322#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009324#endif
Fred Drakec9680921999-12-13 16:37:25 +00009325#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
9352#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009370#ifdef _PC_ACL_ENABLED
9371 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9372#endif
9373#ifdef _PC_MIN_HOLE_SIZE
9374 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9375#endif
9376#ifdef _PC_ALLOC_SIZE_MIN
9377 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9378#endif
9379#ifdef _PC_REC_INCR_XFER_SIZE
9380 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9381#endif
9382#ifdef _PC_REC_MAX_XFER_SIZE
9383 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9384#endif
9385#ifdef _PC_REC_MIN_XFER_SIZE
9386 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9387#endif
9388#ifdef _PC_REC_XFER_ALIGN
9389 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9390#endif
9391#ifdef _PC_SYMLINK_MAX
9392 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9393#endif
9394#ifdef _PC_XATTR_ENABLED
9395 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9396#endif
9397#ifdef _PC_XATTR_EXISTS
9398 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9399#endif
9400#ifdef _PC_TIMESTAMP_RESOLUTION
9401 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9402#endif
Fred Drakec9680921999-12-13 16:37:25 +00009403};
9404
Fred Drakec9680921999-12-13 16:37:25 +00009405static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009406conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009407{
9408 return conv_confname(arg, valuep, posix_constants_pathconf,
9409 sizeof(posix_constants_pathconf)
9410 / sizeof(struct constdef));
9411}
9412#endif
9413
Larry Hastings2f936352014-08-05 14:04:04 +10009414
Fred Drakec9680921999-12-13 16:37:25 +00009415#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009416/*[clinic input]
9417os.fpathconf -> long
9418
9419 fd: int
9420 name: path_confname
9421 /
9422
9423Return the configuration limit name for the file descriptor fd.
9424
9425If there is no limit, return -1.
9426[clinic start generated code]*/
9427
Larry Hastings2f936352014-08-05 14:04:04 +10009428static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009429os_fpathconf_impl(PyObject *module, int fd, int name)
9430/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009431{
9432 long limit;
9433
9434 errno = 0;
9435 limit = fpathconf(fd, name);
9436 if (limit == -1 && errno != 0)
9437 posix_error();
9438
9439 return limit;
9440}
9441#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009442
9443
9444#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009445/*[clinic input]
9446os.pathconf -> long
9447 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9448 name: path_confname
9449
9450Return the configuration limit name for the file or directory path.
9451
9452If there is no limit, return -1.
9453On some platforms, path may also be specified as an open file descriptor.
9454 If this functionality is unavailable, using it raises an exception.
9455[clinic start generated code]*/
9456
Larry Hastings2f936352014-08-05 14:04:04 +10009457static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009458os_pathconf_impl(PyObject *module, path_t *path, int name)
9459/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009460{
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009462
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009464#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009465 if (path->fd != -1)
9466 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009467 else
9468#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009469 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 if (limit == -1 && errno != 0) {
9471 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009472 /* could be a path or name problem */
9473 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009474 else
Larry Hastings2f936352014-08-05 14:04:04 +10009475 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 }
Larry Hastings2f936352014-08-05 14:04:04 +10009477
9478 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009479}
Larry Hastings2f936352014-08-05 14:04:04 +10009480#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009481
9482#ifdef HAVE_CONFSTR
9483static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009484#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009486#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009487#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009489#endif
9490#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009492#endif
Fred Draked86ed291999-12-15 15:34:33 +00009493#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009495#endif
9496#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009498#endif
9499#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009501#endif
9502#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009504#endif
Fred Drakec9680921999-12-13 16:37:25 +00009505#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009507#endif
9508#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
9511#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009513#endif
9514#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
9517#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009519#endif
9520#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009522#endif
9523#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
9526#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009528#endif
Fred Draked86ed291999-12-15 15:34:33 +00009529#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009531#endif
Fred Drakec9680921999-12-13 16:37:25 +00009532#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009534#endif
Fred Draked86ed291999-12-15 15:34:33 +00009535#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009537#endif
9538#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009540#endif
9541#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009543#endif
9544#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009546#endif
Fred Drakec9680921999-12-13 16:37:25 +00009547#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
9589#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
Fred Draked86ed291999-12-15 15:34:33 +00009595#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009597#endif
9598#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009600#endif
9601#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009603#endif
9604#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009606#endif
9607#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009609#endif
9610#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009612#endif
9613#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009615#endif
9616#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009618#endif
9619#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009621#endif
9622#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009624#endif
9625#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009627#endif
9628#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009630#endif
9631#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009633#endif
Fred Drakec9680921999-12-13 16:37:25 +00009634};
9635
9636static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009637conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009638{
9639 return conv_confname(arg, valuep, posix_constants_confstr,
9640 sizeof(posix_constants_confstr)
9641 / sizeof(struct constdef));
9642}
9643
Larry Hastings2f936352014-08-05 14:04:04 +10009644
9645/*[clinic input]
9646os.confstr
9647
9648 name: confstr_confname
9649 /
9650
9651Return a string-valued system configuration variable.
9652[clinic start generated code]*/
9653
Larry Hastings2f936352014-08-05 14:04:04 +10009654static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009655os_confstr_impl(PyObject *module, int name)
9656/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009657{
9658 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009659 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009660 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009661
Victor Stinnercb043522010-09-10 23:49:04 +00009662 errno = 0;
9663 len = confstr(name, buffer, sizeof(buffer));
9664 if (len == 0) {
9665 if (errno) {
9666 posix_error();
9667 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009668 }
9669 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009670 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009671 }
9672 }
Victor Stinnercb043522010-09-10 23:49:04 +00009673
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009674 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009675 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009676 char *buf = PyMem_Malloc(len);
9677 if (buf == NULL)
9678 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009679 len2 = confstr(name, buf, len);
9680 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009681 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009682 PyMem_Free(buf);
9683 }
9684 else
9685 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009686 return result;
9687}
Larry Hastings2f936352014-08-05 14:04:04 +10009688#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009689
9690
9691#ifdef HAVE_SYSCONF
9692static struct constdef posix_constants_sysconf[] = {
9693#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
9696#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009698#endif
9699#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
9702#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
9708#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
9714#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009716#endif
9717#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
Fred Draked86ed291999-12-15 15:34:33 +00009723#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009725#endif
9726#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009728#endif
Fred Drakec9680921999-12-13 16:37:25 +00009729#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
Fred Drakec9680921999-12-13 16:37:25 +00009732#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
Fred Draked86ed291999-12-15 15:34:33 +00009747#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009749#endif
Fred Drakec9680921999-12-13 16:37:25 +00009750#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
Fred Draked86ed291999-12-15 15:34:33 +00009765#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009767#endif
Fred Drakec9680921999-12-13 16:37:25 +00009768#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
Fred Draked86ed291999-12-15 15:34:33 +00009837#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009839#endif
Fred Drakec9680921999-12-13 16:37:25 +00009840#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
Fred Draked86ed291999-12-15 15:34:33 +00009849#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009851#endif
Fred Drakec9680921999-12-13 16:37:25 +00009852#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
Fred Draked86ed291999-12-15 15:34:33 +00009855#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009857#endif
9858#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009860#endif
Fred Drakec9680921999-12-13 16:37:25 +00009861#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
Fred Draked86ed291999-12-15 15:34:33 +00009873#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009875#endif
Fred Drakec9680921999-12-13 16:37:25 +00009876#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
Fred Draked86ed291999-12-15 15:34:33 +00009897#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009899#endif
Fred Drakec9680921999-12-13 16:37:25 +00009900#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
Fred Draked86ed291999-12-15 15:34:33 +00009906#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009908#endif
Fred Drakec9680921999-12-13 16:37:25 +00009909#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
Fred Draked86ed291999-12-15 15:34:33 +00009936#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009938#endif
9939#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009941#endif
Fred Drakec9680921999-12-13 16:37:25 +00009942#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
Fred Draked86ed291999-12-15 15:34:33 +000010047#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010049#endif
Fred Drakec9680921999-12-13 16:37:25 +000010050#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185};
10186
10187static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010188conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010189{
10190 return conv_confname(arg, valuep, posix_constants_sysconf,
10191 sizeof(posix_constants_sysconf)
10192 / sizeof(struct constdef));
10193}
10194
Larry Hastings2f936352014-08-05 14:04:04 +100010195
10196/*[clinic input]
10197os.sysconf -> long
10198 name: sysconf_confname
10199 /
10200
10201Return an integer-valued system configuration variable.
10202[clinic start generated code]*/
10203
Larry Hastings2f936352014-08-05 14:04:04 +100010204static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010205os_sysconf_impl(PyObject *module, int name)
10206/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010207{
10208 long value;
10209
10210 errno = 0;
10211 value = sysconf(name);
10212 if (value == -1 && errno != 0)
10213 posix_error();
10214 return value;
10215}
10216#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010217
10218
Fred Drakebec628d1999-12-15 18:31:10 +000010219/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010220 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010221 * the exported dictionaries that are used to publish information about the
10222 * names available on the host platform.
10223 *
10224 * Sorting the table at runtime ensures that the table is properly ordered
10225 * when used, even for platforms we're not able to test on. It also makes
10226 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010227 */
Fred Drakebec628d1999-12-15 18:31:10 +000010228
10229static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010230cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010231{
10232 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010234 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010236
10237 return strcmp(c1->name, c2->name);
10238}
10239
10240static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010241setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010242 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010243{
Fred Drakebec628d1999-12-15 18:31:10 +000010244 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010245 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010246
10247 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10248 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010249 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010251
Barry Warsaw3155db32000-04-13 15:20:40 +000010252 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 PyObject *o = PyLong_FromLong(table[i].value);
10254 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10255 Py_XDECREF(o);
10256 Py_DECREF(d);
10257 return -1;
10258 }
10259 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010260 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010261 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010262}
10263
Fred Drakebec628d1999-12-15 18:31:10 +000010264/* Return -1 on failure, 0 on success. */
10265static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010266setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010267{
10268#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010269 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010270 sizeof(posix_constants_pathconf)
10271 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010272 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010273 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010274#endif
10275#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010276 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010277 sizeof(posix_constants_confstr)
10278 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010279 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010280 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010281#endif
10282#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010283 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010284 sizeof(posix_constants_sysconf)
10285 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010286 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010287 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010288#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010289 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010290}
Fred Draked86ed291999-12-15 15:34:33 +000010291
10292
Larry Hastings2f936352014-08-05 14:04:04 +100010293/*[clinic input]
10294os.abort
10295
10296Abort the interpreter immediately.
10297
10298This function 'dumps core' or otherwise fails in the hardest way possible
10299on the hosting operating system. This function never returns.
10300[clinic start generated code]*/
10301
Larry Hastings2f936352014-08-05 14:04:04 +100010302static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010303os_abort_impl(PyObject *module)
10304/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010305{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010306 abort();
10307 /*NOTREACHED*/
10308 Py_FatalError("abort() called from Python code didn't abort!");
10309 return NULL;
10310}
Fred Drakebec628d1999-12-15 18:31:10 +000010311
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010312#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010313/* Grab ShellExecute dynamically from shell32 */
10314static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010315static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10316 LPCWSTR, INT);
10317static int
10318check_ShellExecute()
10319{
10320 HINSTANCE hShell32;
10321
10322 /* only recheck */
10323 if (-1 == has_ShellExecute) {
10324 Py_BEGIN_ALLOW_THREADS
10325 hShell32 = LoadLibraryW(L"SHELL32");
10326 Py_END_ALLOW_THREADS
10327 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010328 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10329 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010330 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010331 } else {
10332 has_ShellExecute = 0;
10333 }
10334 }
10335 return has_ShellExecute;
10336}
10337
10338
Steve Dowercc16be82016-09-08 10:35:16 -070010339/*[clinic input]
10340os.startfile
10341 filepath: path_t
10342 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010343
Steve Dowercc16be82016-09-08 10:35:16 -070010344startfile(filepath [, operation])
10345
10346Start a file with its associated application.
10347
10348When "operation" is not specified or "open", this acts like
10349double-clicking the file in Explorer, or giving the file name as an
10350argument to the DOS "start" command: the file is opened with whatever
10351application (if any) its extension is associated.
10352When another "operation" is given, it specifies what should be done with
10353the file. A typical operation is "print".
10354
10355startfile returns as soon as the associated application is launched.
10356There is no option to wait for the application to close, and no way
10357to retrieve the application's exit status.
10358
10359The filepath is relative to the current directory. If you want to use
10360an absolute path, make sure the first character is not a slash ("/");
10361the underlying Win32 ShellExecute function doesn't work if it is.
10362[clinic start generated code]*/
10363
10364static PyObject *
10365os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10366/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10367{
10368 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010369
10370 if(!check_ShellExecute()) {
10371 /* If the OS doesn't have ShellExecute, return a
10372 NotImplementedError. */
10373 return PyErr_Format(PyExc_NotImplementedError,
10374 "startfile not available on this platform");
10375 }
10376
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010378 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010379 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 Py_END_ALLOW_THREADS
10381
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010383 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010384 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 }
Steve Dowercc16be82016-09-08 10:35:16 -070010386 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010387}
Larry Hastings2f936352014-08-05 14:04:04 +100010388#endif /* MS_WINDOWS */
10389
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010390
Martin v. Löwis438b5342002-12-27 10:16:42 +000010391#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010392/*[clinic input]
10393os.getloadavg
10394
10395Return average recent system load information.
10396
10397Return the number of processes in the system run queue averaged over
10398the last 1, 5, and 15 minutes as a tuple of three floats.
10399Raises OSError if the load average was unobtainable.
10400[clinic start generated code]*/
10401
Larry Hastings2f936352014-08-05 14:04:04 +100010402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010403os_getloadavg_impl(PyObject *module)
10404/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010405{
10406 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010407 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010408 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10409 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010410 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010411 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010412}
Larry Hastings2f936352014-08-05 14:04:04 +100010413#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010414
Larry Hastings2f936352014-08-05 14:04:04 +100010415
10416/*[clinic input]
10417os.device_encoding
10418 fd: int
10419
10420Return a string describing the encoding of a terminal's file descriptor.
10421
10422The file descriptor must be attached to a terminal.
10423If the device is not a terminal, return None.
10424[clinic start generated code]*/
10425
Larry Hastings2f936352014-08-05 14:04:04 +100010426static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010427os_device_encoding_impl(PyObject *module, int fd)
10428/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010429{
Brett Cannonefb00c02012-02-29 18:31:31 -050010430 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010431}
10432
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010433
Larry Hastings2f936352014-08-05 14:04:04 +100010434#ifdef HAVE_SETRESUID
10435/*[clinic input]
10436os.setresuid
10437
10438 ruid: uid_t
10439 euid: uid_t
10440 suid: uid_t
10441 /
10442
10443Set the current process's real, effective, and saved user ids.
10444[clinic start generated code]*/
10445
Larry Hastings2f936352014-08-05 14:04:04 +100010446static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010447os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10448/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010449{
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 if (setresuid(ruid, euid, suid) < 0)
10451 return posix_error();
10452 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010453}
Larry Hastings2f936352014-08-05 14:04:04 +100010454#endif /* HAVE_SETRESUID */
10455
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010456
10457#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010458/*[clinic input]
10459os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010460
Larry Hastings2f936352014-08-05 14:04:04 +100010461 rgid: gid_t
10462 egid: gid_t
10463 sgid: gid_t
10464 /
10465
10466Set the current process's real, effective, and saved group ids.
10467[clinic start generated code]*/
10468
Larry Hastings2f936352014-08-05 14:04:04 +100010469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010470os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10471/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010472{
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 if (setresgid(rgid, egid, sgid) < 0)
10474 return posix_error();
10475 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010476}
Larry Hastings2f936352014-08-05 14:04:04 +100010477#endif /* HAVE_SETRESGID */
10478
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010479
10480#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010481/*[clinic input]
10482os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010483
Larry Hastings2f936352014-08-05 14:04:04 +100010484Return a tuple of the current process's real, effective, and saved user ids.
10485[clinic start generated code]*/
10486
Larry Hastings2f936352014-08-05 14:04:04 +100010487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010488os_getresuid_impl(PyObject *module)
10489/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010490{
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 if (getresuid(&ruid, &euid, &suid) < 0)
10493 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010494 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10495 _PyLong_FromUid(euid),
10496 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010497}
Larry Hastings2f936352014-08-05 14:04:04 +100010498#endif /* HAVE_GETRESUID */
10499
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010500
10501#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010502/*[clinic input]
10503os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010504
Larry Hastings2f936352014-08-05 14:04:04 +100010505Return a tuple of the current process's real, effective, and saved group ids.
10506[clinic start generated code]*/
10507
Larry Hastings2f936352014-08-05 14:04:04 +100010508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010509os_getresgid_impl(PyObject *module)
10510/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010511{
10512 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 if (getresgid(&rgid, &egid, &sgid) < 0)
10514 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010515 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10516 _PyLong_FromGid(egid),
10517 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010518}
Larry Hastings2f936352014-08-05 14:04:04 +100010519#endif /* HAVE_GETRESGID */
10520
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010521
Benjamin Peterson9428d532011-09-14 11:45:52 -040010522#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010523/*[clinic input]
10524os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010525
Larry Hastings2f936352014-08-05 14:04:04 +100010526 path: path_t(allow_fd=True)
10527 attribute: path_t
10528 *
10529 follow_symlinks: bool = True
10530
10531Return the value of extended attribute attribute on path.
10532
10533path may be either a string or an open file descriptor.
10534If follow_symlinks is False, and the last element of the path is a symbolic
10535 link, getxattr will examine the symbolic link itself instead of the file
10536 the link points to.
10537
10538[clinic start generated code]*/
10539
Larry Hastings2f936352014-08-05 14:04:04 +100010540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010541os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010542 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010543/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010544{
10545 Py_ssize_t i;
10546 PyObject *buffer = NULL;
10547
10548 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10549 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010550
Larry Hastings9cf065c2012-06-22 16:30:09 -070010551 for (i = 0; ; i++) {
10552 void *ptr;
10553 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010554 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010555 Py_ssize_t buffer_size = buffer_sizes[i];
10556 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010557 path_error(path);
10558 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010559 }
10560 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10561 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010562 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010563 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010564
Larry Hastings9cf065c2012-06-22 16:30:09 -070010565 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010566 if (path->fd >= 0)
10567 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010568 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010569 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570 else
Larry Hastings2f936352014-08-05 14:04:04 +100010571 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010572 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010573
Larry Hastings9cf065c2012-06-22 16:30:09 -070010574 if (result < 0) {
10575 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010576 if (errno == ERANGE)
10577 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010578 path_error(path);
10579 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010580 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010581
Larry Hastings9cf065c2012-06-22 16:30:09 -070010582 if (result != buffer_size) {
10583 /* Can only shrink. */
10584 _PyBytes_Resize(&buffer, result);
10585 }
10586 break;
10587 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010588
Larry Hastings9cf065c2012-06-22 16:30:09 -070010589 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010590}
10591
Larry Hastings2f936352014-08-05 14:04:04 +100010592
10593/*[clinic input]
10594os.setxattr
10595
10596 path: path_t(allow_fd=True)
10597 attribute: path_t
10598 value: Py_buffer
10599 flags: int = 0
10600 *
10601 follow_symlinks: bool = True
10602
10603Set extended attribute attribute on path to value.
10604
10605path may be either a string or an open file descriptor.
10606If follow_symlinks is False, and the last element of the path is a symbolic
10607 link, setxattr will modify the symbolic link itself instead of the file
10608 the link points to.
10609
10610[clinic start generated code]*/
10611
Benjamin Peterson799bd802011-08-31 22:15:17 -040010612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010613os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010614 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010615/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010616{
Larry Hastings2f936352014-08-05 14:04:04 +100010617 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010618
Larry Hastings2f936352014-08-05 14:04:04 +100010619 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010620 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010623 if (path->fd > -1)
10624 result = fsetxattr(path->fd, attribute->narrow,
10625 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010626 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010627 result = setxattr(path->narrow, attribute->narrow,
10628 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010629 else
Larry Hastings2f936352014-08-05 14:04:04 +100010630 result = lsetxattr(path->narrow, attribute->narrow,
10631 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010632 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010633
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010635 path_error(path);
10636 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010637 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010638
Larry Hastings2f936352014-08-05 14:04:04 +100010639 Py_RETURN_NONE;
10640}
10641
10642
10643/*[clinic input]
10644os.removexattr
10645
10646 path: path_t(allow_fd=True)
10647 attribute: path_t
10648 *
10649 follow_symlinks: bool = True
10650
10651Remove extended attribute attribute on path.
10652
10653path may be either a string or an open file descriptor.
10654If follow_symlinks is False, and the last element of the path is a symbolic
10655 link, removexattr will modify the symbolic link itself instead of the file
10656 the link points to.
10657
10658[clinic start generated code]*/
10659
Larry Hastings2f936352014-08-05 14:04:04 +100010660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010661os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010662 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010663/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010664{
10665 ssize_t result;
10666
10667 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10668 return NULL;
10669
10670 Py_BEGIN_ALLOW_THREADS;
10671 if (path->fd > -1)
10672 result = fremovexattr(path->fd, attribute->narrow);
10673 else if (follow_symlinks)
10674 result = removexattr(path->narrow, attribute->narrow);
10675 else
10676 result = lremovexattr(path->narrow, attribute->narrow);
10677 Py_END_ALLOW_THREADS;
10678
10679 if (result) {
10680 return path_error(path);
10681 }
10682
10683 Py_RETURN_NONE;
10684}
10685
10686
10687/*[clinic input]
10688os.listxattr
10689
10690 path: path_t(allow_fd=True, nullable=True) = None
10691 *
10692 follow_symlinks: bool = True
10693
10694Return a list of extended attributes on path.
10695
10696path may be either None, a string, or an open file descriptor.
10697if path is None, listxattr will examine the current directory.
10698If follow_symlinks is False, and the last element of the path is a symbolic
10699 link, listxattr will examine the symbolic link itself instead of the file
10700 the link points to.
10701[clinic start generated code]*/
10702
Larry Hastings2f936352014-08-05 14:04:04 +100010703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010704os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10705/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010706{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010707 Py_ssize_t i;
10708 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010709 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010710 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010711
Larry Hastings2f936352014-08-05 14:04:04 +100010712 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010713 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010714
Larry Hastings2f936352014-08-05 14:04:04 +100010715 name = path->narrow ? path->narrow : ".";
10716
Larry Hastings9cf065c2012-06-22 16:30:09 -070010717 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010718 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010719 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010720 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010721 Py_ssize_t buffer_size = buffer_sizes[i];
10722 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010723 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010724 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010725 break;
10726 }
10727 buffer = PyMem_MALLOC(buffer_size);
10728 if (!buffer) {
10729 PyErr_NoMemory();
10730 break;
10731 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010732
Larry Hastings9cf065c2012-06-22 16:30:09 -070010733 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010734 if (path->fd > -1)
10735 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010736 else if (follow_symlinks)
10737 length = listxattr(name, buffer, buffer_size);
10738 else
10739 length = llistxattr(name, buffer, buffer_size);
10740 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010741
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010743 if (errno == ERANGE) {
10744 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010745 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010746 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010747 }
Larry Hastings2f936352014-08-05 14:04:04 +100010748 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 break;
10750 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010751
Larry Hastings9cf065c2012-06-22 16:30:09 -070010752 result = PyList_New(0);
10753 if (!result) {
10754 goto exit;
10755 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010756
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 end = buffer + length;
10758 for (trace = start = buffer; trace != end; trace++) {
10759 if (!*trace) {
10760 int error;
10761 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10762 trace - start);
10763 if (!attribute) {
10764 Py_DECREF(result);
10765 result = NULL;
10766 goto exit;
10767 }
10768 error = PyList_Append(result, attribute);
10769 Py_DECREF(attribute);
10770 if (error) {
10771 Py_DECREF(result);
10772 result = NULL;
10773 goto exit;
10774 }
10775 start = trace + 1;
10776 }
10777 }
10778 break;
10779 }
10780exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 if (buffer)
10782 PyMem_FREE(buffer);
10783 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010784}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010785#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010786
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010787
Larry Hastings2f936352014-08-05 14:04:04 +100010788/*[clinic input]
10789os.urandom
10790
10791 size: Py_ssize_t
10792 /
10793
10794Return a bytes object containing random bytes suitable for cryptographic use.
10795[clinic start generated code]*/
10796
Larry Hastings2f936352014-08-05 14:04:04 +100010797static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010798os_urandom_impl(PyObject *module, Py_ssize_t size)
10799/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010800{
10801 PyObject *bytes;
10802 int result;
10803
Georg Brandl2fb477c2012-02-21 00:33:36 +010010804 if (size < 0)
10805 return PyErr_Format(PyExc_ValueError,
10806 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010807 bytes = PyBytes_FromStringAndSize(NULL, size);
10808 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010809 return NULL;
10810
Victor Stinnere66987e2016-09-06 16:33:52 -070010811 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010812 if (result == -1) {
10813 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010814 return NULL;
10815 }
Larry Hastings2f936352014-08-05 14:04:04 +100010816 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010817}
10818
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010819/* Terminal size querying */
10820
10821static PyTypeObject TerminalSizeType;
10822
10823PyDoc_STRVAR(TerminalSize_docstring,
10824 "A tuple of (columns, lines) for holding terminal window size");
10825
10826static PyStructSequence_Field TerminalSize_fields[] = {
10827 {"columns", "width of the terminal window in characters"},
10828 {"lines", "height of the terminal window in characters"},
10829 {NULL, NULL}
10830};
10831
10832static PyStructSequence_Desc TerminalSize_desc = {
10833 "os.terminal_size",
10834 TerminalSize_docstring,
10835 TerminalSize_fields,
10836 2,
10837};
10838
10839#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010840/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010841PyDoc_STRVAR(termsize__doc__,
10842 "Return the size of the terminal window as (columns, lines).\n" \
10843 "\n" \
10844 "The optional argument fd (default standard output) specifies\n" \
10845 "which file descriptor should be queried.\n" \
10846 "\n" \
10847 "If the file descriptor is not connected to a terminal, an OSError\n" \
10848 "is thrown.\n" \
10849 "\n" \
10850 "This function will only be defined if an implementation is\n" \
10851 "available for this system.\n" \
10852 "\n" \
10853 "shutil.get_terminal_size is the high-level function which should \n" \
10854 "normally be used, os.get_terminal_size is the low-level implementation.");
10855
10856static PyObject*
10857get_terminal_size(PyObject *self, PyObject *args)
10858{
10859 int columns, lines;
10860 PyObject *termsize;
10861
10862 int fd = fileno(stdout);
10863 /* Under some conditions stdout may not be connected and
10864 * fileno(stdout) may point to an invalid file descriptor. For example
10865 * GUI apps don't have valid standard streams by default.
10866 *
10867 * If this happens, and the optional fd argument is not present,
10868 * the ioctl below will fail returning EBADF. This is what we want.
10869 */
10870
10871 if (!PyArg_ParseTuple(args, "|i", &fd))
10872 return NULL;
10873
10874#ifdef TERMSIZE_USE_IOCTL
10875 {
10876 struct winsize w;
10877 if (ioctl(fd, TIOCGWINSZ, &w))
10878 return PyErr_SetFromErrno(PyExc_OSError);
10879 columns = w.ws_col;
10880 lines = w.ws_row;
10881 }
10882#endif /* TERMSIZE_USE_IOCTL */
10883
10884#ifdef TERMSIZE_USE_CONIO
10885 {
10886 DWORD nhandle;
10887 HANDLE handle;
10888 CONSOLE_SCREEN_BUFFER_INFO csbi;
10889 switch (fd) {
10890 case 0: nhandle = STD_INPUT_HANDLE;
10891 break;
10892 case 1: nhandle = STD_OUTPUT_HANDLE;
10893 break;
10894 case 2: nhandle = STD_ERROR_HANDLE;
10895 break;
10896 default:
10897 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10898 }
10899 handle = GetStdHandle(nhandle);
10900 if (handle == NULL)
10901 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10902 if (handle == INVALID_HANDLE_VALUE)
10903 return PyErr_SetFromWindowsErr(0);
10904
10905 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10906 return PyErr_SetFromWindowsErr(0);
10907
10908 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10909 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10910 }
10911#endif /* TERMSIZE_USE_CONIO */
10912
10913 termsize = PyStructSequence_New(&TerminalSizeType);
10914 if (termsize == NULL)
10915 return NULL;
10916 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10917 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10918 if (PyErr_Occurred()) {
10919 Py_DECREF(termsize);
10920 return NULL;
10921 }
10922 return termsize;
10923}
10924#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10925
Larry Hastings2f936352014-08-05 14:04:04 +100010926
10927/*[clinic input]
10928os.cpu_count
10929
Charles-François Natali80d62e62015-08-13 20:37:08 +010010930Return the number of CPUs in the system; return None if indeterminable.
10931
10932This number is not equivalent to the number of CPUs the current process can
10933use. The number of usable CPUs can be obtained with
10934``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010935[clinic start generated code]*/
10936
Larry Hastings2f936352014-08-05 14:04:04 +100010937static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010938os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010939/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010940{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010941 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010942#ifdef MS_WINDOWS
10943 SYSTEM_INFO sysinfo;
10944 GetSystemInfo(&sysinfo);
10945 ncpu = sysinfo.dwNumberOfProcessors;
10946#elif defined(__hpux)
10947 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10948#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10949 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010950#elif defined(__DragonFly__) || \
10951 defined(__OpenBSD__) || \
10952 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010953 defined(__NetBSD__) || \
10954 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010955 int mib[2];
10956 size_t len = sizeof(ncpu);
10957 mib[0] = CTL_HW;
10958 mib[1] = HW_NCPU;
10959 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10960 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010961#endif
10962 if (ncpu >= 1)
10963 return PyLong_FromLong(ncpu);
10964 else
10965 Py_RETURN_NONE;
10966}
10967
Victor Stinnerdaf45552013-08-28 00:53:59 +020010968
Larry Hastings2f936352014-08-05 14:04:04 +100010969/*[clinic input]
10970os.get_inheritable -> bool
10971
10972 fd: int
10973 /
10974
10975Get the close-on-exe flag of the specified file descriptor.
10976[clinic start generated code]*/
10977
Larry Hastings2f936352014-08-05 14:04:04 +100010978static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010979os_get_inheritable_impl(PyObject *module, int fd)
10980/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010981{
Steve Dower8fc89802015-04-12 00:26:27 -040010982 int return_value;
10983 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100010984 posix_error();
10985 return -1;
10986 }
10987
Steve Dower8fc89802015-04-12 00:26:27 -040010988 _Py_BEGIN_SUPPRESS_IPH
10989 return_value = _Py_get_inheritable(fd);
10990 _Py_END_SUPPRESS_IPH
10991 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010992}
10993
10994
10995/*[clinic input]
10996os.set_inheritable
10997 fd: int
10998 inheritable: int
10999 /
11000
11001Set the inheritable flag of the specified file descriptor.
11002[clinic start generated code]*/
11003
Larry Hastings2f936352014-08-05 14:04:04 +100011004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011005os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11006/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011007{
Steve Dower8fc89802015-04-12 00:26:27 -040011008 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011009 if (!_PyVerify_fd(fd))
11010 return posix_error();
11011
Steve Dower8fc89802015-04-12 00:26:27 -040011012 _Py_BEGIN_SUPPRESS_IPH
11013 result = _Py_set_inheritable(fd, inheritable, NULL);
11014 _Py_END_SUPPRESS_IPH
11015 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011016 return NULL;
11017 Py_RETURN_NONE;
11018}
11019
11020
11021#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011022/*[clinic input]
11023os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011024 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011025 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011026
Larry Hastings2f936352014-08-05 14:04:04 +100011027Get the close-on-exe flag of the specified file descriptor.
11028[clinic start generated code]*/
11029
Larry Hastings2f936352014-08-05 14:04:04 +100011030static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011031os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011032/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011033{
11034 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011035
11036 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11037 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011038 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011039 }
11040
Larry Hastings2f936352014-08-05 14:04:04 +100011041 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011042}
11043
Victor Stinnerdaf45552013-08-28 00:53:59 +020011044
Larry Hastings2f936352014-08-05 14:04:04 +100011045/*[clinic input]
11046os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011047 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011048 inheritable: bool
11049 /
11050
11051Set the inheritable flag of the specified handle.
11052[clinic start generated code]*/
11053
Larry Hastings2f936352014-08-05 14:04:04 +100011054static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011055os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011056 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011057/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011058{
11059 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011060 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11061 PyErr_SetFromWindowsErr(0);
11062 return NULL;
11063 }
11064 Py_RETURN_NONE;
11065}
Larry Hastings2f936352014-08-05 14:04:04 +100011066#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011067
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011068#ifndef MS_WINDOWS
11069PyDoc_STRVAR(get_blocking__doc__,
11070 "get_blocking(fd) -> bool\n" \
11071 "\n" \
11072 "Get the blocking mode of the file descriptor:\n" \
11073 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11074
11075static PyObject*
11076posix_get_blocking(PyObject *self, PyObject *args)
11077{
11078 int fd;
11079 int blocking;
11080
11081 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11082 return NULL;
11083
11084 if (!_PyVerify_fd(fd))
11085 return posix_error();
11086
Steve Dower8fc89802015-04-12 00:26:27 -040011087 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011088 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011089 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011090 if (blocking < 0)
11091 return NULL;
11092 return PyBool_FromLong(blocking);
11093}
11094
11095PyDoc_STRVAR(set_blocking__doc__,
11096 "set_blocking(fd, blocking)\n" \
11097 "\n" \
11098 "Set the blocking mode of the specified file descriptor.\n" \
11099 "Set the O_NONBLOCK flag if blocking is False,\n" \
11100 "clear the O_NONBLOCK flag otherwise.");
11101
11102static PyObject*
11103posix_set_blocking(PyObject *self, PyObject *args)
11104{
Steve Dower8fc89802015-04-12 00:26:27 -040011105 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011106
11107 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11108 return NULL;
11109
11110 if (!_PyVerify_fd(fd))
11111 return posix_error();
11112
Steve Dower8fc89802015-04-12 00:26:27 -040011113 _Py_BEGIN_SUPPRESS_IPH
11114 result = _Py_set_blocking(fd, blocking);
11115 _Py_END_SUPPRESS_IPH
11116 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011117 return NULL;
11118 Py_RETURN_NONE;
11119}
11120#endif /* !MS_WINDOWS */
11121
11122
Victor Stinner6036e442015-03-08 01:58:04 +010011123PyDoc_STRVAR(posix_scandir__doc__,
11124"scandir(path='.') -> iterator of DirEntry objects for given path");
11125
11126static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11127
11128typedef struct {
11129 PyObject_HEAD
11130 PyObject *name;
11131 PyObject *path;
11132 PyObject *stat;
11133 PyObject *lstat;
11134#ifdef MS_WINDOWS
11135 struct _Py_stat_struct win32_lstat;
11136 __int64 win32_file_index;
11137 int got_file_index;
11138#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011139#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011140 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011141#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011142 ino_t d_ino;
11143#endif
11144} DirEntry;
11145
11146static void
11147DirEntry_dealloc(DirEntry *entry)
11148{
11149 Py_XDECREF(entry->name);
11150 Py_XDECREF(entry->path);
11151 Py_XDECREF(entry->stat);
11152 Py_XDECREF(entry->lstat);
11153 Py_TYPE(entry)->tp_free((PyObject *)entry);
11154}
11155
11156/* Forward reference */
11157static int
11158DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11159
11160/* Set exception and return -1 on error, 0 for False, 1 for True */
11161static int
11162DirEntry_is_symlink(DirEntry *self)
11163{
11164#ifdef MS_WINDOWS
11165 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011166#elif defined(HAVE_DIRENT_D_TYPE)
11167 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011168 if (self->d_type != DT_UNKNOWN)
11169 return self->d_type == DT_LNK;
11170 else
11171 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011172#else
11173 /* POSIX without d_type */
11174 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011175#endif
11176}
11177
11178static PyObject *
11179DirEntry_py_is_symlink(DirEntry *self)
11180{
11181 int result;
11182
11183 result = DirEntry_is_symlink(self);
11184 if (result == -1)
11185 return NULL;
11186 return PyBool_FromLong(result);
11187}
11188
11189static PyObject *
11190DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11191{
11192 int result;
11193 struct _Py_stat_struct st;
11194
11195#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011196 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011197
11198 path = PyUnicode_AsUnicode(self->path);
11199 if (!path)
11200 return NULL;
11201
11202 if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -070011203 result = win32_stat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011204 else
Steve Dowercc16be82016-09-08 10:35:16 -070011205 result = win32_lstat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011206
11207 if (result != 0) {
11208 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11209 0, self->path);
11210 }
11211#else /* POSIX */
11212 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011213 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011214
11215 if (!PyUnicode_FSConverter(self->path, &bytes))
11216 return NULL;
11217 path = PyBytes_AS_STRING(bytes);
11218
11219 if (follow_symlinks)
11220 result = STAT(path, &st);
11221 else
11222 result = LSTAT(path, &st);
11223 Py_DECREF(bytes);
11224
11225 if (result != 0)
11226 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11227#endif
11228
11229 return _pystat_fromstructstat(&st);
11230}
11231
11232static PyObject *
11233DirEntry_get_lstat(DirEntry *self)
11234{
11235 if (!self->lstat) {
11236#ifdef MS_WINDOWS
11237 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11238#else /* POSIX */
11239 self->lstat = DirEntry_fetch_stat(self, 0);
11240#endif
11241 }
11242 Py_XINCREF(self->lstat);
11243 return self->lstat;
11244}
11245
11246static PyObject *
11247DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11248{
11249 if (!follow_symlinks)
11250 return DirEntry_get_lstat(self);
11251
11252 if (!self->stat) {
11253 int result = DirEntry_is_symlink(self);
11254 if (result == -1)
11255 return NULL;
11256 else if (result)
11257 self->stat = DirEntry_fetch_stat(self, 1);
11258 else
11259 self->stat = DirEntry_get_lstat(self);
11260 }
11261
11262 Py_XINCREF(self->stat);
11263 return self->stat;
11264}
11265
11266static PyObject *
11267DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11268{
11269 int follow_symlinks = 1;
11270
11271 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11272 follow_symlinks_keywords, &follow_symlinks))
11273 return NULL;
11274
11275 return DirEntry_get_stat(self, follow_symlinks);
11276}
11277
11278/* 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
Victor Stinner6036e442015-03-08 01:58:04 +010011306 stat = DirEntry_get_stat(self, follow_symlinks);
11307 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
11357static PyObject *
11358DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11359{
11360 int result;
11361
11362 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11363 if (result == -1)
11364 return NULL;
11365 return PyBool_FromLong(result);
11366}
11367
11368static PyObject *
11369DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11370{
11371 int follow_symlinks = 1;
11372
11373 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11374 follow_symlinks_keywords, &follow_symlinks))
11375 return NULL;
11376
11377 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11378}
11379
11380static PyObject *
11381DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11382{
11383 int follow_symlinks = 1;
11384
11385 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11386 follow_symlinks_keywords, &follow_symlinks))
11387 return NULL;
11388
11389 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11390}
11391
11392static PyObject *
11393DirEntry_inode(DirEntry *self)
11394{
11395#ifdef MS_WINDOWS
11396 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011397 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011398 struct _Py_stat_struct stat;
11399
11400 path = PyUnicode_AsUnicode(self->path);
11401 if (!path)
11402 return NULL;
11403
Steve Dowercc16be82016-09-08 10:35:16 -070011404 if (win32_lstat(path, &stat) != 0) {
Victor Stinner6036e442015-03-08 01:58:04 +010011405 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11406 0, self->path);
11407 }
11408
11409 self->win32_file_index = stat.st_ino;
11410 self->got_file_index = 1;
11411 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011412 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011413#else /* POSIX */
11414#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011415 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011416#else
11417 return PyLong_FromLong((long)self->d_ino);
11418#endif
11419#endif
11420}
11421
11422static PyObject *
11423DirEntry_repr(DirEntry *self)
11424{
11425 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11426}
11427
Brett Cannon96881cd2016-06-10 14:37:21 -070011428static PyObject *
11429DirEntry_fspath(DirEntry *self)
11430{
11431 Py_INCREF(self->path);
11432 return self->path;
11433}
11434
Victor Stinner6036e442015-03-08 01:58:04 +010011435static PyMemberDef DirEntry_members[] = {
11436 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11437 "the entry's base filename, relative to scandir() \"path\" argument"},
11438 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11439 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11440 {NULL}
11441};
11442
11443static PyMethodDef DirEntry_methods[] = {
11444 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11445 "return True if the entry is a directory; cached per entry"
11446 },
11447 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11448 "return True if the entry is a file; cached per entry"
11449 },
11450 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11451 "return True if the entry is a symbolic link; cached per entry"
11452 },
11453 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11454 "return stat_result object for the entry; cached per entry"
11455 },
11456 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11457 "return inode of the entry; cached per entry",
11458 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011459 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11460 "returns the path for the entry",
11461 },
Victor Stinner6036e442015-03-08 01:58:04 +010011462 {NULL}
11463};
11464
Benjamin Peterson5646de42015-04-12 17:56:34 -040011465static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011466 PyVarObject_HEAD_INIT(NULL, 0)
11467 MODNAME ".DirEntry", /* tp_name */
11468 sizeof(DirEntry), /* tp_basicsize */
11469 0, /* tp_itemsize */
11470 /* methods */
11471 (destructor)DirEntry_dealloc, /* tp_dealloc */
11472 0, /* tp_print */
11473 0, /* tp_getattr */
11474 0, /* tp_setattr */
11475 0, /* tp_compare */
11476 (reprfunc)DirEntry_repr, /* tp_repr */
11477 0, /* tp_as_number */
11478 0, /* tp_as_sequence */
11479 0, /* tp_as_mapping */
11480 0, /* tp_hash */
11481 0, /* tp_call */
11482 0, /* tp_str */
11483 0, /* tp_getattro */
11484 0, /* tp_setattro */
11485 0, /* tp_as_buffer */
11486 Py_TPFLAGS_DEFAULT, /* tp_flags */
11487 0, /* tp_doc */
11488 0, /* tp_traverse */
11489 0, /* tp_clear */
11490 0, /* tp_richcompare */
11491 0, /* tp_weaklistoffset */
11492 0, /* tp_iter */
11493 0, /* tp_iternext */
11494 DirEntry_methods, /* tp_methods */
11495 DirEntry_members, /* tp_members */
11496};
11497
11498#ifdef MS_WINDOWS
11499
11500static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011501join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011502{
11503 Py_ssize_t path_len;
11504 Py_ssize_t size;
11505 wchar_t *result;
11506 wchar_t ch;
11507
11508 if (!path_wide) { /* Default arg: "." */
11509 path_wide = L".";
11510 path_len = 1;
11511 }
11512 else {
11513 path_len = wcslen(path_wide);
11514 }
11515
11516 /* The +1's are for the path separator and the NUL */
11517 size = path_len + 1 + wcslen(filename) + 1;
11518 result = PyMem_New(wchar_t, size);
11519 if (!result) {
11520 PyErr_NoMemory();
11521 return NULL;
11522 }
11523 wcscpy(result, path_wide);
11524 if (path_len > 0) {
11525 ch = result[path_len - 1];
11526 if (ch != SEP && ch != ALTSEP && ch != L':')
11527 result[path_len++] = SEP;
11528 wcscpy(result + path_len, filename);
11529 }
11530 return result;
11531}
11532
11533static PyObject *
11534DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11535{
11536 DirEntry *entry;
11537 BY_HANDLE_FILE_INFORMATION file_info;
11538 ULONG reparse_tag;
11539 wchar_t *joined_path;
11540
11541 entry = PyObject_New(DirEntry, &DirEntryType);
11542 if (!entry)
11543 return NULL;
11544 entry->name = NULL;
11545 entry->path = NULL;
11546 entry->stat = NULL;
11547 entry->lstat = NULL;
11548 entry->got_file_index = 0;
11549
11550 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11551 if (!entry->name)
11552 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011553 if (path->narrow) {
11554 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11555 if (!entry->name)
11556 goto error;
11557 }
Victor Stinner6036e442015-03-08 01:58:04 +010011558
11559 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11560 if (!joined_path)
11561 goto error;
11562
11563 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11564 PyMem_Free(joined_path);
11565 if (!entry->path)
11566 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011567 if (path->narrow) {
11568 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11569 if (!entry->path)
11570 goto error;
11571 }
Victor Stinner6036e442015-03-08 01:58:04 +010011572
Steve Dowercc16be82016-09-08 10:35:16 -070011573 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011574 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11575
11576 return (PyObject *)entry;
11577
11578error:
11579 Py_DECREF(entry);
11580 return NULL;
11581}
11582
11583#else /* POSIX */
11584
11585static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011586join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011587{
11588 Py_ssize_t path_len;
11589 Py_ssize_t size;
11590 char *result;
11591
11592 if (!path_narrow) { /* Default arg: "." */
11593 path_narrow = ".";
11594 path_len = 1;
11595 }
11596 else {
11597 path_len = strlen(path_narrow);
11598 }
11599
11600 if (filename_len == -1)
11601 filename_len = strlen(filename);
11602
11603 /* The +1's are for the path separator and the NUL */
11604 size = path_len + 1 + filename_len + 1;
11605 result = PyMem_New(char, size);
11606 if (!result) {
11607 PyErr_NoMemory();
11608 return NULL;
11609 }
11610 strcpy(result, path_narrow);
11611 if (path_len > 0 && result[path_len - 1] != '/')
11612 result[path_len++] = '/';
11613 strcpy(result + path_len, filename);
11614 return result;
11615}
11616
11617static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011618DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011619 ino_t d_ino
11620#ifdef HAVE_DIRENT_D_TYPE
11621 , unsigned char d_type
11622#endif
11623 )
Victor Stinner6036e442015-03-08 01:58:04 +010011624{
11625 DirEntry *entry;
11626 char *joined_path;
11627
11628 entry = PyObject_New(DirEntry, &DirEntryType);
11629 if (!entry)
11630 return NULL;
11631 entry->name = NULL;
11632 entry->path = NULL;
11633 entry->stat = NULL;
11634 entry->lstat = NULL;
11635
11636 joined_path = join_path_filename(path->narrow, name, name_len);
11637 if (!joined_path)
11638 goto error;
11639
11640 if (!path->narrow || !PyBytes_Check(path->object)) {
11641 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11642 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11643 }
11644 else {
11645 entry->name = PyBytes_FromStringAndSize(name, name_len);
11646 entry->path = PyBytes_FromString(joined_path);
11647 }
11648 PyMem_Free(joined_path);
11649 if (!entry->name || !entry->path)
11650 goto error;
11651
Victor Stinner35a97c02015-03-08 02:59:09 +010011652#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011653 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011654#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011655 entry->d_ino = d_ino;
11656
11657 return (PyObject *)entry;
11658
11659error:
11660 Py_XDECREF(entry);
11661 return NULL;
11662}
11663
11664#endif
11665
11666
11667typedef struct {
11668 PyObject_HEAD
11669 path_t path;
11670#ifdef MS_WINDOWS
11671 HANDLE handle;
11672 WIN32_FIND_DATAW file_data;
11673 int first_time;
11674#else /* POSIX */
11675 DIR *dirp;
11676#endif
11677} ScandirIterator;
11678
11679#ifdef MS_WINDOWS
11680
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011681static int
11682ScandirIterator_is_closed(ScandirIterator *iterator)
11683{
11684 return iterator->handle == INVALID_HANDLE_VALUE;
11685}
11686
Victor Stinner6036e442015-03-08 01:58:04 +010011687static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011688ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011689{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011690 HANDLE handle = iterator->handle;
11691
11692 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011693 return;
11694
Victor Stinner6036e442015-03-08 01:58:04 +010011695 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011696 Py_BEGIN_ALLOW_THREADS
11697 FindClose(handle);
11698 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011699}
11700
11701static PyObject *
11702ScandirIterator_iternext(ScandirIterator *iterator)
11703{
11704 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11705 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011706 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011707
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011708 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011709 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011710 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011711
11712 while (1) {
11713 if (!iterator->first_time) {
11714 Py_BEGIN_ALLOW_THREADS
11715 success = FindNextFileW(iterator->handle, file_data);
11716 Py_END_ALLOW_THREADS
11717 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011718 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011719 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011720 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011721 break;
11722 }
11723 }
11724 iterator->first_time = 0;
11725
11726 /* Skip over . and .. */
11727 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011728 wcscmp(file_data->cFileName, L"..") != 0) {
11729 entry = DirEntry_from_find_data(&iterator->path, file_data);
11730 if (!entry)
11731 break;
11732 return entry;
11733 }
Victor Stinner6036e442015-03-08 01:58:04 +010011734
11735 /* Loop till we get a non-dot directory or finish iterating */
11736 }
11737
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011738 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011739 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011740 return NULL;
11741}
11742
11743#else /* POSIX */
11744
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011745static int
11746ScandirIterator_is_closed(ScandirIterator *iterator)
11747{
11748 return !iterator->dirp;
11749}
11750
Victor Stinner6036e442015-03-08 01:58:04 +010011751static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011752ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011753{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011754 DIR *dirp = iterator->dirp;
11755
11756 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011757 return;
11758
Victor Stinner6036e442015-03-08 01:58:04 +010011759 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011760 Py_BEGIN_ALLOW_THREADS
11761 closedir(dirp);
11762 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011763 return;
11764}
11765
11766static PyObject *
11767ScandirIterator_iternext(ScandirIterator *iterator)
11768{
11769 struct dirent *direntp;
11770 Py_ssize_t name_len;
11771 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011772 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011773
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011774 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011775 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011776 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011777
11778 while (1) {
11779 errno = 0;
11780 Py_BEGIN_ALLOW_THREADS
11781 direntp = readdir(iterator->dirp);
11782 Py_END_ALLOW_THREADS
11783
11784 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011785 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011786 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011787 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011788 break;
11789 }
11790
11791 /* Skip over . and .. */
11792 name_len = NAMLEN(direntp);
11793 is_dot = direntp->d_name[0] == '.' &&
11794 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11795 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011796 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011797 name_len, direntp->d_ino
11798#ifdef HAVE_DIRENT_D_TYPE
11799 , direntp->d_type
11800#endif
11801 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011802 if (!entry)
11803 break;
11804 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011805 }
11806
11807 /* Loop till we get a non-dot directory or finish iterating */
11808 }
11809
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011810 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011811 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011812 return NULL;
11813}
11814
11815#endif
11816
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011817static PyObject *
11818ScandirIterator_close(ScandirIterator *self, PyObject *args)
11819{
11820 ScandirIterator_closedir(self);
11821 Py_RETURN_NONE;
11822}
11823
11824static PyObject *
11825ScandirIterator_enter(PyObject *self, PyObject *args)
11826{
11827 Py_INCREF(self);
11828 return self;
11829}
11830
11831static PyObject *
11832ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11833{
11834 ScandirIterator_closedir(self);
11835 Py_RETURN_NONE;
11836}
11837
Victor Stinner6036e442015-03-08 01:58:04 +010011838static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011839ScandirIterator_finalize(ScandirIterator *iterator)
11840{
11841 PyObject *error_type, *error_value, *error_traceback;
11842
11843 /* Save the current exception, if any. */
11844 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11845
11846 if (!ScandirIterator_is_closed(iterator)) {
11847 ScandirIterator_closedir(iterator);
11848
11849 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11850 "unclosed scandir iterator %R", iterator)) {
11851 /* Spurious errors can appear at shutdown */
11852 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11853 PyErr_WriteUnraisable((PyObject *) iterator);
11854 }
11855 }
11856 }
11857
11858 Py_CLEAR(iterator->path.object);
11859 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
11934static PyObject *
11935posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11936{
11937 ScandirIterator *iterator;
11938 static char *keywords[] = {"path", NULL};
11939#ifdef MS_WINDOWS
11940 wchar_t *path_strW;
11941#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011942 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011943#endif
11944
11945 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11946 if (!iterator)
11947 return NULL;
11948 memset(&iterator->path, 0, sizeof(path_t));
11949 iterator->path.function_name = "scandir";
11950 iterator->path.nullable = 1;
11951
11952#ifdef MS_WINDOWS
11953 iterator->handle = INVALID_HANDLE_VALUE;
11954#else
11955 iterator->dirp = NULL;
11956#endif
11957
11958 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11959 path_converter, &iterator->path))
11960 goto error;
11961
11962 /* path_converter doesn't keep path.object around, so do it
11963 manually for the lifetime of the iterator here (the refcount
11964 is decremented in ScandirIterator_dealloc)
11965 */
11966 Py_XINCREF(iterator->path.object);
11967
11968#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011969 iterator->first_time = 1;
11970
11971 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11972 if (!path_strW)
11973 goto error;
11974
11975 Py_BEGIN_ALLOW_THREADS
11976 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11977 Py_END_ALLOW_THREADS
11978
11979 PyMem_Free(path_strW);
11980
11981 if (iterator->handle == INVALID_HANDLE_VALUE) {
11982 path_error(&iterator->path);
11983 goto error;
11984 }
11985#else /* POSIX */
11986 if (iterator->path.narrow)
11987 path = iterator->path.narrow;
11988 else
11989 path = ".";
11990
11991 errno = 0;
11992 Py_BEGIN_ALLOW_THREADS
11993 iterator->dirp = opendir(path);
11994 Py_END_ALLOW_THREADS
11995
11996 if (!iterator->dirp) {
11997 path_error(&iterator->path);
11998 goto error;
11999 }
12000#endif
12001
12002 return (PyObject *)iterator;
12003
12004error:
12005 Py_DECREF(iterator);
12006 return NULL;
12007}
12008
Ethan Furman410ef8e2016-06-04 12:06:26 -070012009/*
12010 Return the file system path representation of the object.
12011
12012 If the object is str or bytes, then allow it to pass through with
12013 an incremented refcount. If the object defines __fspath__(), then
12014 return the result of that method. All other types raise a TypeError.
12015*/
12016PyObject *
12017PyOS_FSPath(PyObject *path)
12018{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012019 /* For error message reasons, this function is manually inlined in
12020 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012021 _Py_IDENTIFIER(__fspath__);
12022 PyObject *func = NULL;
12023 PyObject *path_repr = NULL;
12024
12025 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12026 Py_INCREF(path);
12027 return path;
12028 }
12029
12030 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12031 if (NULL == func) {
12032 return PyErr_Format(PyExc_TypeError,
12033 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012034 "not %.200s",
12035 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012036 }
12037
12038 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12039 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012040 if (NULL == path_repr) {
12041 return NULL;
12042 }
12043
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012044 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12045 PyErr_Format(PyExc_TypeError,
12046 "expected %.200s.__fspath__() to return str or bytes, "
12047 "not %.200s", Py_TYPE(path)->tp_name,
12048 Py_TYPE(path_repr)->tp_name);
12049 Py_DECREF(path_repr);
12050 return NULL;
12051 }
12052
Ethan Furman410ef8e2016-06-04 12:06:26 -070012053 return path_repr;
12054}
12055
12056/*[clinic input]
12057os.fspath
12058
12059 path: object
12060
12061Return the file system path representation of the object.
12062
Brett Cannonb4f43e92016-06-09 14:32:08 -070012063If the object is str or bytes, then allow it to pass through as-is. If the
12064object defines __fspath__(), then return the result of that method. All other
12065types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012066[clinic start generated code]*/
12067
12068static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012069os_fspath_impl(PyObject *module, PyObject *path)
12070/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012071{
12072 return PyOS_FSPath(path);
12073}
Victor Stinner6036e442015-03-08 01:58:04 +010012074
Victor Stinner9b1f4742016-09-06 16:18:52 -070012075#ifdef HAVE_GETRANDOM_SYSCALL
12076/*[clinic input]
12077os.getrandom
12078
12079 size: Py_ssize_t
12080 flags: int=0
12081
12082Obtain a series of random bytes.
12083[clinic start generated code]*/
12084
12085static PyObject *
12086os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12087/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12088{
12089 char *buffer;
12090 Py_ssize_t n;
12091 PyObject *bytes;
12092
12093 if (size < 0) {
12094 errno = EINVAL;
12095 return posix_error();
12096 }
12097
12098 buffer = PyMem_Malloc(size);
12099 if (buffer == NULL) {
12100 PyErr_NoMemory();
12101 return NULL;
12102 }
12103
12104 while (1) {
12105 n = syscall(SYS_getrandom, buffer, size, flags);
12106 if (n < 0 && errno == EINTR) {
12107 if (PyErr_CheckSignals() < 0) {
12108 return NULL;
12109 }
12110 continue;
12111 }
12112 break;
12113 }
12114
12115 if (n < 0) {
12116 PyMem_Free(buffer);
12117 PyErr_SetFromErrno(PyExc_OSError);
12118 return NULL;
12119 }
12120
12121 bytes = PyBytes_FromStringAndSize(buffer, n);
12122 PyMem_Free(buffer);
12123
12124 return bytes;
12125}
12126#endif /* HAVE_GETRANDOM_SYSCALL */
12127
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012128#include "clinic/posixmodule.c.h"
12129
Larry Hastings7726ac92014-01-31 22:03:12 -080012130/*[clinic input]
12131dump buffer
12132[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012133/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012134
Larry Hastings31826802013-10-19 00:09:25 -070012135
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012136static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012137
12138 OS_STAT_METHODDEF
12139 OS_ACCESS_METHODDEF
12140 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012141 OS_CHDIR_METHODDEF
12142 OS_CHFLAGS_METHODDEF
12143 OS_CHMOD_METHODDEF
12144 OS_FCHMOD_METHODDEF
12145 OS_LCHMOD_METHODDEF
12146 OS_CHOWN_METHODDEF
12147 OS_FCHOWN_METHODDEF
12148 OS_LCHOWN_METHODDEF
12149 OS_LCHFLAGS_METHODDEF
12150 OS_CHROOT_METHODDEF
12151 OS_CTERMID_METHODDEF
12152 OS_GETCWD_METHODDEF
12153 OS_GETCWDB_METHODDEF
12154 OS_LINK_METHODDEF
12155 OS_LISTDIR_METHODDEF
12156 OS_LSTAT_METHODDEF
12157 OS_MKDIR_METHODDEF
12158 OS_NICE_METHODDEF
12159 OS_GETPRIORITY_METHODDEF
12160 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012161#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012162 {"readlink", (PyCFunction)posix_readlink,
12163 METH_VARARGS | METH_KEYWORDS,
12164 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012165#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012166#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012167 {"readlink", (PyCFunction)win_readlink,
12168 METH_VARARGS | METH_KEYWORDS,
12169 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012170#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012171 OS_RENAME_METHODDEF
12172 OS_REPLACE_METHODDEF
12173 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012174 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012175 OS_SYMLINK_METHODDEF
12176 OS_SYSTEM_METHODDEF
12177 OS_UMASK_METHODDEF
12178 OS_UNAME_METHODDEF
12179 OS_UNLINK_METHODDEF
12180 OS_REMOVE_METHODDEF
12181 OS_UTIME_METHODDEF
12182 OS_TIMES_METHODDEF
12183 OS__EXIT_METHODDEF
12184 OS_EXECV_METHODDEF
12185 OS_EXECVE_METHODDEF
12186 OS_SPAWNV_METHODDEF
12187 OS_SPAWNVE_METHODDEF
12188 OS_FORK1_METHODDEF
12189 OS_FORK_METHODDEF
12190 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12191 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12192 OS_SCHED_GETPARAM_METHODDEF
12193 OS_SCHED_GETSCHEDULER_METHODDEF
12194 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12195 OS_SCHED_SETPARAM_METHODDEF
12196 OS_SCHED_SETSCHEDULER_METHODDEF
12197 OS_SCHED_YIELD_METHODDEF
12198 OS_SCHED_SETAFFINITY_METHODDEF
12199 OS_SCHED_GETAFFINITY_METHODDEF
12200 OS_OPENPTY_METHODDEF
12201 OS_FORKPTY_METHODDEF
12202 OS_GETEGID_METHODDEF
12203 OS_GETEUID_METHODDEF
12204 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012205#ifdef HAVE_GETGROUPLIST
12206 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12207#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012208 OS_GETGROUPS_METHODDEF
12209 OS_GETPID_METHODDEF
12210 OS_GETPGRP_METHODDEF
12211 OS_GETPPID_METHODDEF
12212 OS_GETUID_METHODDEF
12213 OS_GETLOGIN_METHODDEF
12214 OS_KILL_METHODDEF
12215 OS_KILLPG_METHODDEF
12216 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012217#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012218 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012219#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012220 OS_SETUID_METHODDEF
12221 OS_SETEUID_METHODDEF
12222 OS_SETREUID_METHODDEF
12223 OS_SETGID_METHODDEF
12224 OS_SETEGID_METHODDEF
12225 OS_SETREGID_METHODDEF
12226 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012227#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012228 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012229#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012230 OS_GETPGID_METHODDEF
12231 OS_SETPGRP_METHODDEF
12232 OS_WAIT_METHODDEF
12233 OS_WAIT3_METHODDEF
12234 OS_WAIT4_METHODDEF
12235 OS_WAITID_METHODDEF
12236 OS_WAITPID_METHODDEF
12237 OS_GETSID_METHODDEF
12238 OS_SETSID_METHODDEF
12239 OS_SETPGID_METHODDEF
12240 OS_TCGETPGRP_METHODDEF
12241 OS_TCSETPGRP_METHODDEF
12242 OS_OPEN_METHODDEF
12243 OS_CLOSE_METHODDEF
12244 OS_CLOSERANGE_METHODDEF
12245 OS_DEVICE_ENCODING_METHODDEF
12246 OS_DUP_METHODDEF
12247 OS_DUP2_METHODDEF
12248 OS_LOCKF_METHODDEF
12249 OS_LSEEK_METHODDEF
12250 OS_READ_METHODDEF
12251 OS_READV_METHODDEF
12252 OS_PREAD_METHODDEF
12253 OS_WRITE_METHODDEF
12254 OS_WRITEV_METHODDEF
12255 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012256#ifdef HAVE_SENDFILE
12257 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12258 posix_sendfile__doc__},
12259#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012260 OS_FSTAT_METHODDEF
12261 OS_ISATTY_METHODDEF
12262 OS_PIPE_METHODDEF
12263 OS_PIPE2_METHODDEF
12264 OS_MKFIFO_METHODDEF
12265 OS_MKNOD_METHODDEF
12266 OS_MAJOR_METHODDEF
12267 OS_MINOR_METHODDEF
12268 OS_MAKEDEV_METHODDEF
12269 OS_FTRUNCATE_METHODDEF
12270 OS_TRUNCATE_METHODDEF
12271 OS_POSIX_FALLOCATE_METHODDEF
12272 OS_POSIX_FADVISE_METHODDEF
12273 OS_PUTENV_METHODDEF
12274 OS_UNSETENV_METHODDEF
12275 OS_STRERROR_METHODDEF
12276 OS_FCHDIR_METHODDEF
12277 OS_FSYNC_METHODDEF
12278 OS_SYNC_METHODDEF
12279 OS_FDATASYNC_METHODDEF
12280 OS_WCOREDUMP_METHODDEF
12281 OS_WIFCONTINUED_METHODDEF
12282 OS_WIFSTOPPED_METHODDEF
12283 OS_WIFSIGNALED_METHODDEF
12284 OS_WIFEXITED_METHODDEF
12285 OS_WEXITSTATUS_METHODDEF
12286 OS_WTERMSIG_METHODDEF
12287 OS_WSTOPSIG_METHODDEF
12288 OS_FSTATVFS_METHODDEF
12289 OS_STATVFS_METHODDEF
12290 OS_CONFSTR_METHODDEF
12291 OS_SYSCONF_METHODDEF
12292 OS_FPATHCONF_METHODDEF
12293 OS_PATHCONF_METHODDEF
12294 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012295 OS__GETFULLPATHNAME_METHODDEF
12296 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012297 OS__GETDISKUSAGE_METHODDEF
12298 OS__GETFINALPATHNAME_METHODDEF
12299 OS__GETVOLUMEPATHNAME_METHODDEF
12300 OS_GETLOADAVG_METHODDEF
12301 OS_URANDOM_METHODDEF
12302 OS_SETRESUID_METHODDEF
12303 OS_SETRESGID_METHODDEF
12304 OS_GETRESUID_METHODDEF
12305 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012306
Larry Hastings2f936352014-08-05 14:04:04 +100012307 OS_GETXATTR_METHODDEF
12308 OS_SETXATTR_METHODDEF
12309 OS_REMOVEXATTR_METHODDEF
12310 OS_LISTXATTR_METHODDEF
12311
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012312#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12313 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12314#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012315 OS_CPU_COUNT_METHODDEF
12316 OS_GET_INHERITABLE_METHODDEF
12317 OS_SET_INHERITABLE_METHODDEF
12318 OS_GET_HANDLE_INHERITABLE_METHODDEF
12319 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012320#ifndef MS_WINDOWS
12321 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12322 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12323#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012324 {"scandir", (PyCFunction)posix_scandir,
12325 METH_VARARGS | METH_KEYWORDS,
12326 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012327 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012328 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012329 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012330};
12331
12332
Brian Curtin52173d42010-12-02 18:29:18 +000012333#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012334static int
Brian Curtin52173d42010-12-02 18:29:18 +000012335enable_symlink()
12336{
12337 HANDLE tok;
12338 TOKEN_PRIVILEGES tok_priv;
12339 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012340
12341 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012342 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012343
12344 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012345 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012346
12347 tok_priv.PrivilegeCount = 1;
12348 tok_priv.Privileges[0].Luid = luid;
12349 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12350
12351 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12352 sizeof(TOKEN_PRIVILEGES),
12353 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012354 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012355
Brian Curtin3b4499c2010-12-28 14:31:47 +000012356 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12357 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012358}
12359#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12360
Barry Warsaw4a342091996-12-19 23:50:02 +000012361static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012362all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012363{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012364#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012365 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012366#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012367#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012368 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012369#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012370#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012371 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012372#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012373#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012374 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012375#endif
Fred Drakec9680921999-12-13 16:37:25 +000012376#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012377 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012378#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012379#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012380 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012381#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012382#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012383 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012384#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012385#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012386 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012387#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012388#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012389 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012390#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012391#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012392 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012393#endif
12394#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012395 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012396#endif
12397#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012398 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012399#endif
12400#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012401 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012402#endif
12403#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012404 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012405#endif
12406#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012407 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012408#endif
12409#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012410 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012411#endif
12412#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012413 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012414#endif
12415#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012416 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012417#endif
12418#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012419 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012420#endif
12421#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012422 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012423#endif
12424#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012425 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012426#endif
12427#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012428 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012429#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012430#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012431 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012432#endif
12433#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012434 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012435#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012436#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012437 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012438#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012439#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012441#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012442#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012443#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012445#endif
12446#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012447 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012448#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012449#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012450#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012452#endif
12453#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012454 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012455#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012456#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012457 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012458#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012459#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012460 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012461#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012462#ifdef O_TMPFILE
12463 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12464#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012465#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012466 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012467#endif
12468#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012469 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012470#endif
12471#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012472 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012473#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012474#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012475 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012476#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012477#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012478 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012479#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012480
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012481
Jesus Cea94363612012-06-22 18:32:07 +020012482#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012484#endif
12485#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012486 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012487#endif
12488
Tim Peters5aa91602002-01-30 05:46:57 +000012489/* MS Windows */
12490#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012491 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012492 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012493#endif
12494#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012495 /* Optimize for short life (keep in memory). */
12496 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012498#endif
12499#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012500 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012501 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012502#endif
12503#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012504 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012505 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012506#endif
12507#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012508 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012509 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012510#endif
12511
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012512/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012513#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012514 /* Send a SIGIO signal whenever input or output
12515 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012516 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012517#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012518#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012519 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012520 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012521#endif
12522#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012523 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012525#endif
12526#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012527 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012528 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012529#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012530#ifdef O_NOLINKS
12531 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012532 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012533#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012534#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012535 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012536 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012537#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012538
Victor Stinner8c62be82010-05-06 00:08:46 +000012539 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012540#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012541 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012542#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012543#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012544 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012545#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012546#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012547 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012548#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012549#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012550 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012551#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012552#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012553 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012554#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012555#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012556 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012557#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012558#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012559 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012560#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012561#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012563#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012564#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012565 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012566#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012567#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012568 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012569#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012570#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012571 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012572#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012573#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012575#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012576#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012577 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012578#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012579#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012580 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012581#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012582#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012583 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012584#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012585#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012586 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012587#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012588#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012589 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012590#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012591
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012592 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012593#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012595#endif /* ST_RDONLY */
12596#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012598#endif /* ST_NOSUID */
12599
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012600 /* GNU extensions */
12601#ifdef ST_NODEV
12602 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12603#endif /* ST_NODEV */
12604#ifdef ST_NOEXEC
12605 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12606#endif /* ST_NOEXEC */
12607#ifdef ST_SYNCHRONOUS
12608 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12609#endif /* ST_SYNCHRONOUS */
12610#ifdef ST_MANDLOCK
12611 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12612#endif /* ST_MANDLOCK */
12613#ifdef ST_WRITE
12614 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12615#endif /* ST_WRITE */
12616#ifdef ST_APPEND
12617 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12618#endif /* ST_APPEND */
12619#ifdef ST_NOATIME
12620 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12621#endif /* ST_NOATIME */
12622#ifdef ST_NODIRATIME
12623 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12624#endif /* ST_NODIRATIME */
12625#ifdef ST_RELATIME
12626 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12627#endif /* ST_RELATIME */
12628
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012629 /* FreeBSD sendfile() constants */
12630#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012631 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012632#endif
12633#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012635#endif
12636#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012637 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012638#endif
12639
Ross Lagerwall7807c352011-03-17 20:20:30 +020012640 /* constants for posix_fadvise */
12641#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012643#endif
12644#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012645 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012646#endif
12647#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012648 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012649#endif
12650#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012651 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012652#endif
12653#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012654 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012655#endif
12656#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012657 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012658#endif
12659
12660 /* constants for waitid */
12661#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12663 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12664 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012665#endif
12666#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012668#endif
12669#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012671#endif
12672#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012673 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012674#endif
12675#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012676 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012677#endif
12678#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012679 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012680#endif
12681#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012682 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012683#endif
12684#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012685 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012686#endif
12687
12688 /* constants for lockf */
12689#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012691#endif
12692#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012694#endif
12695#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012697#endif
12698#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012699 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012700#endif
12701
Guido van Rossum246bc171999-02-01 23:54:31 +000012702#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12704 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12705 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12706 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12707 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012708#endif
12709
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012710#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012711#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012712 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012713#endif
12714#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012715 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012716#endif
12717#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012718 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012719#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012720#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012721 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012722#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012723#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012724 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012725#endif
12726#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012727 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012728#endif
12729#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012730 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012731#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012732#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012733 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012734#endif
12735#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012736 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012737#endif
12738#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012739 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012740#endif
12741#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012742 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012743#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012744#endif
12745
Benjamin Peterson9428d532011-09-14 11:45:52 -040012746#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12748 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12749 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012750#endif
12751
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012752#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012754#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012755#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012757#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012758#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012760#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012761#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012763#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012764#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012766#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012767#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012769#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012770#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012772#endif
12773
Victor Stinner9b1f4742016-09-06 16:18:52 -070012774#ifdef HAVE_GETRANDOM_SYSCALL
12775 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12776 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12777#endif
12778
Victor Stinner8c62be82010-05-06 00:08:46 +000012779 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012780}
12781
12782
Martin v. Löwis1a214512008-06-11 05:26:20 +000012783static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012784 PyModuleDef_HEAD_INIT,
12785 MODNAME,
12786 posix__doc__,
12787 -1,
12788 posix_methods,
12789 NULL,
12790 NULL,
12791 NULL,
12792 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012793};
12794
12795
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012796static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012797
12798#ifdef HAVE_FACCESSAT
12799 "HAVE_FACCESSAT",
12800#endif
12801
12802#ifdef HAVE_FCHDIR
12803 "HAVE_FCHDIR",
12804#endif
12805
12806#ifdef HAVE_FCHMOD
12807 "HAVE_FCHMOD",
12808#endif
12809
12810#ifdef HAVE_FCHMODAT
12811 "HAVE_FCHMODAT",
12812#endif
12813
12814#ifdef HAVE_FCHOWN
12815 "HAVE_FCHOWN",
12816#endif
12817
Larry Hastings00964ed2013-08-12 13:49:30 -040012818#ifdef HAVE_FCHOWNAT
12819 "HAVE_FCHOWNAT",
12820#endif
12821
Larry Hastings9cf065c2012-06-22 16:30:09 -070012822#ifdef HAVE_FEXECVE
12823 "HAVE_FEXECVE",
12824#endif
12825
12826#ifdef HAVE_FDOPENDIR
12827 "HAVE_FDOPENDIR",
12828#endif
12829
Georg Brandl306336b2012-06-24 12:55:33 +020012830#ifdef HAVE_FPATHCONF
12831 "HAVE_FPATHCONF",
12832#endif
12833
Larry Hastings9cf065c2012-06-22 16:30:09 -070012834#ifdef HAVE_FSTATAT
12835 "HAVE_FSTATAT",
12836#endif
12837
12838#ifdef HAVE_FSTATVFS
12839 "HAVE_FSTATVFS",
12840#endif
12841
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012842#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012843 "HAVE_FTRUNCATE",
12844#endif
12845
Larry Hastings9cf065c2012-06-22 16:30:09 -070012846#ifdef HAVE_FUTIMENS
12847 "HAVE_FUTIMENS",
12848#endif
12849
12850#ifdef HAVE_FUTIMES
12851 "HAVE_FUTIMES",
12852#endif
12853
12854#ifdef HAVE_FUTIMESAT
12855 "HAVE_FUTIMESAT",
12856#endif
12857
12858#ifdef HAVE_LINKAT
12859 "HAVE_LINKAT",
12860#endif
12861
12862#ifdef HAVE_LCHFLAGS
12863 "HAVE_LCHFLAGS",
12864#endif
12865
12866#ifdef HAVE_LCHMOD
12867 "HAVE_LCHMOD",
12868#endif
12869
12870#ifdef HAVE_LCHOWN
12871 "HAVE_LCHOWN",
12872#endif
12873
12874#ifdef HAVE_LSTAT
12875 "HAVE_LSTAT",
12876#endif
12877
12878#ifdef HAVE_LUTIMES
12879 "HAVE_LUTIMES",
12880#endif
12881
12882#ifdef HAVE_MKDIRAT
12883 "HAVE_MKDIRAT",
12884#endif
12885
12886#ifdef HAVE_MKFIFOAT
12887 "HAVE_MKFIFOAT",
12888#endif
12889
12890#ifdef HAVE_MKNODAT
12891 "HAVE_MKNODAT",
12892#endif
12893
12894#ifdef HAVE_OPENAT
12895 "HAVE_OPENAT",
12896#endif
12897
12898#ifdef HAVE_READLINKAT
12899 "HAVE_READLINKAT",
12900#endif
12901
12902#ifdef HAVE_RENAMEAT
12903 "HAVE_RENAMEAT",
12904#endif
12905
12906#ifdef HAVE_SYMLINKAT
12907 "HAVE_SYMLINKAT",
12908#endif
12909
12910#ifdef HAVE_UNLINKAT
12911 "HAVE_UNLINKAT",
12912#endif
12913
12914#ifdef HAVE_UTIMENSAT
12915 "HAVE_UTIMENSAT",
12916#endif
12917
12918#ifdef MS_WINDOWS
12919 "MS_WINDOWS",
12920#endif
12921
12922 NULL
12923};
12924
12925
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012926PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012927INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012928{
Victor Stinner8c62be82010-05-06 00:08:46 +000012929 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012930 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012931 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012932
Brian Curtin52173d42010-12-02 18:29:18 +000012933#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012934 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012935#endif
12936
Victor Stinner8c62be82010-05-06 00:08:46 +000012937 m = PyModule_Create(&posixmodule);
12938 if (m == NULL)
12939 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012940
Victor Stinner8c62be82010-05-06 00:08:46 +000012941 /* Initialize environ dictionary */
12942 v = convertenviron();
12943 Py_XINCREF(v);
12944 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12945 return NULL;
12946 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012947
Victor Stinner8c62be82010-05-06 00:08:46 +000012948 if (all_ins(m))
12949 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012950
Victor Stinner8c62be82010-05-06 00:08:46 +000012951 if (setup_confname_tables(m))
12952 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012953
Victor Stinner8c62be82010-05-06 00:08:46 +000012954 Py_INCREF(PyExc_OSError);
12955 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012956
Guido van Rossumb3d39562000-01-31 18:41:26 +000012957#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012958 if (posix_putenv_garbage == NULL)
12959 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012960#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012961
Victor Stinner8c62be82010-05-06 00:08:46 +000012962 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012963#if defined(HAVE_WAITID) && !defined(__APPLE__)
12964 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012965 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12966 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012967#endif
12968
Christian Heimes25827622013-10-12 01:27:08 +020012969 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012970 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12971 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12972 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012973 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12974 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 structseq_new = StatResultType.tp_new;
12976 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012977
Christian Heimes25827622013-10-12 01:27:08 +020012978 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012979 if (PyStructSequence_InitType2(&StatVFSResultType,
12980 &statvfs_result_desc) < 0)
12981 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012982#ifdef NEED_TICKS_PER_SECOND
12983# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012984 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012985# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012987# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012988 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012989# endif
12990#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012991
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012992#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012993 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012994 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12995 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012996 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012997#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012998
12999 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013000 if (PyStructSequence_InitType2(&TerminalSizeType,
13001 &TerminalSize_desc) < 0)
13002 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013003
13004 /* initialize scandir types */
13005 if (PyType_Ready(&ScandirIteratorType) < 0)
13006 return NULL;
13007 if (PyType_Ready(&DirEntryType) < 0)
13008 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013009 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013010#if defined(HAVE_WAITID) && !defined(__APPLE__)
13011 Py_INCREF((PyObject*) &WaitidResultType);
13012 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13013#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013014 Py_INCREF((PyObject*) &StatResultType);
13015 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13016 Py_INCREF((PyObject*) &StatVFSResultType);
13017 PyModule_AddObject(m, "statvfs_result",
13018 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013019
13020#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013021 Py_INCREF(&SchedParamType);
13022 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013023#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013024
Larry Hastings605a62d2012-06-24 04:33:36 -070013025 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013026 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13027 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013028 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13029
13030 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013031 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13032 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013033 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13034
Thomas Wouters477c8d52006-05-27 19:21:47 +000013035#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013036 /*
13037 * Step 2 of weak-linking support on Mac OS X.
13038 *
13039 * The code below removes functions that are not available on the
13040 * currently active platform.
13041 *
13042 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013043 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013044 * OSX 10.4.
13045 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013046#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013047 if (fstatvfs == NULL) {
13048 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13049 return NULL;
13050 }
13051 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013052#endif /* HAVE_FSTATVFS */
13053
13054#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013055 if (statvfs == NULL) {
13056 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13057 return NULL;
13058 }
13059 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013060#endif /* HAVE_STATVFS */
13061
13062# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013063 if (lchown == NULL) {
13064 if (PyObject_DelAttrString(m, "lchown") == -1) {
13065 return NULL;
13066 }
13067 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013068#endif /* HAVE_LCHOWN */
13069
13070
13071#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013072
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013073 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013074 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13075
Larry Hastings6fe20b32012-04-19 15:07:49 -070013076 billion = PyLong_FromLong(1000000000);
13077 if (!billion)
13078 return NULL;
13079
Larry Hastings9cf065c2012-06-22 16:30:09 -070013080 /* suppress "function not used" warnings */
13081 {
13082 int ignored;
13083 fd_specified("", -1);
13084 follow_symlinks_specified("", 1);
13085 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13086 dir_fd_converter(Py_None, &ignored);
13087 dir_fd_unavailable(Py_None, &ignored);
13088 }
13089
13090 /*
13091 * provide list of locally available functions
13092 * so os.py can populate support_* lists
13093 */
13094 list = PyList_New(0);
13095 if (!list)
13096 return NULL;
13097 for (trace = have_functions; *trace; trace++) {
13098 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13099 if (!unicode)
13100 return NULL;
13101 if (PyList_Append(list, unicode))
13102 return NULL;
13103 Py_DECREF(unicode);
13104 }
13105 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013106
13107 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013108 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013109
13110 initialized = 1;
13111
Victor Stinner8c62be82010-05-06 00:08:46 +000013112 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013113}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013114
13115#ifdef __cplusplus
13116}
13117#endif