blob: ae251025cb55ca362f1081d2927398969a6d29ef [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020035/* On android API level 21, 'AT_EACCESS' is not declared although
36 * HAVE_FACCESSAT is defined. */
37#ifdef __ANDROID__
38#undef HAVE_FACCESSAT
39#endif
40
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000041#include <stdio.h> /* needed for ctermid() */
42
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#ifdef __cplusplus
44extern "C" {
45#endif
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000048"This module provides access to operating system functionality that is\n\
49standardized by the C Standard and the POSIX standard (a thinly\n\
50disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000053
Ross Lagerwall4d076da2011-03-18 06:56:53 +020054#ifdef HAVE_SYS_UIO_H
55#include <sys/uio.h>
56#endif
57
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000059#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060#endif /* HAVE_SYS_TYPES_H */
61
62#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000065
Guido van Rossum36bc6801995-06-14 22:54:23 +000066#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000067#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000068#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000071#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000073
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#ifdef HAVE_FCNTL_H
75#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000076#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Guido van Rossuma6535fd2001-10-18 19:44:10 +000078#ifdef HAVE_GRP_H
79#include <grp.h>
80#endif
81
Barry Warsaw5676bd12003-01-07 20:57:09 +000082#ifdef HAVE_SYSEXITS_H
83#include <sysexits.h>
84#endif /* HAVE_SYSEXITS_H */
85
Anthony Baxter8a560de2004-10-13 15:30:56 +000086#ifdef HAVE_SYS_LOADAVG_H
87#include <sys/loadavg.h>
88#endif
89
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000090#ifdef HAVE_LANGINFO_H
91#include <langinfo.h>
92#endif
93
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000094#ifdef HAVE_SYS_SENDFILE_H
95#include <sys/sendfile.h>
96#endif
97
Benjamin Peterson94b580d2011-08-02 17:30:04 -050098#ifdef HAVE_SCHED_H
99#include <sched.h>
100#endif
101
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500102#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500103#undef HAVE_SCHED_SETAFFINITY
104#endif
105
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200106#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400107#define USE_XATTRS
108#endif
109
110#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400111#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400112#endif
113
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
115#ifdef HAVE_SYS_SOCKET_H
116#include <sys/socket.h>
117#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#endif
119
Victor Stinner8b905bd2011-10-25 13:34:04 +0200120#ifdef HAVE_DLFCN_H
121#include <dlfcn.h>
122#endif
123
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200124#ifdef __hpux
125#include <sys/mpctl.h>
126#endif
127
128#if defined(__DragonFly__) || \
129 defined(__OpenBSD__) || \
130 defined(__FreeBSD__) || \
131 defined(__NetBSD__) || \
132 defined(__APPLE__)
133#include <sys/sysctl.h>
134#endif
135
Victor Stinner9b1f4742016-09-06 16:18:52 -0700136#ifdef HAVE_LINUX_RANDOM_H
137# include <linux/random.h>
138#endif
139#ifdef HAVE_GETRANDOM_SYSCALL
140# include <sys/syscall.h>
141#endif
142
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100143#if defined(MS_WINDOWS)
144# define TERMSIZE_USE_CONIO
145#elif defined(HAVE_SYS_IOCTL_H)
146# include <sys/ioctl.h>
147# if defined(HAVE_TERMIOS_H)
148# include <termios.h>
149# endif
150# if defined(TIOCGWINSZ)
151# define TERMSIZE_USE_IOCTL
152# endif
153#endif /* MS_WINDOWS */
154
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000156/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#include <process.h>
161#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000163#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000164#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700167#define HAVE_WSPAWNV 1
168#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#define HAVE_SYSTEM 1
171#define HAVE_CWAIT 1
172#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000173#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000174#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175/* Unix functions that the configure script doesn't check for */
176#define HAVE_EXECV 1
177#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000179#define HAVE_FORK1 1
180#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_GETEGID 1
182#define HAVE_GETEUID 1
183#define HAVE_GETGID 1
184#define HAVE_GETPPID 1
185#define HAVE_GETUID 1
186#define HAVE_KILL 1
187#define HAVE_OPENDIR 1
188#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000189#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000193#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000194
Victor Stinnera2f7c002012-02-08 03:36:25 +0100195
Larry Hastings61272b72014-01-07 12:41:53 -0800196/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000197# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800198module os
Larry Hastings61272b72014-01-07 12:41:53 -0800199[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000200/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100201
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000204#if defined(__sgi)&&_COMPILER_VERSION>=700
205/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
206 (default) */
207extern char *ctermid_r(char *);
208#endif
209
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000210#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000214#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#endif
220#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chdir(char *);
222extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int chdir(const char *);
225extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000228/*#ifdef HAVE_FCHMOD
229extern int fchmod(int, mode_t);
230#endif*/
231/*#ifdef HAVE_LCHMOD
232extern int lchmod(const char *, mode_t);
233#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chown(const char *, uid_t, gid_t);
235extern char *getcwd(char *, int);
236extern char *strerror(int);
237extern int link(const char *, const char *);
238extern int rename(const char *, const char *);
239extern int stat(const char *, struct stat *);
240extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000243#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_UTIME_H
252#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000255#ifdef HAVE_SYS_UTIME_H
256#include <sys/utime.h>
257#define HAVE_UTIME_H /* pretend we do for the rest of this file */
258#endif /* HAVE_SYS_UTIME_H */
259
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#ifdef HAVE_SYS_TIMES_H
261#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef HAVE_SYS_PARAM_H
265#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
268#ifdef HAVE_SYS_UTSNAME_H
269#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#define NAMLEN(dirent) strlen((dirent)->d_name)
275#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000276#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#include <direct.h>
278#define NAMLEN(dirent) strlen((dirent)->d_name)
279#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000294#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
301#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100313#ifndef IO_REPARSE_TAG_MOUNT_POINT
314#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000317#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000319#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000320#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000321#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
322#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000323static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000324#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000325#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#if defined(PATH_MAX) && PATH_MAX > 1024
329#define MAXPATHLEN PATH_MAX
330#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000332#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000333#endif /* MAXPATHLEN */
334
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000335#ifdef UNION_WAIT
336/* Emulate some macros on systems that have a union instead of macros */
337
338#ifndef WIFEXITED
339#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
340#endif
341
342#ifndef WEXITSTATUS
343#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
344#endif
345
346#ifndef WTERMSIG
347#define WTERMSIG(u_wait) ((u_wait).w_termsig)
348#endif
349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350#define WAIT_TYPE union wait
351#define WAIT_STATUS_INT(s) (s.w_status)
352
353#else /* !UNION_WAIT */
354#define WAIT_TYPE int
355#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000356#endif /* UNION_WAIT */
357
Greg Wardb48bc172000-03-01 21:51:56 +0000358/* Don't use the "_r" form if we don't need it (also, won't have a
359 prototype for it, at least on Solaris -- maybe others as well?). */
360#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
361#define USE_CTERMID_R
362#endif
363
Fred Drake699f3522000-06-29 21:12:41 +0000364/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000365#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000366#undef FSTAT
367#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200368#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700370# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200371# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800372# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000373#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000376# define FSTAT fstat
377# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000378#endif
379
Tim Peters11b23062003-04-23 02:39:17 +0000380#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#include <sys/mkdev.h>
382#else
383#if defined(MAJOR_IN_SYSMACROS)
384#include <sys/sysmacros.h>
385#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000386#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
387#include <sys/mkdev.h>
388#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000389#endif
Fred Drake699f3522000-06-29 21:12:41 +0000390
Victor Stinner6edddfa2013-11-24 19:22:57 +0100391#define DWORD_MAX 4294967295U
392
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200393#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100394#define INITFUNC PyInit_nt
395#define MODNAME "nt"
396#else
397#define INITFUNC PyInit_posix
398#define MODNAME "posix"
399#endif
400
401#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200402/* defined in fileutils.c */
403PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
404PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
405 ULONG, struct _Py_stat_struct *);
406#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700407
408#ifdef MS_WINDOWS
409static int
410win32_warn_bytes_api()
411{
412 return PyErr_WarnEx(PyExc_DeprecationWarning,
413 "The Windows bytes API has been deprecated, "
414 "use Unicode filenames instead",
415 1);
416}
417#endif
418
419
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200420#ifndef MS_WINDOWS
421PyObject *
422_PyLong_FromUid(uid_t uid)
423{
424 if (uid == (uid_t)-1)
425 return PyLong_FromLong(-1);
426 return PyLong_FromUnsignedLong(uid);
427}
428
429PyObject *
430_PyLong_FromGid(gid_t gid)
431{
432 if (gid == (gid_t)-1)
433 return PyLong_FromLong(-1);
434 return PyLong_FromUnsignedLong(gid);
435}
436
437int
438_Py_Uid_Converter(PyObject *obj, void *p)
439{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700440 uid_t uid;
441 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200442 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200443 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700444 unsigned long uresult;
445
446 index = PyNumber_Index(obj);
447 if (index == NULL) {
448 PyErr_Format(PyExc_TypeError,
449 "uid should be integer, not %.200s",
450 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200451 return 0;
452 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700453
454 /*
455 * Handling uid_t is complicated for two reasons:
456 * * Although uid_t is (always?) unsigned, it still
457 * accepts -1.
458 * * We don't know its size in advance--it may be
459 * bigger than an int, or it may be smaller than
460 * a long.
461 *
462 * So a bit of defensive programming is in order.
463 * Start with interpreting the value passed
464 * in as a signed long and see if it works.
465 */
466
467 result = PyLong_AsLongAndOverflow(index, &overflow);
468
469 if (!overflow) {
470 uid = (uid_t)result;
471
472 if (result == -1) {
473 if (PyErr_Occurred())
474 goto fail;
475 /* It's a legitimate -1, we're done. */
476 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200477 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700478
479 /* Any other negative number is disallowed. */
480 if (result < 0)
481 goto underflow;
482
483 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200484 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700485 (long)uid != result)
486 goto underflow;
487 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200488 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700489
490 if (overflow < 0)
491 goto underflow;
492
493 /*
494 * Okay, the value overflowed a signed long. If it
495 * fits in an *unsigned* long, it may still be okay,
496 * as uid_t may be unsigned long on this platform.
497 */
498 uresult = PyLong_AsUnsignedLong(index);
499 if (PyErr_Occurred()) {
500 if (PyErr_ExceptionMatches(PyExc_OverflowError))
501 goto overflow;
502 goto fail;
503 }
504
505 uid = (uid_t)uresult;
506
507 /*
508 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
509 * but this value would get interpreted as (uid_t)-1 by chown
510 * and its siblings. That's not what the user meant! So we
511 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100512 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 */
514 if (uid == (uid_t)-1)
515 goto overflow;
516
517 /* Ensure the value wasn't truncated. */
518 if (sizeof(uid_t) < sizeof(long) &&
519 (unsigned long)uid != uresult)
520 goto overflow;
521 /* fallthrough */
522
523success:
524 Py_DECREF(index);
525 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 return 1;
527
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200529 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 "uid is less than minimum");
531 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200534 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 "uid is greater than maximum");
536 /* fallthrough */
537
538fail:
539 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200540 return 0;
541}
542
543int
544_Py_Gid_Converter(PyObject *obj, void *p)
545{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700546 gid_t gid;
547 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200548 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200549 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700550 unsigned long uresult;
551
552 index = PyNumber_Index(obj);
553 if (index == NULL) {
554 PyErr_Format(PyExc_TypeError,
555 "gid should be integer, not %.200s",
556 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200557 return 0;
558 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700559
560 /*
561 * Handling gid_t is complicated for two reasons:
562 * * Although gid_t is (always?) unsigned, it still
563 * accepts -1.
564 * * We don't know its size in advance--it may be
565 * bigger than an int, or it may be smaller than
566 * a long.
567 *
568 * So a bit of defensive programming is in order.
569 * Start with interpreting the value passed
570 * in as a signed long and see if it works.
571 */
572
573 result = PyLong_AsLongAndOverflow(index, &overflow);
574
575 if (!overflow) {
576 gid = (gid_t)result;
577
578 if (result == -1) {
579 if (PyErr_Occurred())
580 goto fail;
581 /* It's a legitimate -1, we're done. */
582 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200583 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700584
585 /* Any other negative number is disallowed. */
586 if (result < 0) {
587 goto underflow;
588 }
589
590 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592 (long)gid != result)
593 goto underflow;
594 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200595 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700596
597 if (overflow < 0)
598 goto underflow;
599
600 /*
601 * Okay, the value overflowed a signed long. If it
602 * fits in an *unsigned* long, it may still be okay,
603 * as gid_t may be unsigned long on this platform.
604 */
605 uresult = PyLong_AsUnsignedLong(index);
606 if (PyErr_Occurred()) {
607 if (PyErr_ExceptionMatches(PyExc_OverflowError))
608 goto overflow;
609 goto fail;
610 }
611
612 gid = (gid_t)uresult;
613
614 /*
615 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
616 * but this value would get interpreted as (gid_t)-1 by chown
617 * and its siblings. That's not what the user meant! So we
618 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100619 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 */
621 if (gid == (gid_t)-1)
622 goto overflow;
623
624 /* Ensure the value wasn't truncated. */
625 if (sizeof(gid_t) < sizeof(long) &&
626 (unsigned long)gid != uresult)
627 goto overflow;
628 /* fallthrough */
629
630success:
631 Py_DECREF(index);
632 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200633 return 1;
634
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 "gid is less than minimum");
638 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642 "gid is greater than maximum");
643 /* fallthrough */
644
645fail:
646 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200647 return 0;
648}
649#endif /* MS_WINDOWS */
650
651
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700652#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800653
654
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200655#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
656static int
657_Py_Dev_Converter(PyObject *obj, void *p)
658{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200659 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200660 if (PyErr_Occurred())
661 return 0;
662 return 1;
663}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800664#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200665
666
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400668/*
669 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
670 * without the int cast, the value gets interpreted as uint (4291925331),
671 * which doesn't play nicely with all the initializer lines in this file that
672 * look like this:
673 * int dir_fd = DEFAULT_DIR_FD;
674 */
675#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700676#else
677#define DEFAULT_DIR_FD (-100)
678#endif
679
680static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300681_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200682{
683 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684 long long_value;
685
686 PyObject *index = PyNumber_Index(o);
687 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 return 0;
689 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300691 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 long_value = PyLong_AsLongAndOverflow(index, &overflow);
693 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300694 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200695 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700696 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 return 0;
699 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200700 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700702 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700703 return 0;
704 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700705
Larry Hastings9cf065c2012-06-22 16:30:09 -0700706 *p = (int)long_value;
707 return 1;
708}
709
710static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200711dir_fd_converter(PyObject *o, void *p)
712{
713 if (o == Py_None) {
714 *(int *)p = DEFAULT_DIR_FD;
715 return 1;
716 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300717 else if (PyIndex_Check(o)) {
718 return _fd_converter(o, (int *)p);
719 }
720 else {
721 PyErr_Format(PyExc_TypeError,
722 "argument should be integer or None, not %.200s",
723 Py_TYPE(o)->tp_name);
724 return 0;
725 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700726}
727
728
Larry Hastings9cf065c2012-06-22 16:30:09 -0700729/*
730 * A PyArg_ParseTuple "converter" function
731 * that handles filesystem paths in the manner
732 * preferred by the os module.
733 *
734 * path_converter accepts (Unicode) strings and their
735 * subclasses, and bytes and their subclasses. What
736 * it does with the argument depends on the platform:
737 *
738 * * On Windows, if we get a (Unicode) string we
739 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700740 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700741 *
742 * * On all other platforms, strings are encoded
743 * to bytes using PyUnicode_FSConverter, then we
744 * extract the char * from the bytes object and
745 * return that.
746 *
747 * path_converter also optionally accepts signed
748 * integers (representing open file descriptors) instead
749 * of path strings.
750 *
751 * Input fields:
752 * path.nullable
753 * If nonzero, the path is permitted to be None.
754 * path.allow_fd
755 * If nonzero, the path is permitted to be a file handle
756 * (a signed int) instead of a string.
757 * path.function_name
758 * If non-NULL, path_converter will use that as the name
759 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700760 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761 * path.argument_name
762 * If non-NULL, path_converter will use that as the name
763 * of the parameter in error messages.
764 * (If path.argument_name is NULL it uses "path".)
765 *
766 * Output fields:
767 * path.wide
768 * Points to the path if it was expressed as Unicode
769 * and was not encoded. (Only used on Windows.)
770 * path.narrow
771 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700772 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000773 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700774 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700775 * path.fd
776 * Contains a file descriptor if path.accept_fd was true
777 * and the caller provided a signed integer instead of any
778 * sort of string.
779 *
780 * WARNING: if your "path" parameter is optional, and is
781 * unspecified, path_converter will never get called.
782 * So if you set allow_fd, you *MUST* initialize path.fd = -1
783 * yourself!
784 * path.length
785 * The length of the path in characters, if specified as
786 * a string.
787 * path.object
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
Victor Stinner26c03bd2016-09-19 11:55:44 +0200923 wide = PyUnicode_AsUnicodeAndSize(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
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001181#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001182
1183static int
Brian Curtind25aef52011-06-13 15:16:04 -05001184win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001185{
Martin Panter70214ad2016-08-04 02:38:59 +00001186 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1187 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001188 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001189
1190 if (0 == DeviceIoControl(
1191 reparse_point_handle,
1192 FSCTL_GET_REPARSE_POINT,
1193 NULL, 0, /* in buffer */
1194 target_buffer, sizeof(target_buffer),
1195 &n_bytes_returned,
1196 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001197 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001198
1199 if (reparse_tag)
1200 *reparse_tag = rdb->ReparseTag;
1201
Brian Curtind25aef52011-06-13 15:16:04 -05001202 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001203}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001204
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001205#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001206
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001208#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001209/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001210** environ directly, we must obtain it with _NSGetEnviron(). See also
1211** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001212*/
1213#include <crt_externs.h>
1214static char **environ;
1215#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001217#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218
Barry Warsaw53699e91996-12-10 23:23:01 +00001219static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001220convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221{
Victor Stinner8c62be82010-05-06 00:08:46 +00001222 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001224 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001225#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001227#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001228
Victor Stinner8c62be82010-05-06 00:08:46 +00001229 d = PyDict_New();
1230 if (d == NULL)
1231 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001232#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 if (environ == NULL)
1234 environ = *_NSGetEnviron();
1235#endif
1236#ifdef MS_WINDOWS
1237 /* _wenviron must be initialized in this way if the program is started
1238 through main() instead of wmain(). */
1239 _wgetenv(L"");
1240 if (_wenviron == NULL)
1241 return d;
1242 /* This part ignores errors */
1243 for (e = _wenviron; *e != NULL; e++) {
1244 PyObject *k;
1245 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001246 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001247 if (p == NULL)
1248 continue;
1249 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1250 if (k == NULL) {
1251 PyErr_Clear();
1252 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001253 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1255 if (v == NULL) {
1256 PyErr_Clear();
1257 Py_DECREF(k);
1258 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001259 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001260 if (PyDict_GetItem(d, k) == NULL) {
1261 if (PyDict_SetItem(d, k, v) != 0)
1262 PyErr_Clear();
1263 }
1264 Py_DECREF(k);
1265 Py_DECREF(v);
1266 }
1267#else
1268 if (environ == NULL)
1269 return d;
1270 /* This part ignores errors */
1271 for (e = environ; *e != NULL; e++) {
1272 PyObject *k;
1273 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001274 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 if (p == NULL)
1276 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001277 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 if (k == NULL) {
1279 PyErr_Clear();
1280 continue;
1281 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001282 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 if (v == NULL) {
1284 PyErr_Clear();
1285 Py_DECREF(k);
1286 continue;
1287 }
1288 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);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001294 }
1295#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001296 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297}
1298
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299/* Set a POSIX-specific error from errno, and return NULL */
1300
Barry Warsawd58d7641998-07-23 16:14:40 +00001301static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001302posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001303{
Victor Stinner8c62be82010-05-06 00:08:46 +00001304 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305}
Mark Hammondef8b6542001-05-13 08:04:26 +00001306
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001307#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001308static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001309win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001310{
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 /* XXX We should pass the function name along in the future.
1312 (winreg.c also wants to pass the function name.)
1313 This would however require an additional param to the
1314 Windows error object, which is non-trivial.
1315 */
1316 errno = GetLastError();
1317 if (filename)
1318 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1319 else
1320 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001321}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001322
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001323static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001324win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001325{
1326 /* XXX - see win32_error for comments on 'function' */
1327 errno = GetLastError();
1328 if (filename)
1329 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001330 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001331 errno,
1332 filename);
1333 else
1334 return PyErr_SetFromWindowsErr(errno);
1335}
1336
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001337#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338
Larry Hastings9cf065c2012-06-22 16:30:09 -07001339static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001340path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001341{
1342#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001343 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1344 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001345#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001346 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001347#endif
1348}
1349
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001350static PyObject *
1351path_object_error2(PyObject *path, PyObject *path2)
1352{
1353#ifdef MS_WINDOWS
1354 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1355 PyExc_OSError, 0, path, path2);
1356#else
1357 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1358#endif
1359}
1360
1361static PyObject *
1362path_error(path_t *path)
1363{
1364 return path_object_error(path->object);
1365}
Larry Hastings31826802013-10-19 00:09:25 -07001366
Larry Hastingsb0827312014-02-09 22:05:19 -08001367static PyObject *
1368path_error2(path_t *path, path_t *path2)
1369{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001370 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001371}
1372
1373
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001374/* POSIX generic methods */
1375
Larry Hastings2f936352014-08-05 14:04:04 +10001376static int
1377fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001378{
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001380 int *pointer = (int *)p;
1381 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001383 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001384 *pointer = fd;
1385 return 1;
1386}
1387
1388static PyObject *
1389posix_fildes_fd(int fd, int (*func)(int))
1390{
1391 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001392 int async_err = 0;
1393
1394 do {
1395 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001396 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001397 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001398 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001399 Py_END_ALLOW_THREADS
1400 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1401 if (res != 0)
1402 return (!async_err) ? posix_error() : NULL;
1403 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001404}
Guido van Rossum21142a01999-01-08 21:05:37 +00001405
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001406
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001407#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001408/* This is a reimplementation of the C library's chdir function,
1409 but one that produces Win32 errors instead of DOS error codes.
1410 chdir is essentially a wrapper around SetCurrentDirectory; however,
1411 it also needs to set "magic" environment variables indicating
1412 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001413static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414win32_wchdir(LPCWSTR path)
1415{
Victor Stinnered537822015-12-13 21:40:26 +01001416 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001417 int result;
1418 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001419
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 if(!SetCurrentDirectoryW(path))
1421 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001422 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 if (!result)
1424 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001425 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001426 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 if (!new_path) {
1428 SetLastError(ERROR_OUTOFMEMORY);
1429 return FALSE;
1430 }
1431 result = GetCurrentDirectoryW(result, new_path);
1432 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001433 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001434 return FALSE;
1435 }
1436 }
1437 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1438 wcsncmp(new_path, L"//", 2) == 0)
1439 /* UNC path, nothing to do. */
1440 return TRUE;
1441 env[1] = new_path[0];
1442 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001443 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001444 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001446}
1447#endif
1448
Martin v. Löwis14694662006-02-03 12:54:16 +00001449#ifdef MS_WINDOWS
1450/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1451 - time stamps are restricted to second resolution
1452 - file modification times suffer from forth-and-back conversions between
1453 UTC and local time
1454 Therefore, we implement our own stat, based on the Win32 API directly.
1455*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001456#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001457#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001458
Victor Stinner6036e442015-03-08 01:58:04 +01001459static void
Steve Dowercc16be82016-09-08 10:35:16 -07001460find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1461 BY_HANDLE_FILE_INFORMATION *info,
1462 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001463{
1464 memset(info, 0, sizeof(*info));
1465 info->dwFileAttributes = pFileData->dwFileAttributes;
1466 info->ftCreationTime = pFileData->ftCreationTime;
1467 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1468 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1469 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1470 info->nFileSizeLow = pFileData->nFileSizeLow;
1471/* info->nNumberOfLinks = 1; */
1472 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1473 *reparse_tag = pFileData->dwReserved0;
1474 else
1475 *reparse_tag = 0;
1476}
1477
Guido van Rossumd8faa362007-04-27 19:54:29 +00001478static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001479attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001480{
Victor Stinner8c62be82010-05-06 00:08:46 +00001481 HANDLE hFindFile;
1482 WIN32_FIND_DATAW FileData;
1483 hFindFile = FindFirstFileW(pszFile, &FileData);
1484 if (hFindFile == INVALID_HANDLE_VALUE)
1485 return FALSE;
1486 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001487 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001488 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001489}
1490
Brian Curtind25aef52011-06-13 15:16:04 -05001491static BOOL
1492get_target_path(HANDLE hdl, wchar_t **target_path)
1493{
1494 int buf_size, result_length;
1495 wchar_t *buf;
1496
1497 /* We have a good handle to the target, use it to determine
1498 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001499 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1500 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001501 if(!buf_size)
1502 return FALSE;
1503
Victor Stinnerc36674a2016-03-16 14:30:16 +01001504 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001505 if (!buf) {
1506 SetLastError(ERROR_OUTOFMEMORY);
1507 return FALSE;
1508 }
1509
Steve Dower2ea51c92015-03-20 21:49:12 -07001510 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001511 buf, buf_size, VOLUME_NAME_DOS);
1512
1513 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001514 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001515 return FALSE;
1516 }
1517
1518 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001519 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001520 return FALSE;
1521 }
1522
1523 buf[result_length] = 0;
1524
1525 *target_path = buf;
1526 return TRUE;
1527}
1528
1529static int
Steve Dowercc16be82016-09-08 10:35:16 -07001530win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001531 BOOL traverse)
1532{
Victor Stinner26de69d2011-06-17 15:15:38 +02001533 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001534 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001535 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001536 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001537 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001538 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001539
Steve Dowercc16be82016-09-08 10:35:16 -07001540 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001541 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001542 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001543 0, /* share mode */
1544 NULL, /* security attributes */
1545 OPEN_EXISTING,
1546 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001547 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1548 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001549 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001550 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1551 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001552 NULL);
1553
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001554 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001555 /* Either the target doesn't exist, or we don't have access to
1556 get a handle to it. If the former, we need to return an error.
1557 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001558 DWORD lastError = GetLastError();
1559 if (lastError != ERROR_ACCESS_DENIED &&
1560 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001561 return -1;
1562 /* Could not get attributes on open file. Fall back to
1563 reading the directory. */
1564 if (!attributes_from_dir(path, &info, &reparse_tag))
1565 /* Very strange. This should not fail now */
1566 return -1;
1567 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1568 if (traverse) {
1569 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001570 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001571 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001572 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001574 } else {
1575 if (!GetFileInformationByHandle(hFile, &info)) {
1576 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001577 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001578 }
1579 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001580 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1581 return -1;
1582
1583 /* Close the outer open file handle now that we're about to
1584 reopen it with different flags. */
1585 if (!CloseHandle(hFile))
1586 return -1;
1587
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001588 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001589 /* In order to call GetFinalPathNameByHandle we need to open
1590 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001591 hFile2 = CreateFileW(
1592 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1593 NULL, OPEN_EXISTING,
1594 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1595 NULL);
1596 if (hFile2 == INVALID_HANDLE_VALUE)
1597 return -1;
1598
1599 if (!get_target_path(hFile2, &target_path))
1600 return -1;
1601
Steve Dowercc16be82016-09-08 10:35:16 -07001602 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001603 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001604 return code;
1605 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001606 } else
1607 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001608 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001609 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001610
1611 /* Set S_IEXEC if it is an .exe, .bat, ... */
1612 dot = wcsrchr(path, '.');
1613 if (dot) {
1614 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1615 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1616 result->st_mode |= 0111;
1617 }
1618 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001619}
1620
1621static int
Steve Dowercc16be82016-09-08 10:35:16 -07001622win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001623{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 /* Protocol violation: we explicitly clear errno, instead of
1625 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001626 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 errno = 0;
1628 return code;
1629}
Brian Curtind25aef52011-06-13 15:16:04 -05001630/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001631
1632 In Posix, stat automatically traverses symlinks and returns the stat
1633 structure for the target. In Windows, the equivalent GetFileAttributes by
1634 default does not traverse symlinks and instead returns attributes for
1635 the symlink.
1636
1637 Therefore, win32_lstat will get the attributes traditionally, and
1638 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001639 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001640
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001641static int
Steve Dowercc16be82016-09-08 10:35:16 -07001642win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001643{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001644 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001645}
1646
Victor Stinner8c62be82010-05-06 00:08:46 +00001647static int
Steve Dowercc16be82016-09-08 10:35:16 -07001648win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001649{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001650 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001651}
1652
Martin v. Löwis14694662006-02-03 12:54:16 +00001653#endif /* MS_WINDOWS */
1654
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001655PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001656"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001657This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001658 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001659or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1660\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001661Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1662or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001663\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001664See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001665
1666static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001667 {"st_mode", "protection bits"},
1668 {"st_ino", "inode"},
1669 {"st_dev", "device"},
1670 {"st_nlink", "number of hard links"},
1671 {"st_uid", "user ID of owner"},
1672 {"st_gid", "group ID of owner"},
1673 {"st_size", "total size, in bytes"},
1674 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1675 {NULL, "integer time of last access"},
1676 {NULL, "integer time of last modification"},
1677 {NULL, "integer time of last change"},
1678 {"st_atime", "time of last access"},
1679 {"st_mtime", "time of last modification"},
1680 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001681 {"st_atime_ns", "time of last access in nanoseconds"},
1682 {"st_mtime_ns", "time of last modification in nanoseconds"},
1683 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001684#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001686#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001687#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001689#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001690#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001691 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001692#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001693#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001694 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001695#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001696#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001697 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001698#endif
1699#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001700 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001701#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001702#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1703 {"st_file_attributes", "Windows file attribute bits"},
1704#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001705 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001706};
1707
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001708#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001709#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001710#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001711#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001712#endif
1713
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001714#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001715#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1716#else
1717#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1718#endif
1719
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001720#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001721#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1722#else
1723#define ST_RDEV_IDX ST_BLOCKS_IDX
1724#endif
1725
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001726#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1727#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1728#else
1729#define ST_FLAGS_IDX ST_RDEV_IDX
1730#endif
1731
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001732#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001733#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001734#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001735#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001736#endif
1737
1738#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1739#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1740#else
1741#define ST_BIRTHTIME_IDX ST_GEN_IDX
1742#endif
1743
Zachary Ware63f277b2014-06-19 09:46:37 -05001744#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1745#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1746#else
1747#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1748#endif
1749
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001751 "stat_result", /* name */
1752 stat_result__doc__, /* doc */
1753 stat_result_fields,
1754 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001755};
1756
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001757PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001758"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1759This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001760 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001761or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001763See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001764
1765static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001766 {"f_bsize", },
1767 {"f_frsize", },
1768 {"f_blocks", },
1769 {"f_bfree", },
1770 {"f_bavail", },
1771 {"f_files", },
1772 {"f_ffree", },
1773 {"f_favail", },
1774 {"f_flag", },
1775 {"f_namemax",},
1776 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777};
1778
1779static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 "statvfs_result", /* name */
1781 statvfs_result__doc__, /* doc */
1782 statvfs_result_fields,
1783 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001784};
1785
Ross Lagerwall7807c352011-03-17 20:20:30 +02001786#if defined(HAVE_WAITID) && !defined(__APPLE__)
1787PyDoc_STRVAR(waitid_result__doc__,
1788"waitid_result: Result from waitid.\n\n\
1789This object may be accessed either as a tuple of\n\
1790 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1791or via the attributes si_pid, si_uid, and so on.\n\
1792\n\
1793See os.waitid for more information.");
1794
1795static PyStructSequence_Field waitid_result_fields[] = {
1796 {"si_pid", },
1797 {"si_uid", },
1798 {"si_signo", },
1799 {"si_status", },
1800 {"si_code", },
1801 {0}
1802};
1803
1804static PyStructSequence_Desc waitid_result_desc = {
1805 "waitid_result", /* name */
1806 waitid_result__doc__, /* doc */
1807 waitid_result_fields,
1808 5
1809};
1810static PyTypeObject WaitidResultType;
1811#endif
1812
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001813static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001814static PyTypeObject StatResultType;
1815static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001816#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001817static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001818#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001819static newfunc structseq_new;
1820
1821static PyObject *
1822statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1823{
Victor Stinner8c62be82010-05-06 00:08:46 +00001824 PyStructSequence *result;
1825 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001826
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 result = (PyStructSequence*)structseq_new(type, args, kwds);
1828 if (!result)
1829 return NULL;
1830 /* If we have been initialized from a tuple,
1831 st_?time might be set to None. Initialize it
1832 from the int slots. */
1833 for (i = 7; i <= 9; i++) {
1834 if (result->ob_item[i+3] == Py_None) {
1835 Py_DECREF(Py_None);
1836 Py_INCREF(result->ob_item[i]);
1837 result->ob_item[i+3] = result->ob_item[i];
1838 }
1839 }
1840 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001841}
1842
1843
1844
1845/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001846static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001847
1848PyDoc_STRVAR(stat_float_times__doc__,
1849"stat_float_times([newval]) -> oldval\n\n\
1850Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001851\n\
1852If value is True, future calls to stat() return floats; if it is False,\n\
1853future calls return ints.\n\
1854If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001855
Larry Hastings2f936352014-08-05 14:04:04 +10001856/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001857static PyObject*
1858stat_float_times(PyObject* self, PyObject *args)
1859{
Victor Stinner8c62be82010-05-06 00:08:46 +00001860 int newval = -1;
1861 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1862 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001863 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1864 "stat_float_times() is deprecated",
1865 1))
1866 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 if (newval == -1)
1868 /* Return old value */
1869 return PyBool_FromLong(_stat_float_times);
1870 _stat_float_times = newval;
1871 Py_INCREF(Py_None);
1872 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001873}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001874
Larry Hastings6fe20b32012-04-19 15:07:49 -07001875static PyObject *billion = NULL;
1876
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001877static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001878fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001879{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001880 PyObject *s = _PyLong_FromTime_t(sec);
1881 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1882 PyObject *s_in_ns = NULL;
1883 PyObject *ns_total = NULL;
1884 PyObject *float_s = NULL;
1885
1886 if (!(s && ns_fractional))
1887 goto exit;
1888
1889 s_in_ns = PyNumber_Multiply(s, billion);
1890 if (!s_in_ns)
1891 goto exit;
1892
1893 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1894 if (!ns_total)
1895 goto exit;
1896
Victor Stinner4195b5c2012-02-08 23:03:19 +01001897 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001898 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1899 if (!float_s)
1900 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001902 else {
1903 float_s = s;
1904 Py_INCREF(float_s);
1905 }
1906
1907 PyStructSequence_SET_ITEM(v, index, s);
1908 PyStructSequence_SET_ITEM(v, index+3, float_s);
1909 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1910 s = NULL;
1911 float_s = NULL;
1912 ns_total = NULL;
1913exit:
1914 Py_XDECREF(s);
1915 Py_XDECREF(ns_fractional);
1916 Py_XDECREF(s_in_ns);
1917 Py_XDECREF(ns_total);
1918 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001919}
1920
Tim Peters5aa91602002-01-30 05:46:57 +00001921/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001922 (used by posix_stat() and posix_fstat()) */
1923static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001924_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001925{
Victor Stinner8c62be82010-05-06 00:08:46 +00001926 unsigned long ansec, mnsec, cnsec;
1927 PyObject *v = PyStructSequence_New(&StatResultType);
1928 if (v == NULL)
1929 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001930
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001932#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001934 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001935#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001936 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001937#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001938#ifdef MS_WINDOWS
1939 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001940#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001941 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001942#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001944#if defined(MS_WINDOWS)
1945 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1946 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1947#else
1948 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1949 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1950#endif
Fred Drake699f3522000-06-29 21:12:41 +00001951#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001953 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001954#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001956#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001957
Martin v. Löwis14694662006-02-03 12:54:16 +00001958#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 ansec = st->st_atim.tv_nsec;
1960 mnsec = st->st_mtim.tv_nsec;
1961 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001962#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001963 ansec = st->st_atimespec.tv_nsec;
1964 mnsec = st->st_mtimespec.tv_nsec;
1965 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001966#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001967 ansec = st->st_atime_nsec;
1968 mnsec = st->st_mtime_nsec;
1969 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001970#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001973 fill_time(v, 7, st->st_atime, ansec);
1974 fill_time(v, 8, st->st_mtime, mnsec);
1975 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001977#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1979 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001980#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001981#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1983 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001984#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001985#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1987 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001988#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001989#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1991 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001992#endif
1993#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001994 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001995 PyObject *val;
1996 unsigned long bsec,bnsec;
1997 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001998#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01001999 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002000#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002001 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002002#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002003 if (_stat_float_times) {
2004 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2005 } else {
2006 val = PyLong_FromLong((long)bsec);
2007 }
2008 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2009 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002011#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002012#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2014 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002015#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002016#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2017 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2018 PyLong_FromUnsignedLong(st->st_file_attributes));
2019#endif
Fred Drake699f3522000-06-29 21:12:41 +00002020
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 if (PyErr_Occurred()) {
2022 Py_DECREF(v);
2023 return NULL;
2024 }
Fred Drake699f3522000-06-29 21:12:41 +00002025
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002027}
2028
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002029/* POSIX methods */
2030
Guido van Rossum94f6f721999-01-06 18:42:14 +00002031
2032static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002033posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002034 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002035{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002036 STRUCT_STAT st;
2037 int result;
2038
2039#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2040 if (follow_symlinks_specified(function_name, follow_symlinks))
2041 return NULL;
2042#endif
2043
2044 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2045 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2046 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2047 return NULL;
2048
2049 Py_BEGIN_ALLOW_THREADS
2050 if (path->fd != -1)
2051 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002052#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002053 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002054 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002055 else
Steve Dowercc16be82016-09-08 10:35:16 -07002056 result = win32_lstat(path->wide, &st);
2057#else
2058 else
2059#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002060 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2061 result = LSTAT(path->narrow, &st);
2062 else
Steve Dowercc16be82016-09-08 10:35:16 -07002063#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002064#ifdef HAVE_FSTATAT
2065 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2066 result = fstatat(dir_fd, path->narrow, &st,
2067 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2068 else
Steve Dowercc16be82016-09-08 10:35:16 -07002069#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002070 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002071#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002072 Py_END_ALLOW_THREADS
2073
Victor Stinner292c8352012-10-30 02:17:38 +01002074 if (result != 0) {
2075 return path_error(path);
2076 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002077
2078 return _pystat_fromstructstat(&st);
2079}
2080
Larry Hastings2f936352014-08-05 14:04:04 +10002081/*[python input]
2082
2083for s in """
2084
2085FACCESSAT
2086FCHMODAT
2087FCHOWNAT
2088FSTATAT
2089LINKAT
2090MKDIRAT
2091MKFIFOAT
2092MKNODAT
2093OPENAT
2094READLINKAT
2095SYMLINKAT
2096UNLINKAT
2097
2098""".strip().split():
2099 s = s.strip()
2100 print("""
2101#ifdef HAVE_{s}
2102 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002103#else
Larry Hastings2f936352014-08-05 14:04:04 +10002104 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002105#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002106""".rstrip().format(s=s))
2107
2108for s in """
2109
2110FCHDIR
2111FCHMOD
2112FCHOWN
2113FDOPENDIR
2114FEXECVE
2115FPATHCONF
2116FSTATVFS
2117FTRUNCATE
2118
2119""".strip().split():
2120 s = s.strip()
2121 print("""
2122#ifdef HAVE_{s}
2123 #define PATH_HAVE_{s} 1
2124#else
2125 #define PATH_HAVE_{s} 0
2126#endif
2127
2128""".rstrip().format(s=s))
2129[python start generated code]*/
2130
2131#ifdef HAVE_FACCESSAT
2132 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2133#else
2134 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2135#endif
2136
2137#ifdef HAVE_FCHMODAT
2138 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2139#else
2140 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2141#endif
2142
2143#ifdef HAVE_FCHOWNAT
2144 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2145#else
2146 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2147#endif
2148
2149#ifdef HAVE_FSTATAT
2150 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2151#else
2152 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2153#endif
2154
2155#ifdef HAVE_LINKAT
2156 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2157#else
2158 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2159#endif
2160
2161#ifdef HAVE_MKDIRAT
2162 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2163#else
2164 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2165#endif
2166
2167#ifdef HAVE_MKFIFOAT
2168 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2169#else
2170 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2171#endif
2172
2173#ifdef HAVE_MKNODAT
2174 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2175#else
2176 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2177#endif
2178
2179#ifdef HAVE_OPENAT
2180 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2181#else
2182 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2183#endif
2184
2185#ifdef HAVE_READLINKAT
2186 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2187#else
2188 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2189#endif
2190
2191#ifdef HAVE_SYMLINKAT
2192 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2193#else
2194 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2195#endif
2196
2197#ifdef HAVE_UNLINKAT
2198 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2199#else
2200 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2201#endif
2202
2203#ifdef HAVE_FCHDIR
2204 #define PATH_HAVE_FCHDIR 1
2205#else
2206 #define PATH_HAVE_FCHDIR 0
2207#endif
2208
2209#ifdef HAVE_FCHMOD
2210 #define PATH_HAVE_FCHMOD 1
2211#else
2212 #define PATH_HAVE_FCHMOD 0
2213#endif
2214
2215#ifdef HAVE_FCHOWN
2216 #define PATH_HAVE_FCHOWN 1
2217#else
2218 #define PATH_HAVE_FCHOWN 0
2219#endif
2220
2221#ifdef HAVE_FDOPENDIR
2222 #define PATH_HAVE_FDOPENDIR 1
2223#else
2224 #define PATH_HAVE_FDOPENDIR 0
2225#endif
2226
2227#ifdef HAVE_FEXECVE
2228 #define PATH_HAVE_FEXECVE 1
2229#else
2230 #define PATH_HAVE_FEXECVE 0
2231#endif
2232
2233#ifdef HAVE_FPATHCONF
2234 #define PATH_HAVE_FPATHCONF 1
2235#else
2236 #define PATH_HAVE_FPATHCONF 0
2237#endif
2238
2239#ifdef HAVE_FSTATVFS
2240 #define PATH_HAVE_FSTATVFS 1
2241#else
2242 #define PATH_HAVE_FSTATVFS 0
2243#endif
2244
2245#ifdef HAVE_FTRUNCATE
2246 #define PATH_HAVE_FTRUNCATE 1
2247#else
2248 #define PATH_HAVE_FTRUNCATE 0
2249#endif
2250/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002251
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002252#ifdef MS_WINDOWS
2253 #undef PATH_HAVE_FTRUNCATE
2254 #define PATH_HAVE_FTRUNCATE 1
2255#endif
Larry Hastings31826802013-10-19 00:09:25 -07002256
Larry Hastings61272b72014-01-07 12:41:53 -08002257/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002258
2259class path_t_converter(CConverter):
2260
2261 type = "path_t"
2262 impl_by_reference = True
2263 parse_by_reference = True
2264
2265 converter = 'path_converter'
2266
2267 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002268 # right now path_t doesn't support default values.
2269 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002270 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002271 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002272
Larry Hastings2f936352014-08-05 14:04:04 +10002273 if self.c_default not in (None, 'Py_None'):
2274 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002275
2276 self.nullable = nullable
2277 self.allow_fd = allow_fd
2278
Larry Hastings7726ac92014-01-31 22:03:12 -08002279 def pre_render(self):
2280 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002281 if isinstance(value, str):
2282 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002283 return str(int(bool(value)))
2284
2285 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002286 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002287 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002288 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002289 strify(self.nullable),
2290 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002291 )
2292
2293 def cleanup(self):
2294 return "path_cleanup(&" + self.name + ");\n"
2295
2296
2297class dir_fd_converter(CConverter):
2298 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002299
Larry Hastings2f936352014-08-05 14:04:04 +10002300 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002301 if self.default in (unspecified, None):
2302 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002303 if isinstance(requires, str):
2304 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2305 else:
2306 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002307
Larry Hastings2f936352014-08-05 14:04:04 +10002308class fildes_converter(CConverter):
2309 type = 'int'
2310 converter = 'fildes_converter'
2311
2312class uid_t_converter(CConverter):
2313 type = "uid_t"
2314 converter = '_Py_Uid_Converter'
2315
2316class gid_t_converter(CConverter):
2317 type = "gid_t"
2318 converter = '_Py_Gid_Converter'
2319
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002320class dev_t_converter(CConverter):
2321 type = 'dev_t'
2322 converter = '_Py_Dev_Converter'
2323
2324class dev_t_return_converter(unsigned_long_return_converter):
2325 type = 'dev_t'
2326 conversion_fn = '_PyLong_FromDev'
2327 unsigned_cast = '(dev_t)'
2328
Larry Hastings2f936352014-08-05 14:04:04 +10002329class FSConverter_converter(CConverter):
2330 type = 'PyObject *'
2331 converter = 'PyUnicode_FSConverter'
2332 def converter_init(self):
2333 if self.default is not unspecified:
2334 fail("FSConverter_converter does not support default values")
2335 self.c_default = 'NULL'
2336
2337 def cleanup(self):
2338 return "Py_XDECREF(" + self.name + ");\n"
2339
2340class pid_t_converter(CConverter):
2341 type = 'pid_t'
2342 format_unit = '" _Py_PARSE_PID "'
2343
2344class idtype_t_converter(int_converter):
2345 type = 'idtype_t'
2346
2347class id_t_converter(CConverter):
2348 type = 'id_t'
2349 format_unit = '" _Py_PARSE_PID "'
2350
Benjamin Petersonca470632016-09-06 13:47:26 -07002351class intptr_t_converter(CConverter):
2352 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002353 format_unit = '" _Py_PARSE_INTPTR "'
2354
2355class Py_off_t_converter(CConverter):
2356 type = 'Py_off_t'
2357 converter = 'Py_off_t_converter'
2358
2359class Py_off_t_return_converter(long_return_converter):
2360 type = 'Py_off_t'
2361 conversion_fn = 'PyLong_FromPy_off_t'
2362
2363class path_confname_converter(CConverter):
2364 type="int"
2365 converter="conv_path_confname"
2366
2367class confstr_confname_converter(path_confname_converter):
2368 converter='conv_confstr_confname'
2369
2370class sysconf_confname_converter(path_confname_converter):
2371 converter="conv_sysconf_confname"
2372
2373class sched_param_converter(CConverter):
2374 type = 'struct sched_param'
2375 converter = 'convert_sched_param'
2376 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002377
Larry Hastings61272b72014-01-07 12:41:53 -08002378[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002379/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002380
Larry Hastings61272b72014-01-07 12:41:53 -08002381/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002382
Larry Hastings2a727912014-01-16 11:32:01 -08002383os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002384
2385 path : path_t(allow_fd=True)
2386 Path to be examined; can be string, bytes, or open-file-descriptor int.
2387
2388 *
2389
Larry Hastings2f936352014-08-05 14:04:04 +10002390 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002391 If not None, it should be a file descriptor open to a directory,
2392 and path should be a relative string; path will then be relative to
2393 that directory.
2394
2395 follow_symlinks: bool = True
2396 If False, and the last element of the path is a symbolic link,
2397 stat will examine the symbolic link itself instead of the file
2398 the link points to.
2399
2400Perform a stat system call on the given path.
2401
2402dir_fd and follow_symlinks may not be implemented
2403 on your platform. If they are unavailable, using them will raise a
2404 NotImplementedError.
2405
2406It's an error to use dir_fd or follow_symlinks when specifying path as
2407 an open file descriptor.
2408
Larry Hastings61272b72014-01-07 12:41:53 -08002409[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002410
Larry Hastings31826802013-10-19 00:09:25 -07002411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002412os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2413/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002414{
2415 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2416}
2417
Larry Hastings2f936352014-08-05 14:04:04 +10002418
2419/*[clinic input]
2420os.lstat
2421
2422 path : path_t
2423
2424 *
2425
2426 dir_fd : dir_fd(requires='fstatat') = None
2427
2428Perform a stat system call on the given path, without following symbolic links.
2429
2430Like stat(), but do not follow symbolic links.
2431Equivalent to stat(path, follow_symlinks=False).
2432[clinic start generated code]*/
2433
Larry Hastings2f936352014-08-05 14:04:04 +10002434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002435os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2436/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002437{
2438 int follow_symlinks = 0;
2439 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2440}
Larry Hastings31826802013-10-19 00:09:25 -07002441
Larry Hastings2f936352014-08-05 14:04:04 +10002442
Larry Hastings61272b72014-01-07 12:41:53 -08002443/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002444os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002445
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002446 path: path_t
2447 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002448
2449 mode: int
2450 Operating-system mode bitfield. Can be F_OK to test existence,
2451 or the inclusive-OR of R_OK, W_OK, and X_OK.
2452
2453 *
2454
Larry Hastings2f936352014-08-05 14:04:04 +10002455 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002456 If not None, it should be a file descriptor open to a directory,
2457 and path should be relative; path will then be relative to that
2458 directory.
2459
2460 effective_ids: bool = False
2461 If True, access will use the effective uid/gid instead of
2462 the real uid/gid.
2463
2464 follow_symlinks: bool = True
2465 If False, and the last element of the path is a symbolic link,
2466 access will examine the symbolic link itself instead of the file
2467 the link points to.
2468
2469Use the real uid/gid to test for access to a path.
2470
2471{parameters}
2472dir_fd, effective_ids, and follow_symlinks may not be implemented
2473 on your platform. If they are unavailable, using them will raise a
2474 NotImplementedError.
2475
2476Note that most operations will use the effective uid/gid, therefore this
2477 routine can be used in a suid/sgid environment to test if the invoking user
2478 has the specified access to the path.
2479
Larry Hastings61272b72014-01-07 12:41:53 -08002480[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002481
Larry Hastings2f936352014-08-05 14:04:04 +10002482static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002483os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002484 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002485/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002486{
Larry Hastings2f936352014-08-05 14:04:04 +10002487 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002488
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002489#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002490 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002491#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002492 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002493#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002494
Larry Hastings9cf065c2012-06-22 16:30:09 -07002495#ifndef HAVE_FACCESSAT
2496 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002497 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002498
2499 if (effective_ids) {
2500 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002501 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002502 }
2503#endif
2504
2505#ifdef MS_WINDOWS
2506 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002507 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508 Py_END_ALLOW_THREADS
2509
2510 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002511 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002512 * * we didn't get a -1, and
2513 * * write access wasn't requested,
2514 * * or the file isn't read-only,
2515 * * or it's a directory.
2516 * (Directories cannot be read-only on Windows.)
2517 */
Larry Hastings2f936352014-08-05 14:04:04 +10002518 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002519 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002520 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002521 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002522#else
2523
2524 Py_BEGIN_ALLOW_THREADS
2525#ifdef HAVE_FACCESSAT
2526 if ((dir_fd != DEFAULT_DIR_FD) ||
2527 effective_ids ||
2528 !follow_symlinks) {
2529 int flags = 0;
2530 if (!follow_symlinks)
2531 flags |= AT_SYMLINK_NOFOLLOW;
2532 if (effective_ids)
2533 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002534 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002535 }
2536 else
2537#endif
Larry Hastings31826802013-10-19 00:09:25 -07002538 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002540 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541#endif
2542
Larry Hastings9cf065c2012-06-22 16:30:09 -07002543 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002544}
2545
Guido van Rossumd371ff11999-01-25 16:12:23 +00002546#ifndef F_OK
2547#define F_OK 0
2548#endif
2549#ifndef R_OK
2550#define R_OK 4
2551#endif
2552#ifndef W_OK
2553#define W_OK 2
2554#endif
2555#ifndef X_OK
2556#define X_OK 1
2557#endif
2558
Larry Hastings31826802013-10-19 00:09:25 -07002559
Guido van Rossumd371ff11999-01-25 16:12:23 +00002560#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002561/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002562os.ttyname -> DecodeFSDefault
2563
2564 fd: int
2565 Integer file descriptor handle.
2566
2567 /
2568
2569Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002570[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002571
Larry Hastings31826802013-10-19 00:09:25 -07002572static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002573os_ttyname_impl(PyObject *module, int fd)
2574/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002575{
2576 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002577
Larry Hastings31826802013-10-19 00:09:25 -07002578 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002579 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002580 posix_error();
2581 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002582}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002583#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002584
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002585#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002586/*[clinic input]
2587os.ctermid
2588
2589Return the name of the controlling terminal for this process.
2590[clinic start generated code]*/
2591
Larry Hastings2f936352014-08-05 14:04:04 +10002592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002593os_ctermid_impl(PyObject *module)
2594/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002595{
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 char *ret;
2597 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002598
Greg Wardb48bc172000-03-01 21:51:56 +00002599#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002600 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002601#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002602 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002603#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002604 if (ret == NULL)
2605 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002606 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002607}
Larry Hastings2f936352014-08-05 14:04:04 +10002608#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002609
Larry Hastings2f936352014-08-05 14:04:04 +10002610
2611/*[clinic input]
2612os.chdir
2613
2614 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2615
2616Change the current working directory to the specified path.
2617
2618path may always be specified as a string.
2619On some platforms, path may also be specified as an open file descriptor.
2620 If this functionality is unavailable, using it raises an exception.
2621[clinic start generated code]*/
2622
Larry Hastings2f936352014-08-05 14:04:04 +10002623static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002624os_chdir_impl(PyObject *module, path_t *path)
2625/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002626{
2627 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002628
2629 Py_BEGIN_ALLOW_THREADS
2630#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002631 /* on unix, success = 0, on windows, success = !0 */
2632 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002633#else
2634#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002635 if (path->fd != -1)
2636 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002637 else
2638#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002639 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002640#endif
2641 Py_END_ALLOW_THREADS
2642
2643 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002644 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002645 }
2646
Larry Hastings2f936352014-08-05 14:04:04 +10002647 Py_RETURN_NONE;
2648}
2649
2650
2651#ifdef HAVE_FCHDIR
2652/*[clinic input]
2653os.fchdir
2654
2655 fd: fildes
2656
2657Change to the directory of the given file descriptor.
2658
2659fd must be opened on a directory, not a file.
2660Equivalent to os.chdir(fd).
2661
2662[clinic start generated code]*/
2663
Fred Drake4d1e64b2002-04-15 19:40:07 +00002664static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002665os_fchdir_impl(PyObject *module, int fd)
2666/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002667{
Larry Hastings2f936352014-08-05 14:04:04 +10002668 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002669}
2670#endif /* HAVE_FCHDIR */
2671
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002672
Larry Hastings2f936352014-08-05 14:04:04 +10002673/*[clinic input]
2674os.chmod
2675
2676 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2677 Path to be modified. May always be specified as a str or bytes.
2678 On some platforms, path may also be specified as an open file descriptor.
2679 If this functionality is unavailable, using it raises an exception.
2680
2681 mode: int
2682 Operating-system mode bitfield.
2683
2684 *
2685
2686 dir_fd : dir_fd(requires='fchmodat') = None
2687 If not None, it should be a file descriptor open to a directory,
2688 and path should be relative; path will then be relative to that
2689 directory.
2690
2691 follow_symlinks: bool = True
2692 If False, and the last element of the path is a symbolic link,
2693 chmod will modify the symbolic link itself instead of the file
2694 the link points to.
2695
2696Change the access permissions of a file.
2697
2698It is an error to use dir_fd or follow_symlinks when specifying path as
2699 an open file descriptor.
2700dir_fd and follow_symlinks may not be implemented on your platform.
2701 If they are unavailable, using them will raise a NotImplementedError.
2702
2703[clinic start generated code]*/
2704
Larry Hastings2f936352014-08-05 14:04:04 +10002705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002706os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002707 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002708/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002709{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002710 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002712#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002713 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002714#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002715
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716#ifdef HAVE_FCHMODAT
2717 int fchmodat_nofollow_unsupported = 0;
2718#endif
2719
Larry Hastings9cf065c2012-06-22 16:30:09 -07002720#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2721 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002722 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723#endif
2724
2725#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002726 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002727 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002728 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 result = 0;
2730 else {
2731 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002732 attr &= ~FILE_ATTRIBUTE_READONLY;
2733 else
2734 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002735 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002736 }
2737 Py_END_ALLOW_THREADS
2738
2739 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002740 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002741 }
2742#else /* MS_WINDOWS */
2743 Py_BEGIN_ALLOW_THREADS
2744#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002745 if (path->fd != -1)
2746 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002747 else
2748#endif
2749#ifdef HAVE_LCHMOD
2750 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002751 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002752 else
2753#endif
2754#ifdef HAVE_FCHMODAT
2755 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2756 /*
2757 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2758 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002759 * and then says it isn't implemented yet.
2760 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002761 *
2762 * Once it is supported, os.chmod will automatically
2763 * support dir_fd and follow_symlinks=False. (Hopefully.)
2764 * Until then, we need to be careful what exception we raise.
2765 */
Larry Hastings2f936352014-08-05 14:04:04 +10002766 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002767 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2768 /*
2769 * But wait! We can't throw the exception without allowing threads,
2770 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2771 */
2772 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002773 result &&
2774 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2775 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002776 }
2777 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002778#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002779 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780 Py_END_ALLOW_THREADS
2781
2782 if (result) {
2783#ifdef HAVE_FCHMODAT
2784 if (fchmodat_nofollow_unsupported) {
2785 if (dir_fd != DEFAULT_DIR_FD)
2786 dir_fd_and_follow_symlinks_invalid("chmod",
2787 dir_fd, follow_symlinks);
2788 else
2789 follow_symlinks_specified("chmod", follow_symlinks);
2790 }
2791 else
2792#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002793 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794 }
2795#endif
2796
Larry Hastings2f936352014-08-05 14:04:04 +10002797 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002798}
2799
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800
Christian Heimes4e30a842007-11-30 22:12:06 +00002801#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002802/*[clinic input]
2803os.fchmod
2804
2805 fd: int
2806 mode: int
2807
2808Change the access permissions of the file given by file descriptor fd.
2809
2810Equivalent to os.chmod(fd, mode).
2811[clinic start generated code]*/
2812
Larry Hastings2f936352014-08-05 14:04:04 +10002813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002814os_fchmod_impl(PyObject *module, int fd, int mode)
2815/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002816{
2817 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002818 int async_err = 0;
2819
2820 do {
2821 Py_BEGIN_ALLOW_THREADS
2822 res = fchmod(fd, mode);
2823 Py_END_ALLOW_THREADS
2824 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2825 if (res != 0)
2826 return (!async_err) ? posix_error() : NULL;
2827
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002829}
2830#endif /* HAVE_FCHMOD */
2831
Larry Hastings2f936352014-08-05 14:04:04 +10002832
Christian Heimes4e30a842007-11-30 22:12:06 +00002833#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002834/*[clinic input]
2835os.lchmod
2836
2837 path: path_t
2838 mode: int
2839
2840Change the access permissions of a file, without following symbolic links.
2841
2842If path is a symlink, this affects the link itself rather than the target.
2843Equivalent to chmod(path, mode, follow_symlinks=False)."
2844[clinic start generated code]*/
2845
Larry Hastings2f936352014-08-05 14:04:04 +10002846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002847os_lchmod_impl(PyObject *module, path_t *path, int mode)
2848/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002849{
Victor Stinner8c62be82010-05-06 00:08:46 +00002850 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002852 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002854 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002855 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002856 return NULL;
2857 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002859}
2860#endif /* HAVE_LCHMOD */
2861
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002862
Thomas Wouterscf297e42007-02-23 15:07:44 +00002863#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002864/*[clinic input]
2865os.chflags
2866
2867 path: path_t
2868 flags: unsigned_long(bitwise=True)
2869 follow_symlinks: bool=True
2870
2871Set file flags.
2872
2873If follow_symlinks is False, and the last element of the path is a symbolic
2874 link, chflags will change flags on the symbolic link itself instead of the
2875 file the link points to.
2876follow_symlinks may not be implemented on your platform. If it is
2877unavailable, using it will raise a NotImplementedError.
2878
2879[clinic start generated code]*/
2880
Larry Hastings2f936352014-08-05 14:04:04 +10002881static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002882os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002883 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002884/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002885{
2886 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887
2888#ifndef HAVE_LCHFLAGS
2889 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002890 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002891#endif
2892
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002894#ifdef HAVE_LCHFLAGS
2895 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002896 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897 else
2898#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002899 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002900 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002901
Larry Hastings2f936352014-08-05 14:04:04 +10002902 if (result)
2903 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002904
Larry Hastings2f936352014-08-05 14:04:04 +10002905 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002906}
2907#endif /* HAVE_CHFLAGS */
2908
Larry Hastings2f936352014-08-05 14:04:04 +10002909
Thomas Wouterscf297e42007-02-23 15:07:44 +00002910#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002911/*[clinic input]
2912os.lchflags
2913
2914 path: path_t
2915 flags: unsigned_long(bitwise=True)
2916
2917Set file flags.
2918
2919This function will not follow symbolic links.
2920Equivalent to chflags(path, flags, follow_symlinks=False).
2921[clinic start generated code]*/
2922
Larry Hastings2f936352014-08-05 14:04:04 +10002923static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002924os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2925/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002926{
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002929 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002931 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002932 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002933 }
Victor Stinner292c8352012-10-30 02:17:38 +01002934 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002935}
2936#endif /* HAVE_LCHFLAGS */
2937
Larry Hastings2f936352014-08-05 14:04:04 +10002938
Martin v. Löwis244edc82001-10-04 22:44:26 +00002939#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002940/*[clinic input]
2941os.chroot
2942 path: path_t
2943
2944Change root directory to path.
2945
2946[clinic start generated code]*/
2947
Larry Hastings2f936352014-08-05 14:04:04 +10002948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002949os_chroot_impl(PyObject *module, path_t *path)
2950/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002951{
2952 int res;
2953 Py_BEGIN_ALLOW_THREADS
2954 res = chroot(path->narrow);
2955 Py_END_ALLOW_THREADS
2956 if (res < 0)
2957 return path_error(path);
2958 Py_RETURN_NONE;
2959}
2960#endif /* HAVE_CHROOT */
2961
Martin v. Löwis244edc82001-10-04 22:44:26 +00002962
Guido van Rossum21142a01999-01-08 21:05:37 +00002963#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002964/*[clinic input]
2965os.fsync
2966
2967 fd: fildes
2968
2969Force write of fd to disk.
2970[clinic start generated code]*/
2971
Larry Hastings2f936352014-08-05 14:04:04 +10002972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002973os_fsync_impl(PyObject *module, int fd)
2974/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002975{
2976 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002977}
2978#endif /* HAVE_FSYNC */
2979
Larry Hastings2f936352014-08-05 14:04:04 +10002980
Ross Lagerwall7807c352011-03-17 20:20:30 +02002981#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002982/*[clinic input]
2983os.sync
2984
2985Force write of everything to disk.
2986[clinic start generated code]*/
2987
Larry Hastings2f936352014-08-05 14:04:04 +10002988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002989os_sync_impl(PyObject *module)
2990/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002991{
2992 Py_BEGIN_ALLOW_THREADS
2993 sync();
2994 Py_END_ALLOW_THREADS
2995 Py_RETURN_NONE;
2996}
Larry Hastings2f936352014-08-05 14:04:04 +10002997#endif /* HAVE_SYNC */
2998
Ross Lagerwall7807c352011-03-17 20:20:30 +02002999
Guido van Rossum21142a01999-01-08 21:05:37 +00003000#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003001#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003002extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3003#endif
3004
Larry Hastings2f936352014-08-05 14:04:04 +10003005/*[clinic input]
3006os.fdatasync
3007
3008 fd: fildes
3009
3010Force write of fd to disk without forcing update of metadata.
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_fdatasync_impl(PyObject *module, int fd)
3015/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
3017 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003018}
3019#endif /* HAVE_FDATASYNC */
3020
3021
Fredrik Lundh10723342000-07-10 16:38:09 +00003022#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003023/*[clinic input]
3024os.chown
3025
3026 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3027 Path to be examined; can be string, bytes, or open-file-descriptor int.
3028
3029 uid: uid_t
3030
3031 gid: gid_t
3032
3033 *
3034
3035 dir_fd : dir_fd(requires='fchownat') = None
3036 If not None, it should be a file descriptor open to a directory,
3037 and path should be relative; path will then be relative to that
3038 directory.
3039
3040 follow_symlinks: bool = True
3041 If False, and the last element of the path is a symbolic link,
3042 stat will examine the symbolic link itself instead of the file
3043 the link points to.
3044
3045Change the owner and group id of path to the numeric uid and gid.\
3046
3047path may always be specified as a string.
3048On some platforms, path may also be specified as an open file descriptor.
3049 If this functionality is unavailable, using it raises an exception.
3050If dir_fd is not None, it should be a file descriptor open to a directory,
3051 and path should be relative; path will then be relative to that directory.
3052If follow_symlinks is False, and the last element of the path is a symbolic
3053 link, chown will modify the symbolic link itself instead of the file the
3054 link points to.
3055It is an error to use dir_fd or follow_symlinks when specifying path as
3056 an open file descriptor.
3057dir_fd and follow_symlinks may not be implemented on your platform.
3058 If they are unavailable, using them will raise a NotImplementedError.
3059
3060[clinic start generated code]*/
3061
Larry Hastings2f936352014-08-05 14:04:04 +10003062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003063os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003064 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003065/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003066{
3067 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003068
3069#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3070 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003071 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003073 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3074 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3075 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076
3077#ifdef __APPLE__
3078 /*
3079 * This is for Mac OS X 10.3, which doesn't have lchown.
3080 * (But we still have an lchown symbol because of weak-linking.)
3081 * It doesn't have fchownat either. So there's no possibility
3082 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003083 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003084 if ((!follow_symlinks) && (lchown == NULL)) {
3085 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003086 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087 }
3088#endif
3089
Victor Stinner8c62be82010-05-06 00:08:46 +00003090 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003091#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003092 if (path->fd != -1)
3093 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003094 else
3095#endif
3096#ifdef HAVE_LCHOWN
3097 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003098 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003099 else
3100#endif
3101#ifdef HAVE_FCHOWNAT
3102 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003103 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003104 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3105 else
3106#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003107 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003108 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003109
Larry Hastings2f936352014-08-05 14:04:04 +10003110 if (result)
3111 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003112
Larry Hastings2f936352014-08-05 14:04:04 +10003113 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003114}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003115#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003116
Larry Hastings2f936352014-08-05 14:04:04 +10003117
Christian Heimes4e30a842007-11-30 22:12:06 +00003118#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003119/*[clinic input]
3120os.fchown
3121
3122 fd: int
3123 uid: uid_t
3124 gid: gid_t
3125
3126Change the owner and group id of the file specified by file descriptor.
3127
3128Equivalent to os.chown(fd, uid, gid).
3129
3130[clinic start generated code]*/
3131
Larry Hastings2f936352014-08-05 14:04:04 +10003132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003133os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3134/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003135{
Victor Stinner8c62be82010-05-06 00:08:46 +00003136 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003137 int async_err = 0;
3138
3139 do {
3140 Py_BEGIN_ALLOW_THREADS
3141 res = fchown(fd, uid, gid);
3142 Py_END_ALLOW_THREADS
3143 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3144 if (res != 0)
3145 return (!async_err) ? posix_error() : NULL;
3146
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003148}
3149#endif /* HAVE_FCHOWN */
3150
Larry Hastings2f936352014-08-05 14:04:04 +10003151
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003152#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003153/*[clinic input]
3154os.lchown
3155
3156 path : path_t
3157 uid: uid_t
3158 gid: gid_t
3159
3160Change the owner and group id of path to the numeric uid and gid.
3161
3162This function will not follow symbolic links.
3163Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3164[clinic start generated code]*/
3165
Larry Hastings2f936352014-08-05 14:04:04 +10003166static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003167os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3168/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003169{
Victor Stinner8c62be82010-05-06 00:08:46 +00003170 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003172 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003174 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003175 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003176 }
Larry Hastings2f936352014-08-05 14:04:04 +10003177 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003178}
3179#endif /* HAVE_LCHOWN */
3180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003181
Barry Warsaw53699e91996-12-10 23:23:01 +00003182static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003183posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003184{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003185 char *buf, *tmpbuf;
3186 char *cwd;
3187 const size_t chunk = 1024;
3188 size_t buflen = 0;
3189 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003190
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003191#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003193 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003194 wchar_t *wbuf2 = wbuf;
3195 PyObject *resobj;
3196 DWORD len;
3197 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003198 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 /* If the buffer is large enough, len does not include the
3200 terminating \0. If the buffer is too small, len includes
3201 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003202 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003203 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 if (wbuf2)
3205 len = GetCurrentDirectoryW(len, wbuf2);
3206 }
3207 Py_END_ALLOW_THREADS
3208 if (!wbuf2) {
3209 PyErr_NoMemory();
3210 return NULL;
3211 }
3212 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003213 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003214 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003215 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 }
3217 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003218 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003219 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003220 return resobj;
3221 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003222
3223 if (win32_warn_bytes_api())
3224 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003225#endif
3226
Victor Stinner4403d7d2015-04-25 00:16:10 +02003227 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003229 do {
3230 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003231#ifdef MS_WINDOWS
3232 if (buflen > INT_MAX) {
3233 PyErr_NoMemory();
3234 break;
3235 }
3236#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003237 tmpbuf = PyMem_RawRealloc(buf, buflen);
3238 if (tmpbuf == NULL)
3239 break;
3240
3241 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003242#ifdef MS_WINDOWS
3243 cwd = getcwd(buf, (int)buflen);
3244#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003245 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003246#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003247 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003248 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003249
3250 if (cwd == NULL) {
3251 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003253 }
3254
Victor Stinner8c62be82010-05-06 00:08:46 +00003255 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003256 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3257 else
3258 obj = PyUnicode_DecodeFSDefault(buf);
3259 PyMem_RawFree(buf);
3260
3261 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003262}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003263
Larry Hastings2f936352014-08-05 14:04:04 +10003264
3265/*[clinic input]
3266os.getcwd
3267
3268Return a unicode string representing the current working directory.
3269[clinic start generated code]*/
3270
Larry Hastings2f936352014-08-05 14:04:04 +10003271static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003272os_getcwd_impl(PyObject *module)
3273/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003274{
3275 return posix_getcwd(0);
3276}
3277
Larry Hastings2f936352014-08-05 14:04:04 +10003278
3279/*[clinic input]
3280os.getcwdb
3281
3282Return a bytes string representing the current working directory.
3283[clinic start generated code]*/
3284
Larry Hastings2f936352014-08-05 14:04:04 +10003285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003286os_getcwdb_impl(PyObject *module)
3287/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003288{
3289 return posix_getcwd(1);
3290}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003291
Larry Hastings2f936352014-08-05 14:04:04 +10003292
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3294#define HAVE_LINK 1
3295#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003296
Guido van Rossumb6775db1994-08-01 11:34:53 +00003297#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003298/*[clinic input]
3299
3300os.link
3301
3302 src : path_t
3303 dst : path_t
3304 *
3305 src_dir_fd : dir_fd = None
3306 dst_dir_fd : dir_fd = None
3307 follow_symlinks: bool = True
3308
3309Create a hard link to a file.
3310
3311If either src_dir_fd or dst_dir_fd is not None, it should be a file
3312 descriptor open to a directory, and the respective path string (src or dst)
3313 should be relative; the path will then be relative to that directory.
3314If follow_symlinks is False, and the last element of src is a symbolic
3315 link, link will create a link to the symbolic link itself instead of the
3316 file the link points to.
3317src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3318 platform. If they are unavailable, using them will raise a
3319 NotImplementedError.
3320[clinic start generated code]*/
3321
Larry Hastings2f936352014-08-05 14:04:04 +10003322static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003323os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003324 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003325/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003326{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003327#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003328 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003329#else
3330 int result;
3331#endif
3332
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333#ifndef HAVE_LINKAT
3334 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3335 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003336 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337 }
3338#endif
3339
Steve Dowercc16be82016-09-08 10:35:16 -07003340#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003341 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003342 PyErr_SetString(PyExc_NotImplementedError,
3343 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003344 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003345 }
Steve Dowercc16be82016-09-08 10:35:16 -07003346#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003347
Brian Curtin1b9df392010-11-24 20:24:31 +00003348#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003350 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003351 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003352
Larry Hastings2f936352014-08-05 14:04:04 +10003353 if (!result)
3354 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003355#else
3356 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003357#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3359 (dst_dir_fd != DEFAULT_DIR_FD) ||
3360 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003361 result = linkat(src_dir_fd, src->narrow,
3362 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003363 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3364 else
Steve Dowercc16be82016-09-08 10:35:16 -07003365#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003366 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003367 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003368
Larry Hastings2f936352014-08-05 14:04:04 +10003369 if (result)
3370 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003371#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372
Larry Hastings2f936352014-08-05 14:04:04 +10003373 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003374}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375#endif
3376
Brian Curtin1b9df392010-11-24 20:24:31 +00003377
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003378#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003379static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003380_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003381{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382 PyObject *v;
3383 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3384 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003385 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003387 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389
Steve Dowercc16be82016-09-08 10:35:16 -07003390 WIN32_FIND_DATAW wFileData;
3391 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003392
Steve Dowercc16be82016-09-08 10:35:16 -07003393 if (!path->wide) { /* Default arg: "." */
3394 po_wchars = L".";
3395 len = 1;
3396 } else {
3397 po_wchars = path->wide;
3398 len = wcslen(path->wide);
3399 }
3400 /* The +5 is so we can append "\\*.*\0" */
3401 wnamebuf = PyMem_New(wchar_t, len + 5);
3402 if (!wnamebuf) {
3403 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 }
Steve Dowercc16be82016-09-08 10:35:16 -07003406 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003408 wchar_t wch = wnamebuf[len-1];
3409 if (wch != SEP && wch != ALTSEP && wch != L':')
3410 wnamebuf[len++] = SEP;
3411 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 }
Steve Dowercc16be82016-09-08 10:35:16 -07003413 if ((list = PyList_New(0)) == NULL) {
3414 goto exit;
3415 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003416 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003417 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003418 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 if (hFindFile == INVALID_HANDLE_VALUE) {
3420 int error = GetLastError();
3421 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 goto exit;
3423 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003424 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 }
3427 do {
3428 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003429 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3430 wcscmp(wFileData.cFileName, L"..") != 0) {
3431 v = PyUnicode_FromWideChar(wFileData.cFileName,
3432 wcslen(wFileData.cFileName));
3433 if (path->narrow && v) {
3434 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3435 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003436 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437 Py_DECREF(list);
3438 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 break;
3440 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 Py_DECREF(list);
3444 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 break;
3446 }
3447 Py_DECREF(v);
3448 }
3449 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003450 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 Py_END_ALLOW_THREADS
3452 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3453 it got to the end of the directory. */
3454 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003456 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 }
3459 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461exit:
3462 if (hFindFile != INVALID_HANDLE_VALUE) {
3463 if (FindClose(hFindFile) == FALSE) {
3464 if (list != NULL) {
3465 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003466 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 }
3468 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003470 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003471
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003473} /* end of _listdir_windows_no_opendir */
3474
3475#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3476
3477static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003478_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003479{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003480 PyObject *v;
3481 DIR *dirp = NULL;
3482 struct dirent *ep;
3483 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003484#ifdef HAVE_FDOPENDIR
3485 int fd = -1;
3486#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003487
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003490 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003492 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003493 if (fd == -1)
3494 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495
Larry Hastingsfdaea062012-06-25 04:42:23 -07003496 return_str = 1;
3497
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 Py_BEGIN_ALLOW_THREADS
3499 dirp = fdopendir(fd);
3500 Py_END_ALLOW_THREADS
3501 }
3502 else
3503#endif
3504 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003505 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003506 if (path->narrow) {
3507 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003508 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003509 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003510 }
3511 else {
3512 name = ".";
3513 return_str = 1;
3514 }
3515
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 Py_BEGIN_ALLOW_THREADS
3517 dirp = opendir(name);
3518 Py_END_ALLOW_THREADS
3519 }
3520
3521 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003522 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003523#ifdef HAVE_FDOPENDIR
3524 if (fd != -1) {
3525 Py_BEGIN_ALLOW_THREADS
3526 close(fd);
3527 Py_END_ALLOW_THREADS
3528 }
3529#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 goto exit;
3531 }
3532 if ((list = PyList_New(0)) == NULL) {
3533 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 }
3535 for (;;) {
3536 errno = 0;
3537 Py_BEGIN_ALLOW_THREADS
3538 ep = readdir(dirp);
3539 Py_END_ALLOW_THREADS
3540 if (ep == NULL) {
3541 if (errno == 0) {
3542 break;
3543 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003545 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 }
3548 }
3549 if (ep->d_name[0] == '.' &&
3550 (NAMLEN(ep) == 1 ||
3551 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3552 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003553 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003554 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3555 else
3556 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 break;
3560 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 break;
3565 }
3566 Py_DECREF(v);
3567 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003568
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569exit:
3570 if (dirp != NULL) {
3571 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003572#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 if (fd > -1)
3574 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003575#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 closedir(dirp);
3577 Py_END_ALLOW_THREADS
3578 }
3579
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003581} /* end of _posix_listdir */
3582#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003583
Larry Hastings2f936352014-08-05 14:04:04 +10003584
3585/*[clinic input]
3586os.listdir
3587
3588 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3589
3590Return a list containing the names of the files in the directory.
3591
3592path can be specified as either str or bytes. If path is bytes,
3593 the filenames returned will also be bytes; in all other circumstances
3594 the filenames returned will be str.
3595If path is None, uses the path='.'.
3596On some platforms, path may also be specified as an open file descriptor;\
3597 the file descriptor must refer to a directory.
3598 If this functionality is unavailable, using it raises NotImplementedError.
3599
3600The list is in arbitrary order. It does not include the special
3601entries '.' and '..' even if they are present in the directory.
3602
3603
3604[clinic start generated code]*/
3605
Larry Hastings2f936352014-08-05 14:04:04 +10003606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003607os_listdir_impl(PyObject *module, path_t *path)
3608/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003609{
3610#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3611 return _listdir_windows_no_opendir(path, NULL);
3612#else
3613 return _posix_listdir(path, NULL);
3614#endif
3615}
3616
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003617#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003618/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003619/*[clinic input]
3620os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003621
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003622 path: path_t
3623 /
3624
3625[clinic start generated code]*/
3626
3627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003628os__getfullpathname_impl(PyObject *module, path_t *path)
3629/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003630{
Steve Dowercc16be82016-09-08 10:35:16 -07003631 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3632 wchar_t *wtemp;
3633 DWORD result;
3634 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003635
Steve Dowercc16be82016-09-08 10:35:16 -07003636 result = GetFullPathNameW(path->wide,
3637 Py_ARRAY_LENGTH(woutbuf),
3638 woutbuf, &wtemp);
3639 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3640 woutbufp = PyMem_New(wchar_t, result);
3641 if (!woutbufp)
3642 return PyErr_NoMemory();
3643 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 }
Steve Dowercc16be82016-09-08 10:35:16 -07003645 if (result) {
3646 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3647 if (path->narrow)
3648 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3649 } else
3650 v = win32_error_object("GetFullPathNameW", path->object);
3651 if (woutbufp != woutbuf)
3652 PyMem_Free(woutbufp);
3653 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003654}
Brian Curtind40e6f72010-07-08 21:39:08 +00003655
Brian Curtind25aef52011-06-13 15:16:04 -05003656
Larry Hastings2f936352014-08-05 14:04:04 +10003657/*[clinic input]
3658os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003659
Larry Hastings2f936352014-08-05 14:04:04 +10003660 path: unicode
3661 /
3662
3663A helper function for samepath on windows.
3664[clinic start generated code]*/
3665
Larry Hastings2f936352014-08-05 14:04:04 +10003666static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003667os__getfinalpathname_impl(PyObject *module, PyObject *path)
3668/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003669{
3670 HANDLE hFile;
3671 int buf_size;
3672 wchar_t *target_path;
3673 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003674 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003675 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003676
Larry Hastings2f936352014-08-05 14:04:04 +10003677 path_wchar = PyUnicode_AsUnicode(path);
3678 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003679 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003680
Brian Curtind40e6f72010-07-08 21:39:08 +00003681 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003682 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003683 0, /* desired access */
3684 0, /* share mode */
3685 NULL, /* security attributes */
3686 OPEN_EXISTING,
3687 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3688 FILE_FLAG_BACKUP_SEMANTICS,
3689 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003690
Victor Stinnereb5657a2011-09-30 01:44:27 +02003691 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003692 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003693
3694 /* We have a good handle to the target, use it to determine the
3695 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003696 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003697
3698 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003699 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003700
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003701 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003702 if(!target_path)
3703 return PyErr_NoMemory();
3704
Steve Dower2ea51c92015-03-20 21:49:12 -07003705 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3706 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003707 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003708 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003709
3710 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003711 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003712
3713 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003714 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003715 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003716 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003717}
Brian Curtin62857742010-09-06 17:07:27 +00003718
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003719/*[clinic input]
3720os._isdir
3721
3722 path: path_t
3723 /
3724
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003725Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003726[clinic start generated code]*/
3727
Brian Curtin9c669cc2011-06-08 18:17:18 -05003728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003729os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003730/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003731{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003732 DWORD attributes;
3733
Steve Dowerb22a6772016-07-17 20:49:38 -07003734 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003735 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003736 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003737
Brian Curtin9c669cc2011-06-08 18:17:18 -05003738 if (attributes == INVALID_FILE_ATTRIBUTES)
3739 Py_RETURN_FALSE;
3740
Brian Curtin9c669cc2011-06-08 18:17:18 -05003741 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3742 Py_RETURN_TRUE;
3743 else
3744 Py_RETURN_FALSE;
3745}
Tim Golden6b528062013-08-01 12:44:00 +01003746
Tim Golden6b528062013-08-01 12:44:00 +01003747
Larry Hastings2f936352014-08-05 14:04:04 +10003748/*[clinic input]
3749os._getvolumepathname
3750
3751 path: unicode
3752
3753A helper function for ismount on Win32.
3754[clinic start generated code]*/
3755
Larry Hastings2f936352014-08-05 14:04:04 +10003756static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003757os__getvolumepathname_impl(PyObject *module, PyObject *path)
3758/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003759{
3760 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003761 const wchar_t *path_wchar;
3762 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003763 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003764 BOOL ret;
3765
Larry Hastings2f936352014-08-05 14:04:04 +10003766 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3767 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003768 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003769 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003770
3771 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003772 buflen = Py_MAX(buflen, MAX_PATH);
3773
3774 if (buflen > DWORD_MAX) {
3775 PyErr_SetString(PyExc_OverflowError, "path too long");
3776 return NULL;
3777 }
3778
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003779 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003780 if (mountpath == NULL)
3781 return PyErr_NoMemory();
3782
3783 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003784 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003785 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003786 Py_END_ALLOW_THREADS
3787
3788 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003789 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003790 goto exit;
3791 }
3792 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3793
3794exit:
3795 PyMem_Free(mountpath);
3796 return result;
3797}
Tim Golden6b528062013-08-01 12:44:00 +01003798
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003799#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003800
Larry Hastings2f936352014-08-05 14:04:04 +10003801
3802/*[clinic input]
3803os.mkdir
3804
3805 path : path_t
3806
3807 mode: int = 0o777
3808
3809 *
3810
3811 dir_fd : dir_fd(requires='mkdirat') = None
3812
3813# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3814
3815Create a directory.
3816
3817If dir_fd is not None, it should be a file descriptor open to a directory,
3818 and path should be relative; path will then be relative to that directory.
3819dir_fd may not be implemented on your platform.
3820 If it is unavailable, using it will raise a NotImplementedError.
3821
3822The mode argument is ignored on Windows.
3823[clinic start generated code]*/
3824
Larry Hastings2f936352014-08-05 14:04:04 +10003825static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003826os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3827/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003828{
3829 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003830
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003831#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003832 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003833 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003835
Larry Hastings2f936352014-08-05 14:04:04 +10003836 if (!result)
3837 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003838#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003839 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003840#if HAVE_MKDIRAT
3841 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003842 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003843 else
3844#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003845#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003846 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003847#else
Larry Hastings2f936352014-08-05 14:04:04 +10003848 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003849#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003851 if (result < 0)
3852 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003853#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003854 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003855}
3856
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003857
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003858/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3859#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003860#include <sys/resource.h>
3861#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003862
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003863
3864#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003865/*[clinic input]
3866os.nice
3867
3868 increment: int
3869 /
3870
3871Add increment to the priority of process and return the new priority.
3872[clinic start generated code]*/
3873
Larry Hastings2f936352014-08-05 14:04:04 +10003874static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003875os_nice_impl(PyObject *module, int increment)
3876/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003877{
3878 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003879
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 /* There are two flavours of 'nice': one that returns the new
3881 priority (as required by almost all standards out there) and the
3882 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3883 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003884
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 If we are of the nice family that returns the new priority, we
3886 need to clear errno before the call, and check if errno is filled
3887 before calling posix_error() on a returnvalue of -1, because the
3888 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003889
Victor Stinner8c62be82010-05-06 00:08:46 +00003890 errno = 0;
3891 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003892#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 if (value == 0)
3894 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003895#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 if (value == -1 && errno != 0)
3897 /* either nice() or getpriority() returned an error */
3898 return posix_error();
3899 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003900}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003901#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003902
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003903
3904#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003905/*[clinic input]
3906os.getpriority
3907
3908 which: int
3909 who: int
3910
3911Return program scheduling priority.
3912[clinic start generated code]*/
3913
Larry Hastings2f936352014-08-05 14:04:04 +10003914static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003915os_getpriority_impl(PyObject *module, int which, int who)
3916/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003917{
3918 int retval;
3919
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003920 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003921 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003922 if (errno != 0)
3923 return posix_error();
3924 return PyLong_FromLong((long)retval);
3925}
3926#endif /* HAVE_GETPRIORITY */
3927
3928
3929#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003930/*[clinic input]
3931os.setpriority
3932
3933 which: int
3934 who: int
3935 priority: int
3936
3937Set program scheduling priority.
3938[clinic start generated code]*/
3939
Larry Hastings2f936352014-08-05 14:04:04 +10003940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003941os_setpriority_impl(PyObject *module, int which, int who, int priority)
3942/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003943{
3944 int retval;
3945
3946 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003947 if (retval == -1)
3948 return posix_error();
3949 Py_RETURN_NONE;
3950}
3951#endif /* HAVE_SETPRIORITY */
3952
3953
Barry Warsaw53699e91996-12-10 23:23:01 +00003954static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003955internal_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 +00003956{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003957 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003959
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003960#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003962 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003963#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003964 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003965#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003966
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3968 (dst_dir_fd != DEFAULT_DIR_FD);
3969#ifndef HAVE_RENAMEAT
3970 if (dir_fd_specified) {
3971 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003972 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003973 }
3974#endif
3975
Larry Hastings9cf065c2012-06-22 16:30:09 -07003976#ifdef MS_WINDOWS
3977 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003978 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979 Py_END_ALLOW_THREADS
3980
Larry Hastings2f936352014-08-05 14:04:04 +10003981 if (!result)
3982 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003983
3984#else
Steve Dowercc16be82016-09-08 10:35:16 -07003985 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3986 PyErr_Format(PyExc_ValueError,
3987 "%s: src and dst must be the same type", function_name);
3988 return NULL;
3989 }
3990
Larry Hastings9cf065c2012-06-22 16:30:09 -07003991 Py_BEGIN_ALLOW_THREADS
3992#ifdef HAVE_RENAMEAT
3993 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10003994 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995 else
3996#endif
Steve Dowercc16be82016-09-08 10:35:16 -07003997 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 Py_END_ALLOW_THREADS
3999
Larry Hastings2f936352014-08-05 14:04:04 +10004000 if (result)
4001 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004003 Py_RETURN_NONE;
4004}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005
Larry Hastings2f936352014-08-05 14:04:04 +10004006
4007/*[clinic input]
4008os.rename
4009
4010 src : path_t
4011 dst : path_t
4012 *
4013 src_dir_fd : dir_fd = None
4014 dst_dir_fd : dir_fd = None
4015
4016Rename a file or directory.
4017
4018If either src_dir_fd or dst_dir_fd is not None, it should be a file
4019 descriptor open to a directory, and the respective path string (src or dst)
4020 should be relative; the path will then be relative to that directory.
4021src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4022 If they are unavailable, using them will raise a NotImplementedError.
4023[clinic start generated code]*/
4024
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004026os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004027 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004028/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004029{
Larry Hastings2f936352014-08-05 14:04:04 +10004030 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004031}
4032
Larry Hastings2f936352014-08-05 14:04:04 +10004033
4034/*[clinic input]
4035os.replace = os.rename
4036
4037Rename a file or directory, overwriting the destination.
4038
4039If either src_dir_fd or dst_dir_fd is not None, it should be a file
4040 descriptor open to a directory, and the respective path string (src or dst)
4041 should be relative; the path will then be relative to that directory.
4042src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4043 If they are unavailable, using them will raise a NotImplementedError."
4044[clinic start generated code]*/
4045
Larry Hastings2f936352014-08-05 14:04:04 +10004046static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004047os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4048 int dst_dir_fd)
4049/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004050{
4051 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4052}
4053
4054
4055/*[clinic input]
4056os.rmdir
4057
4058 path: path_t
4059 *
4060 dir_fd: dir_fd(requires='unlinkat') = None
4061
4062Remove a directory.
4063
4064If dir_fd is not None, it should be a file descriptor open to a directory,
4065 and path should be relative; path will then be relative to that directory.
4066dir_fd may not be implemented on your platform.
4067 If it is unavailable, using it will raise a NotImplementedError.
4068[clinic start generated code]*/
4069
Larry Hastings2f936352014-08-05 14:04:04 +10004070static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004071os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4072/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004073{
4074 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004075
4076 Py_BEGIN_ALLOW_THREADS
4077#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004078 /* Windows, success=1, UNIX, success=0 */
4079 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004080#else
4081#ifdef HAVE_UNLINKAT
4082 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004083 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004084 else
4085#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004086 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004087#endif
4088 Py_END_ALLOW_THREADS
4089
Larry Hastings2f936352014-08-05 14:04:04 +10004090 if (result)
4091 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004092
Larry Hastings2f936352014-08-05 14:04:04 +10004093 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004094}
4095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004096
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004097#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004098#ifdef MS_WINDOWS
4099/*[clinic input]
4100os.system -> long
4101
4102 command: Py_UNICODE
4103
4104Execute the command in a subshell.
4105[clinic start generated code]*/
4106
Larry Hastings2f936352014-08-05 14:04:04 +10004107static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004108os_system_impl(PyObject *module, Py_UNICODE *command)
4109/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004110{
4111 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004112 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004113 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004114 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004115 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004116 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004117 return result;
4118}
4119#else /* MS_WINDOWS */
4120/*[clinic input]
4121os.system -> long
4122
4123 command: FSConverter
4124
4125Execute the command in a subshell.
4126[clinic start generated code]*/
4127
Larry Hastings2f936352014-08-05 14:04:04 +10004128static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004129os_system_impl(PyObject *module, PyObject *command)
4130/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004131{
4132 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004133 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004134 Py_BEGIN_ALLOW_THREADS
4135 result = system(bytes);
4136 Py_END_ALLOW_THREADS
4137 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004138}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004139#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004140#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004141
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Larry Hastings2f936352014-08-05 14:04:04 +10004143/*[clinic input]
4144os.umask
4145
4146 mask: int
4147 /
4148
4149Set the current numeric umask and return the previous umask.
4150[clinic start generated code]*/
4151
Larry Hastings2f936352014-08-05 14:04:04 +10004152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004153os_umask_impl(PyObject *module, int mask)
4154/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004155{
4156 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004157 if (i < 0)
4158 return posix_error();
4159 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004160}
4161
Brian Curtind40e6f72010-07-08 21:39:08 +00004162#ifdef MS_WINDOWS
4163
4164/* override the default DeleteFileW behavior so that directory
4165symlinks can be removed with this function, the same as with
4166Unix symlinks */
4167BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4168{
4169 WIN32_FILE_ATTRIBUTE_DATA info;
4170 WIN32_FIND_DATAW find_data;
4171 HANDLE find_data_handle;
4172 int is_directory = 0;
4173 int is_link = 0;
4174
4175 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4176 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004177
Brian Curtind40e6f72010-07-08 21:39:08 +00004178 /* Get WIN32_FIND_DATA structure for the path to determine if
4179 it is a symlink */
4180 if(is_directory &&
4181 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4182 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4183
4184 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004185 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4186 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4187 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4188 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004189 FindClose(find_data_handle);
4190 }
4191 }
4192 }
4193
4194 if (is_directory && is_link)
4195 return RemoveDirectoryW(lpFileName);
4196
4197 return DeleteFileW(lpFileName);
4198}
4199#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004201
Larry Hastings2f936352014-08-05 14:04:04 +10004202/*[clinic input]
4203os.unlink
4204
4205 path: path_t
4206 *
4207 dir_fd: dir_fd(requires='unlinkat')=None
4208
4209Remove a file (same as remove()).
4210
4211If dir_fd is not None, it should be a file descriptor open to a directory,
4212 and path should be relative; path will then be relative to that directory.
4213dir_fd may not be implemented on your platform.
4214 If it is unavailable, using it will raise a NotImplementedError.
4215
4216[clinic start generated code]*/
4217
Larry Hastings2f936352014-08-05 14:04:04 +10004218static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004219os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4220/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004221{
4222 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004223
4224 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004225 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004226#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004227 /* Windows, success=1, UNIX, success=0 */
4228 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004229#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004230#ifdef HAVE_UNLINKAT
4231 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004232 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233 else
4234#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004235 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004236#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004237 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004238 Py_END_ALLOW_THREADS
4239
Larry Hastings2f936352014-08-05 14:04:04 +10004240 if (result)
4241 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004242
Larry Hastings2f936352014-08-05 14:04:04 +10004243 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004244}
4245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004246
Larry Hastings2f936352014-08-05 14:04:04 +10004247/*[clinic input]
4248os.remove = os.unlink
4249
4250Remove a file (same as unlink()).
4251
4252If dir_fd is not None, it should be a file descriptor open to a directory,
4253 and path should be relative; path will then be relative to that directory.
4254dir_fd may not be implemented on your platform.
4255 If it is unavailable, using it will raise a NotImplementedError.
4256[clinic start generated code]*/
4257
Larry Hastings2f936352014-08-05 14:04:04 +10004258static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004259os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4260/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004261{
4262 return os_unlink_impl(module, path, dir_fd);
4263}
4264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004265
Larry Hastings605a62d2012-06-24 04:33:36 -07004266static PyStructSequence_Field uname_result_fields[] = {
4267 {"sysname", "operating system name"},
4268 {"nodename", "name of machine on network (implementation-defined)"},
4269 {"release", "operating system release"},
4270 {"version", "operating system version"},
4271 {"machine", "hardware identifier"},
4272 {NULL}
4273};
4274
4275PyDoc_STRVAR(uname_result__doc__,
4276"uname_result: Result from os.uname().\n\n\
4277This object may be accessed either as a tuple of\n\
4278 (sysname, nodename, release, version, machine),\n\
4279or via the attributes sysname, nodename, release, version, and machine.\n\
4280\n\
4281See os.uname for more information.");
4282
4283static PyStructSequence_Desc uname_result_desc = {
4284 "uname_result", /* name */
4285 uname_result__doc__, /* doc */
4286 uname_result_fields,
4287 5
4288};
4289
4290static PyTypeObject UnameResultType;
4291
4292
4293#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004294/*[clinic input]
4295os.uname
4296
4297Return an object identifying the current operating system.
4298
4299The object behaves like a named tuple with the following fields:
4300 (sysname, nodename, release, version, machine)
4301
4302[clinic start generated code]*/
4303
Larry Hastings2f936352014-08-05 14:04:04 +10004304static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004305os_uname_impl(PyObject *module)
4306/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004307{
Victor Stinner8c62be82010-05-06 00:08:46 +00004308 struct utsname u;
4309 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004310 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004311
Victor Stinner8c62be82010-05-06 00:08:46 +00004312 Py_BEGIN_ALLOW_THREADS
4313 res = uname(&u);
4314 Py_END_ALLOW_THREADS
4315 if (res < 0)
4316 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004317
4318 value = PyStructSequence_New(&UnameResultType);
4319 if (value == NULL)
4320 return NULL;
4321
4322#define SET(i, field) \
4323 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004324 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004325 if (!o) { \
4326 Py_DECREF(value); \
4327 return NULL; \
4328 } \
4329 PyStructSequence_SET_ITEM(value, i, o); \
4330 } \
4331
4332 SET(0, u.sysname);
4333 SET(1, u.nodename);
4334 SET(2, u.release);
4335 SET(3, u.version);
4336 SET(4, u.machine);
4337
4338#undef SET
4339
4340 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004341}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004342#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004343
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004344
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345
4346typedef struct {
4347 int now;
4348 time_t atime_s;
4349 long atime_ns;
4350 time_t mtime_s;
4351 long mtime_ns;
4352} utime_t;
4353
4354/*
Victor Stinner484df002014-10-09 13:52:31 +02004355 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004356 * they also intentionally leak the declaration of a pointer named "time"
4357 */
4358#define UTIME_TO_TIMESPEC \
4359 struct timespec ts[2]; \
4360 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004361 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004362 time = NULL; \
4363 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004364 ts[0].tv_sec = ut->atime_s; \
4365 ts[0].tv_nsec = ut->atime_ns; \
4366 ts[1].tv_sec = ut->mtime_s; \
4367 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368 time = ts; \
4369 } \
4370
4371#define UTIME_TO_TIMEVAL \
4372 struct timeval tv[2]; \
4373 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004374 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004375 time = NULL; \
4376 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004377 tv[0].tv_sec = ut->atime_s; \
4378 tv[0].tv_usec = ut->atime_ns / 1000; \
4379 tv[1].tv_sec = ut->mtime_s; \
4380 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004381 time = tv; \
4382 } \
4383
4384#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004385 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004387 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004388 time = NULL; \
4389 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004390 u.actime = ut->atime_s; \
4391 u.modtime = ut->mtime_s; \
4392 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004393 }
4394
4395#define UTIME_TO_TIME_T \
4396 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004397 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004398 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399 time = NULL; \
4400 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004401 timet[0] = ut->atime_s; \
4402 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004403 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004404 } \
4405
4406
Victor Stinner528a9ab2015-09-03 21:30:26 +02004407#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004408
4409static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004410utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004411{
4412#ifdef HAVE_UTIMENSAT
4413 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4414 UTIME_TO_TIMESPEC;
4415 return utimensat(dir_fd, path, time, flags);
4416#elif defined(HAVE_FUTIMESAT)
4417 UTIME_TO_TIMEVAL;
4418 /*
4419 * follow_symlinks will never be false here;
4420 * we only allow !follow_symlinks and dir_fd together
4421 * if we have utimensat()
4422 */
4423 assert(follow_symlinks);
4424 return futimesat(dir_fd, path, time);
4425#endif
4426}
4427
Larry Hastings2f936352014-08-05 14:04:04 +10004428 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4429#else
4430 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004431#endif
4432
Victor Stinner528a9ab2015-09-03 21:30:26 +02004433#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004434
4435static int
Victor Stinner484df002014-10-09 13:52:31 +02004436utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004437{
4438#ifdef HAVE_FUTIMENS
4439 UTIME_TO_TIMESPEC;
4440 return futimens(fd, time);
4441#else
4442 UTIME_TO_TIMEVAL;
4443 return futimes(fd, time);
4444#endif
4445}
4446
Larry Hastings2f936352014-08-05 14:04:04 +10004447 #define PATH_UTIME_HAVE_FD 1
4448#else
4449 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450#endif
4451
Victor Stinner5ebae872015-09-22 01:29:33 +02004452#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4453# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4454#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004455
Victor Stinner4552ced2015-09-21 22:37:15 +02004456#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457
4458static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004459utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004460{
4461#ifdef HAVE_UTIMENSAT
4462 UTIME_TO_TIMESPEC;
4463 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4464#else
4465 UTIME_TO_TIMEVAL;
4466 return lutimes(path, time);
4467#endif
4468}
4469
4470#endif
4471
4472#ifndef MS_WINDOWS
4473
4474static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004475utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476{
4477#ifdef HAVE_UTIMENSAT
4478 UTIME_TO_TIMESPEC;
4479 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4480#elif defined(HAVE_UTIMES)
4481 UTIME_TO_TIMEVAL;
4482 return utimes(path, time);
4483#elif defined(HAVE_UTIME_H)
4484 UTIME_TO_UTIMBUF;
4485 return utime(path, time);
4486#else
4487 UTIME_TO_TIME_T;
4488 return utime(path, time);
4489#endif
4490}
4491
4492#endif
4493
Larry Hastings76ad59b2012-05-03 00:30:07 -07004494static int
4495split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4496{
4497 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004498 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004499 divmod = PyNumber_Divmod(py_long, billion);
4500 if (!divmod)
4501 goto exit;
4502 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4503 if ((*s == -1) && PyErr_Occurred())
4504 goto exit;
4505 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004506 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004507 goto exit;
4508
4509 result = 1;
4510exit:
4511 Py_XDECREF(divmod);
4512 return result;
4513}
4514
Larry Hastings2f936352014-08-05 14:04:04 +10004515
4516/*[clinic input]
4517os.utime
4518
4519 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4520 times: object = NULL
4521 *
4522 ns: object = NULL
4523 dir_fd: dir_fd(requires='futimensat') = None
4524 follow_symlinks: bool=True
4525
Martin Panter0ff89092015-09-09 01:56:53 +00004526# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004527
4528Set the access and modified time of path.
4529
4530path may always be specified as a string.
4531On some platforms, path may also be specified as an open file descriptor.
4532 If this functionality is unavailable, using it raises an exception.
4533
4534If times is not None, it must be a tuple (atime, mtime);
4535 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004536If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004537 atime_ns and mtime_ns should be expressed as integer nanoseconds
4538 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004539If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004540Specifying tuples for both times and ns is an error.
4541
4542If dir_fd is not None, it should be a file descriptor open to a directory,
4543 and path should be relative; path will then be relative to that directory.
4544If follow_symlinks is False, and the last element of the path is a symbolic
4545 link, utime will modify the symbolic link itself instead of the file the
4546 link points to.
4547It is an error to use dir_fd or follow_symlinks when specifying path
4548 as an open file descriptor.
4549dir_fd and follow_symlinks may not be available on your platform.
4550 If they are unavailable, using them will raise a NotImplementedError.
4551
4552[clinic start generated code]*/
4553
Larry Hastings2f936352014-08-05 14:04:04 +10004554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004555os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4556 int dir_fd, int follow_symlinks)
4557/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004558{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559#ifdef MS_WINDOWS
4560 HANDLE hFile;
4561 FILETIME atime, mtime;
4562#else
4563 int result;
4564#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004565
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004567 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004568
Christian Heimesb3c87242013-08-01 00:08:16 +02004569 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004570
Larry Hastings9cf065c2012-06-22 16:30:09 -07004571 if (times && (times != Py_None) && ns) {
4572 PyErr_SetString(PyExc_ValueError,
4573 "utime: you may specify either 'times'"
4574 " or 'ns' but not both");
4575 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004576 }
4577
4578 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004579 time_t a_sec, m_sec;
4580 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004581 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582 PyErr_SetString(PyExc_TypeError,
4583 "utime: 'times' must be either"
4584 " a tuple of two ints or None");
4585 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004586 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004588 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004589 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004590 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004591 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004593 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004594 utime.atime_s = a_sec;
4595 utime.atime_ns = a_nsec;
4596 utime.mtime_s = m_sec;
4597 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004598 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004599 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004600 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601 PyErr_SetString(PyExc_TypeError,
4602 "utime: 'ns' must be a tuple of two ints");
4603 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004604 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004606 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004608 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004609 &utime.mtime_s, &utime.mtime_ns)) {
4610 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004611 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612 }
4613 else {
4614 /* times and ns are both None/unspecified. use "now". */
4615 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004616 }
4617
Victor Stinner4552ced2015-09-21 22:37:15 +02004618#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004619 if (follow_symlinks_specified("utime", follow_symlinks))
4620 goto exit;
4621#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004622
Larry Hastings2f936352014-08-05 14:04:04 +10004623 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4624 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4625 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004627
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628#if !defined(HAVE_UTIMENSAT)
4629 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004630 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631 "utime: cannot use dir_fd and follow_symlinks "
4632 "together on this platform");
4633 goto exit;
4634 }
4635#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004636
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004637#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004638 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004639 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4640 NULL, OPEN_EXISTING,
4641 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 Py_END_ALLOW_THREADS
4643 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004644 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004646 }
4647
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004649 GetSystemTimeAsFileTime(&mtime);
4650 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004651 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004652 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004653 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4654 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004655 }
4656 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4657 /* Avoid putting the file name into the error here,
4658 as that may confuse the user into believing that
4659 something is wrong with the file, when it also
4660 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004661 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004662 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004663 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004664#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004666
Victor Stinner4552ced2015-09-21 22:37:15 +02004667#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004669 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004670 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004671#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004672
Victor Stinner528a9ab2015-09-03 21:30:26 +02004673#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004675 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004676 else
4677#endif
4678
Victor Stinner528a9ab2015-09-03 21:30:26 +02004679#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004680 if (path->fd != -1)
4681 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 else
4683#endif
4684
Larry Hastings2f936352014-08-05 14:04:04 +10004685 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686
4687 Py_END_ALLOW_THREADS
4688
4689 if (result < 0) {
4690 /* see previous comment about not putting filename in error here */
4691 return_value = posix_error();
4692 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004693 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004694
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004695#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004696
4697 Py_INCREF(Py_None);
4698 return_value = Py_None;
4699
4700exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701#ifdef MS_WINDOWS
4702 if (hFile != INVALID_HANDLE_VALUE)
4703 CloseHandle(hFile);
4704#endif
4705 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004706}
4707
Guido van Rossum3b066191991-06-04 19:40:25 +00004708/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004709
Larry Hastings2f936352014-08-05 14:04:04 +10004710
4711/*[clinic input]
4712os._exit
4713
4714 status: int
4715
4716Exit to the system with specified status, without normal exit processing.
4717[clinic start generated code]*/
4718
Larry Hastings2f936352014-08-05 14:04:04 +10004719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004720os__exit_impl(PyObject *module, int status)
4721/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004722{
4723 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004724 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004725}
4726
Steve Dowercc16be82016-09-08 10:35:16 -07004727#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4728#define EXECV_CHAR wchar_t
4729#else
4730#define EXECV_CHAR char
4731#endif
4732
Martin v. Löwis114619e2002-10-07 06:44:21 +00004733#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4734static void
Steve Dowercc16be82016-09-08 10:35:16 -07004735free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004736{
Victor Stinner8c62be82010-05-06 00:08:46 +00004737 Py_ssize_t i;
4738 for (i = 0; i < count; i++)
4739 PyMem_Free(array[i]);
4740 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004741}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004742
Berker Peksag81816462016-09-15 20:19:47 +03004743static int
4744fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004745{
Victor Stinner8c62be82010-05-06 00:08:46 +00004746 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004747 PyObject *ub;
4748 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004749#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004750 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004751 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004752 *out = PyUnicode_AsWideCharString(ub, &size);
4753 if (*out)
4754 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004755#else
Berker Peksag81816462016-09-15 20:19:47 +03004756 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004757 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004758 size = PyBytes_GET_SIZE(ub);
4759 *out = PyMem_Malloc(size + 1);
4760 if (*out) {
4761 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4762 result = 1;
4763 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004764 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004765#endif
Berker Peksag81816462016-09-15 20:19:47 +03004766 Py_DECREF(ub);
4767 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004768}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004769#endif
4770
Ross Lagerwall7807c352011-03-17 20:20:30 +02004771#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004772static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004773parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4774{
Victor Stinner8c62be82010-05-06 00:08:46 +00004775 Py_ssize_t i, pos, envc;
4776 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004777 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004778 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004779
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 i = PyMapping_Size(env);
4781 if (i < 0)
4782 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004783 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004784 if (envlist == NULL) {
4785 PyErr_NoMemory();
4786 return NULL;
4787 }
4788 envc = 0;
4789 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004790 if (!keys)
4791 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004792 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004793 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004794 goto error;
4795 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4796 PyErr_Format(PyExc_TypeError,
4797 "env.keys() or env.values() is not a list");
4798 goto error;
4799 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004800
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 for (pos = 0; pos < i; pos++) {
4802 key = PyList_GetItem(keys, pos);
4803 val = PyList_GetItem(vals, pos);
4804 if (!key || !val)
4805 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004806
Berker Peksag81816462016-09-15 20:19:47 +03004807#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4808 if (!PyUnicode_FSDecoder(key, &key2))
4809 goto error;
4810 if (!PyUnicode_FSDecoder(val, &val2)) {
4811 Py_DECREF(key2);
4812 goto error;
4813 }
4814 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4815#else
4816 if (!PyUnicode_FSConverter(key, &key2))
4817 goto error;
4818 if (!PyUnicode_FSConverter(val, &val2)) {
4819 Py_DECREF(key2);
4820 goto error;
4821 }
4822 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4823 PyBytes_AS_STRING(val2));
4824#endif
4825 Py_DECREF(key2);
4826 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004827 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004829
4830 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4831 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 goto error;
4833 }
Berker Peksag81816462016-09-15 20:19:47 +03004834
Steve Dowercc16be82016-09-08 10:35:16 -07004835 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 }
4837 Py_DECREF(vals);
4838 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004839
Victor Stinner8c62be82010-05-06 00:08:46 +00004840 envlist[envc] = 0;
4841 *envc_ptr = envc;
4842 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004843
4844error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 Py_XDECREF(keys);
4846 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004847 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004849}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004850
Steve Dowercc16be82016-09-08 10:35:16 -07004851static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004852parse_arglist(PyObject* argv, Py_ssize_t *argc)
4853{
4854 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004855 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004856 if (argvlist == NULL) {
4857 PyErr_NoMemory();
4858 return NULL;
4859 }
4860 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004861 PyObject* item = PySequence_ITEM(argv, i);
4862 if (item == NULL)
4863 goto fail;
4864 if (!fsconvert_strdup(item, &argvlist[i])) {
4865 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004866 goto fail;
4867 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004868 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004869 }
4870 argvlist[*argc] = NULL;
4871 return argvlist;
4872fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004873 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004874 free_string_array(argvlist, *argc);
4875 return NULL;
4876}
Steve Dowercc16be82016-09-08 10:35:16 -07004877
Ross Lagerwall7807c352011-03-17 20:20:30 +02004878#endif
4879
Larry Hastings2f936352014-08-05 14:04:04 +10004880
Ross Lagerwall7807c352011-03-17 20:20:30 +02004881#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004882/*[clinic input]
4883os.execv
4884
Steve Dowercc16be82016-09-08 10:35:16 -07004885 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004886 Path of executable file.
4887 argv: object
4888 Tuple or list of strings.
4889 /
4890
4891Execute an executable path with arguments, replacing current process.
4892[clinic start generated code]*/
4893
Larry Hastings2f936352014-08-05 14:04:04 +10004894static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004895os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4896/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004897{
Steve Dowercc16be82016-09-08 10:35:16 -07004898 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004899 Py_ssize_t argc;
4900
4901 /* execv has two arguments: (path, argv), where
4902 argv is a list or tuple of strings. */
4903
Ross Lagerwall7807c352011-03-17 20:20:30 +02004904 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4905 PyErr_SetString(PyExc_TypeError,
4906 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004907 return NULL;
4908 }
4909 argc = PySequence_Size(argv);
4910 if (argc < 1) {
4911 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004912 return NULL;
4913 }
4914
4915 argvlist = parse_arglist(argv, &argc);
4916 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004917 return NULL;
4918 }
Steve Dowerbce26262016-11-19 19:17:26 -08004919 if (!argvlist[0][0]) {
4920 PyErr_SetString(PyExc_ValueError,
4921 "execv() arg 2 first element cannot be empty");
4922 free_string_array(argvlist, argc);
4923 return NULL;
4924 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004925
Steve Dowerbce26262016-11-19 19:17:26 -08004926 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004927#ifdef HAVE_WEXECV
4928 _wexecv(path->wide, argvlist);
4929#else
4930 execv(path->narrow, argvlist);
4931#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004932 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004933
4934 /* If we get here it's definitely an error */
4935
4936 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004937 return posix_error();
4938}
4939
Larry Hastings2f936352014-08-05 14:04:04 +10004940
4941/*[clinic input]
4942os.execve
4943
4944 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4945 Path of executable file.
4946 argv: object
4947 Tuple or list of strings.
4948 env: object
4949 Dictionary of strings mapping to strings.
4950
4951Execute an executable path with arguments, replacing current process.
4952[clinic start generated code]*/
4953
Larry Hastings2f936352014-08-05 14:04:04 +10004954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004955os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4956/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004957{
Steve Dowercc16be82016-09-08 10:35:16 -07004958 EXECV_CHAR **argvlist = NULL;
4959 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004960 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004961
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 /* execve has three arguments: (path, argv, env), where
4963 argv is a list or tuple of strings and env is a dictionary
4964 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004965
Ross Lagerwall7807c352011-03-17 20:20:30 +02004966 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968 "execve: argv must be a tuple or list");
4969 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004971 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08004972 if (argc < 1) {
4973 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
4974 return NULL;
4975 }
4976
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 if (!PyMapping_Check(env)) {
4978 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004979 "execve: environment must be a mapping object");
4980 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004982
Ross Lagerwall7807c352011-03-17 20:20:30 +02004983 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 }
Steve Dowerbce26262016-11-19 19:17:26 -08004987 if (!argvlist[0][0]) {
4988 PyErr_SetString(PyExc_ValueError,
4989 "execve: argv first element cannot be empty");
4990 goto fail;
4991 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004992
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 envlist = parse_envlist(env, &envc);
4994 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004995 goto fail;
4996
Steve Dowerbce26262016-11-19 19:17:26 -08004997 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004998#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10004999 if (path->fd > -1)
5000 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005001 else
5002#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005003#ifdef HAVE_WEXECV
5004 _wexecve(path->wide, argvlist, envlist);
5005#else
Larry Hastings2f936352014-08-05 14:04:04 +10005006 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005007#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005008 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005009
5010 /* If we get here it's definitely an error */
5011
Larry Hastings2f936352014-08-05 14:04:04 +10005012 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013
Steve Dowercc16be82016-09-08 10:35:16 -07005014 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005016 if (argvlist)
5017 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005018 return NULL;
5019}
Steve Dowercc16be82016-09-08 10:35:16 -07005020
Larry Hastings9cf065c2012-06-22 16:30:09 -07005021#endif /* HAVE_EXECV */
5022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005023
Steve Dowercc16be82016-09-08 10:35:16 -07005024#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005025/*[clinic input]
5026os.spawnv
5027
5028 mode: int
5029 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005030 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005031 Path of executable file.
5032 argv: object
5033 Tuple or list of strings.
5034 /
5035
5036Execute the program specified by path in a new process.
5037[clinic start generated code]*/
5038
Larry Hastings2f936352014-08-05 14:04:04 +10005039static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005040os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5041/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005042{
Steve Dowercc16be82016-09-08 10:35:16 -07005043 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005044 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005045 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005046 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005047 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005048
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 /* spawnv has three arguments: (mode, path, argv), where
5050 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005051
Victor Stinner8c62be82010-05-06 00:08:46 +00005052 if (PyList_Check(argv)) {
5053 argc = PyList_Size(argv);
5054 getitem = PyList_GetItem;
5055 }
5056 else if (PyTuple_Check(argv)) {
5057 argc = PyTuple_Size(argv);
5058 getitem = PyTuple_GetItem;
5059 }
5060 else {
5061 PyErr_SetString(PyExc_TypeError,
5062 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 return NULL;
5064 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005065 if (argc == 0) {
5066 PyErr_SetString(PyExc_ValueError,
5067 "spawnv() arg 2 cannot be empty");
5068 return NULL;
5069 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005070
Steve Dowercc16be82016-09-08 10:35:16 -07005071 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005073 return PyErr_NoMemory();
5074 }
5075 for (i = 0; i < argc; i++) {
5076 if (!fsconvert_strdup((*getitem)(argv, i),
5077 &argvlist[i])) {
5078 free_string_array(argvlist, i);
5079 PyErr_SetString(
5080 PyExc_TypeError,
5081 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 return NULL;
5083 }
Steve Dower93ff8722016-11-19 19:03:54 -08005084 if (i == 0 && !argvlist[0][0]) {
5085 free_string_array(argvlist, i);
5086 PyErr_SetString(
5087 PyExc_ValueError,
5088 "spawnv() arg 2 first element cannot be empty");
5089 return NULL;
5090 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005091 }
5092 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005093
Victor Stinner8c62be82010-05-06 00:08:46 +00005094 if (mode == _OLD_P_OVERLAY)
5095 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005096
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005098 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005099#ifdef HAVE_WSPAWNV
5100 spawnval = _wspawnv(mode, path->wide, argvlist);
5101#else
5102 spawnval = _spawnv(mode, path->narrow, argvlist);
5103#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005104 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005106
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005108
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 if (spawnval == -1)
5110 return posix_error();
5111 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005112 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005113}
5114
5115
Larry Hastings2f936352014-08-05 14:04:04 +10005116/*[clinic input]
5117os.spawnve
5118
5119 mode: int
5120 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005121 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005122 Path of executable file.
5123 argv: object
5124 Tuple or list of strings.
5125 env: object
5126 Dictionary of strings mapping to strings.
5127 /
5128
5129Execute the program specified by path in a new process.
5130[clinic start generated code]*/
5131
Larry Hastings2f936352014-08-05 14:04:04 +10005132static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005133os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005134 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005135/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005136{
Steve Dowercc16be82016-09-08 10:35:16 -07005137 EXECV_CHAR **argvlist;
5138 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005140 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005141 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5143 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005144
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 /* spawnve has four arguments: (mode, path, argv, env), where
5146 argv is a list or tuple of strings and env is a dictionary
5147 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005148
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 if (PyList_Check(argv)) {
5150 argc = PyList_Size(argv);
5151 getitem = PyList_GetItem;
5152 }
5153 else if (PyTuple_Check(argv)) {
5154 argc = PyTuple_Size(argv);
5155 getitem = PyTuple_GetItem;
5156 }
5157 else {
5158 PyErr_SetString(PyExc_TypeError,
5159 "spawnve() arg 2 must be a tuple or list");
5160 goto fail_0;
5161 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005162 if (argc == 0) {
5163 PyErr_SetString(PyExc_ValueError,
5164 "spawnve() arg 2 cannot be empty");
5165 goto fail_0;
5166 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005167 if (!PyMapping_Check(env)) {
5168 PyErr_SetString(PyExc_TypeError,
5169 "spawnve() arg 3 must be a mapping object");
5170 goto fail_0;
5171 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005172
Steve Dowercc16be82016-09-08 10:35:16 -07005173 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 if (argvlist == NULL) {
5175 PyErr_NoMemory();
5176 goto fail_0;
5177 }
5178 for (i = 0; i < argc; i++) {
5179 if (!fsconvert_strdup((*getitem)(argv, i),
5180 &argvlist[i]))
5181 {
5182 lastarg = i;
5183 goto fail_1;
5184 }
Steve Dowerbce26262016-11-19 19:17:26 -08005185 if (i == 0 && !argvlist[0][0]) {
5186 lastarg = i;
5187 PyErr_SetString(
5188 PyExc_ValueError,
5189 "spawnv() arg 2 first element cannot be empty");
5190 goto fail_1;
5191 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 }
5193 lastarg = argc;
5194 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 envlist = parse_envlist(env, &envc);
5197 if (envlist == NULL)
5198 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 if (mode == _OLD_P_OVERLAY)
5201 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005204 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005205#ifdef HAVE_WSPAWNV
5206 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5207#else
5208 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5209#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005210 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005212
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 if (spawnval == -1)
5214 (void) posix_error();
5215 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005216 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005217
Victor Stinner8c62be82010-05-06 00:08:46 +00005218 while (--envc >= 0)
5219 PyMem_DEL(envlist[envc]);
5220 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005221 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005223 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005225}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005226
Guido van Rossuma1065681999-01-25 23:20:23 +00005227#endif /* HAVE_SPAWNV */
5228
5229
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005230#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005231/*[clinic input]
5232os.fork1
5233
5234Fork a child process with a single multiplexed (i.e., not bound) thread.
5235
5236Return 0 to child process and PID of child to parent process.
5237[clinic start generated code]*/
5238
Larry Hastings2f936352014-08-05 14:04:04 +10005239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005240os_fork1_impl(PyObject *module)
5241/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005242{
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 pid_t pid;
5244 int result = 0;
5245 _PyImport_AcquireLock();
5246 pid = fork1();
5247 if (pid == 0) {
5248 /* child: this clobbers and resets the import lock. */
5249 PyOS_AfterFork();
5250 } else {
5251 /* parent: release the import lock. */
5252 result = _PyImport_ReleaseLock();
5253 }
5254 if (pid == -1)
5255 return posix_error();
5256 if (result < 0) {
5257 /* Don't clobber the OSError if the fork failed. */
5258 PyErr_SetString(PyExc_RuntimeError,
5259 "not holding the import lock");
5260 return NULL;
5261 }
5262 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005263}
Larry Hastings2f936352014-08-05 14:04:04 +10005264#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005265
5266
Guido van Rossumad0ee831995-03-01 10:34:45 +00005267#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005268/*[clinic input]
5269os.fork
5270
5271Fork a child process.
5272
5273Return 0 to child process and PID of child to parent process.
5274[clinic start generated code]*/
5275
Larry Hastings2f936352014-08-05 14:04:04 +10005276static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005277os_fork_impl(PyObject *module)
5278/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005279{
Victor Stinner8c62be82010-05-06 00:08:46 +00005280 pid_t pid;
5281 int result = 0;
5282 _PyImport_AcquireLock();
5283 pid = fork();
5284 if (pid == 0) {
5285 /* child: this clobbers and resets the import lock. */
5286 PyOS_AfterFork();
5287 } else {
5288 /* parent: release the import lock. */
5289 result = _PyImport_ReleaseLock();
5290 }
5291 if (pid == -1)
5292 return posix_error();
5293 if (result < 0) {
5294 /* Don't clobber the OSError if the fork failed. */
5295 PyErr_SetString(PyExc_RuntimeError,
5296 "not holding the import lock");
5297 return NULL;
5298 }
5299 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005300}
Larry Hastings2f936352014-08-05 14:04:04 +10005301#endif /* HAVE_FORK */
5302
Guido van Rossum85e3b011991-06-03 12:42:10 +00005303
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005304#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005305#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005306/*[clinic input]
5307os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005308
Larry Hastings2f936352014-08-05 14:04:04 +10005309 policy: int
5310
5311Get the maximum scheduling priority for policy.
5312[clinic start generated code]*/
5313
Larry Hastings2f936352014-08-05 14:04:04 +10005314static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005315os_sched_get_priority_max_impl(PyObject *module, int policy)
5316/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005317{
5318 int max;
5319
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005320 max = sched_get_priority_max(policy);
5321 if (max < 0)
5322 return posix_error();
5323 return PyLong_FromLong(max);
5324}
5325
Larry Hastings2f936352014-08-05 14:04:04 +10005326
5327/*[clinic input]
5328os.sched_get_priority_min
5329
5330 policy: int
5331
5332Get the minimum scheduling priority for policy.
5333[clinic start generated code]*/
5334
Larry Hastings2f936352014-08-05 14:04:04 +10005335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005336os_sched_get_priority_min_impl(PyObject *module, int policy)
5337/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005338{
5339 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005340 if (min < 0)
5341 return posix_error();
5342 return PyLong_FromLong(min);
5343}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005344#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5345
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005346
Larry Hastings2f936352014-08-05 14:04:04 +10005347#ifdef HAVE_SCHED_SETSCHEDULER
5348/*[clinic input]
5349os.sched_getscheduler
5350 pid: pid_t
5351 /
5352
5353Get the scheduling policy for the process identifiedy by pid.
5354
5355Passing 0 for pid returns the scheduling policy for the calling process.
5356[clinic start generated code]*/
5357
Larry Hastings2f936352014-08-05 14:04:04 +10005358static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005359os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5360/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005361{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005362 int policy;
5363
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005364 policy = sched_getscheduler(pid);
5365 if (policy < 0)
5366 return posix_error();
5367 return PyLong_FromLong(policy);
5368}
Larry Hastings2f936352014-08-05 14:04:04 +10005369#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005370
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005371
5372#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005373/*[clinic input]
5374class os.sched_param "PyObject *" "&SchedParamType"
5375
5376@classmethod
5377os.sched_param.__new__
5378
5379 sched_priority: object
5380 A scheduling parameter.
5381
5382Current has only one field: sched_priority");
5383[clinic start generated code]*/
5384
Larry Hastings2f936352014-08-05 14:04:04 +10005385static PyObject *
5386os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005387/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005388{
5389 PyObject *res;
5390
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005391 res = PyStructSequence_New(type);
5392 if (!res)
5393 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005394 Py_INCREF(sched_priority);
5395 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005396 return res;
5397}
5398
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005399
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005400PyDoc_VAR(os_sched_param__doc__);
5401
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005402static PyStructSequence_Field sched_param_fields[] = {
5403 {"sched_priority", "the scheduling priority"},
5404 {0}
5405};
5406
5407static PyStructSequence_Desc sched_param_desc = {
5408 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005409 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005410 sched_param_fields,
5411 1
5412};
5413
5414static int
5415convert_sched_param(PyObject *param, struct sched_param *res)
5416{
5417 long priority;
5418
5419 if (Py_TYPE(param) != &SchedParamType) {
5420 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5421 return 0;
5422 }
5423 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5424 if (priority == -1 && PyErr_Occurred())
5425 return 0;
5426 if (priority > INT_MAX || priority < INT_MIN) {
5427 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5428 return 0;
5429 }
5430 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5431 return 1;
5432}
Larry Hastings2f936352014-08-05 14:04:04 +10005433#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005434
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005435
5436#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005437/*[clinic input]
5438os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005439
Larry Hastings2f936352014-08-05 14:04:04 +10005440 pid: pid_t
5441 policy: int
5442 param: sched_param
5443 /
5444
5445Set the scheduling policy for the process identified by pid.
5446
5447If pid is 0, the calling process is changed.
5448param is an instance of sched_param.
5449[clinic start generated code]*/
5450
Larry Hastings2f936352014-08-05 14:04:04 +10005451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005452os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005453 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005454/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005455{
Jesus Cea9c822272011-09-10 01:40:52 +02005456 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005457 ** sched_setscheduler() returns 0 in Linux, but the previous
5458 ** scheduling policy under Solaris/Illumos, and others.
5459 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005460 */
Larry Hastings2f936352014-08-05 14:04:04 +10005461 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005462 return posix_error();
5463 Py_RETURN_NONE;
5464}
Larry Hastings2f936352014-08-05 14:04:04 +10005465#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005466
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005467
5468#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005469/*[clinic input]
5470os.sched_getparam
5471 pid: pid_t
5472 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005473
Larry Hastings2f936352014-08-05 14:04:04 +10005474Returns scheduling parameters for the process identified by pid.
5475
5476If pid is 0, returns parameters for the calling process.
5477Return value is an instance of sched_param.
5478[clinic start generated code]*/
5479
Larry Hastings2f936352014-08-05 14:04:04 +10005480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005481os_sched_getparam_impl(PyObject *module, pid_t pid)
5482/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005483{
5484 struct sched_param param;
5485 PyObject *result;
5486 PyObject *priority;
5487
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005488 if (sched_getparam(pid, &param))
5489 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005490 result = PyStructSequence_New(&SchedParamType);
5491 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492 return NULL;
5493 priority = PyLong_FromLong(param.sched_priority);
5494 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005495 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496 return NULL;
5497 }
Larry Hastings2f936352014-08-05 14:04:04 +10005498 PyStructSequence_SET_ITEM(result, 0, priority);
5499 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005500}
5501
Larry Hastings2f936352014-08-05 14:04:04 +10005502
5503/*[clinic input]
5504os.sched_setparam
5505 pid: pid_t
5506 param: sched_param
5507 /
5508
5509Set scheduling parameters for the process identified by pid.
5510
5511If pid is 0, sets parameters for the calling process.
5512param should be an instance of sched_param.
5513[clinic start generated code]*/
5514
Larry Hastings2f936352014-08-05 14:04:04 +10005515static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005516os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005517 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005518/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005519{
5520 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005521 return posix_error();
5522 Py_RETURN_NONE;
5523}
Larry Hastings2f936352014-08-05 14:04:04 +10005524#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005525
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005526
5527#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005528/*[clinic input]
5529os.sched_rr_get_interval -> double
5530 pid: pid_t
5531 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005532
Larry Hastings2f936352014-08-05 14:04:04 +10005533Return the round-robin quantum for the process identified by pid, in seconds.
5534
5535Value returned is a float.
5536[clinic start generated code]*/
5537
Larry Hastings2f936352014-08-05 14:04:04 +10005538static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005539os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5540/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005541{
5542 struct timespec interval;
5543 if (sched_rr_get_interval(pid, &interval)) {
5544 posix_error();
5545 return -1.0;
5546 }
5547 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5548}
5549#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005550
Larry Hastings2f936352014-08-05 14:04:04 +10005551
5552/*[clinic input]
5553os.sched_yield
5554
5555Voluntarily relinquish the CPU.
5556[clinic start generated code]*/
5557
Larry Hastings2f936352014-08-05 14:04:04 +10005558static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005559os_sched_yield_impl(PyObject *module)
5560/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005561{
5562 if (sched_yield())
5563 return posix_error();
5564 Py_RETURN_NONE;
5565}
5566
Benjamin Peterson2740af82011-08-02 17:41:34 -05005567#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005568/* The minimum number of CPUs allocated in a cpu_set_t */
5569static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005570
Larry Hastings2f936352014-08-05 14:04:04 +10005571/*[clinic input]
5572os.sched_setaffinity
5573 pid: pid_t
5574 mask : object
5575 /
5576
5577Set the CPU affinity of the process identified by pid to mask.
5578
5579mask should be an iterable of integers identifying CPUs.
5580[clinic start generated code]*/
5581
Larry Hastings2f936352014-08-05 14:04:04 +10005582static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005583os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5584/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005585{
Antoine Pitrou84869872012-08-04 16:16:35 +02005586 int ncpus;
5587 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005588 cpu_set_t *cpu_set = NULL;
5589 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005590
Larry Hastings2f936352014-08-05 14:04:04 +10005591 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005592 if (iterator == NULL)
5593 return NULL;
5594
5595 ncpus = NCPUS_START;
5596 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005597 cpu_set = CPU_ALLOC(ncpus);
5598 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005599 PyErr_NoMemory();
5600 goto error;
5601 }
Larry Hastings2f936352014-08-05 14:04:04 +10005602 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005603
5604 while ((item = PyIter_Next(iterator))) {
5605 long cpu;
5606 if (!PyLong_Check(item)) {
5607 PyErr_Format(PyExc_TypeError,
5608 "expected an iterator of ints, "
5609 "but iterator yielded %R",
5610 Py_TYPE(item));
5611 Py_DECREF(item);
5612 goto error;
5613 }
5614 cpu = PyLong_AsLong(item);
5615 Py_DECREF(item);
5616 if (cpu < 0) {
5617 if (!PyErr_Occurred())
5618 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5619 goto error;
5620 }
5621 if (cpu > INT_MAX - 1) {
5622 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5623 goto error;
5624 }
5625 if (cpu >= ncpus) {
5626 /* Grow CPU mask to fit the CPU number */
5627 int newncpus = ncpus;
5628 cpu_set_t *newmask;
5629 size_t newsetsize;
5630 while (newncpus <= cpu) {
5631 if (newncpus > INT_MAX / 2)
5632 newncpus = cpu + 1;
5633 else
5634 newncpus = newncpus * 2;
5635 }
5636 newmask = CPU_ALLOC(newncpus);
5637 if (newmask == NULL) {
5638 PyErr_NoMemory();
5639 goto error;
5640 }
5641 newsetsize = CPU_ALLOC_SIZE(newncpus);
5642 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005643 memcpy(newmask, cpu_set, setsize);
5644 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005645 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005646 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005647 ncpus = newncpus;
5648 }
Larry Hastings2f936352014-08-05 14:04:04 +10005649 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005650 }
5651 Py_CLEAR(iterator);
5652
Larry Hastings2f936352014-08-05 14:04:04 +10005653 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005654 posix_error();
5655 goto error;
5656 }
Larry Hastings2f936352014-08-05 14:04:04 +10005657 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005658 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005659
5660error:
Larry Hastings2f936352014-08-05 14:04:04 +10005661 if (cpu_set)
5662 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005663 Py_XDECREF(iterator);
5664 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005665}
5666
Larry Hastings2f936352014-08-05 14:04:04 +10005667
5668/*[clinic input]
5669os.sched_getaffinity
5670 pid: pid_t
5671 /
5672
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005673Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005674
5675The affinity is returned as a set of CPU identifiers.
5676[clinic start generated code]*/
5677
Larry Hastings2f936352014-08-05 14:04:04 +10005678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005679os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005680/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005681{
Antoine Pitrou84869872012-08-04 16:16:35 +02005682 int cpu, ncpus, count;
5683 size_t setsize;
5684 cpu_set_t *mask = NULL;
5685 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005686
Antoine Pitrou84869872012-08-04 16:16:35 +02005687 ncpus = NCPUS_START;
5688 while (1) {
5689 setsize = CPU_ALLOC_SIZE(ncpus);
5690 mask = CPU_ALLOC(ncpus);
5691 if (mask == NULL)
5692 return PyErr_NoMemory();
5693 if (sched_getaffinity(pid, setsize, mask) == 0)
5694 break;
5695 CPU_FREE(mask);
5696 if (errno != EINVAL)
5697 return posix_error();
5698 if (ncpus > INT_MAX / 2) {
5699 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5700 "a large enough CPU set");
5701 return NULL;
5702 }
5703 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005704 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005705
5706 res = PySet_New(NULL);
5707 if (res == NULL)
5708 goto error;
5709 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5710 if (CPU_ISSET_S(cpu, setsize, mask)) {
5711 PyObject *cpu_num = PyLong_FromLong(cpu);
5712 --count;
5713 if (cpu_num == NULL)
5714 goto error;
5715 if (PySet_Add(res, cpu_num)) {
5716 Py_DECREF(cpu_num);
5717 goto error;
5718 }
5719 Py_DECREF(cpu_num);
5720 }
5721 }
5722 CPU_FREE(mask);
5723 return res;
5724
5725error:
5726 if (mask)
5727 CPU_FREE(mask);
5728 Py_XDECREF(res);
5729 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005730}
5731
Benjamin Peterson2740af82011-08-02 17:41:34 -05005732#endif /* HAVE_SCHED_SETAFFINITY */
5733
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005734#endif /* HAVE_SCHED_H */
5735
Larry Hastings2f936352014-08-05 14:04:04 +10005736
Neal Norwitzb59798b2003-03-21 01:43:31 +00005737/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005738/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5739#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005740#define DEV_PTY_FILE "/dev/ptc"
5741#define HAVE_DEV_PTMX
5742#else
5743#define DEV_PTY_FILE "/dev/ptmx"
5744#endif
5745
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005746#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005747#ifdef HAVE_PTY_H
5748#include <pty.h>
5749#else
5750#ifdef HAVE_LIBUTIL_H
5751#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005752#else
5753#ifdef HAVE_UTIL_H
5754#include <util.h>
5755#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005756#endif /* HAVE_LIBUTIL_H */
5757#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005758#ifdef HAVE_STROPTS_H
5759#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005760#endif
5761#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005762
Larry Hastings2f936352014-08-05 14:04:04 +10005763
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005764#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005765/*[clinic input]
5766os.openpty
5767
5768Open a pseudo-terminal.
5769
5770Return a tuple of (master_fd, slave_fd) containing open file descriptors
5771for both the master and slave ends.
5772[clinic start generated code]*/
5773
Larry Hastings2f936352014-08-05 14:04:04 +10005774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005775os_openpty_impl(PyObject *module)
5776/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005777{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005778 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005779#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005780 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005781#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005782#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005783 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005784#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005785 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005786#endif
5787#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005788
Thomas Wouters70c21a12000-07-14 14:28:33 +00005789#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005790 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005791 goto posix_error;
5792
5793 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5794 goto error;
5795 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5796 goto error;
5797
Neal Norwitzb59798b2003-03-21 01:43:31 +00005798#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5800 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005801 goto posix_error;
5802 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5803 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005804
Victor Stinnerdaf45552013-08-28 00:53:59 +02005805 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005806 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005807 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005808
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005809#else
Victor Stinner000de532013-11-25 23:19:58 +01005810 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005811 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005812 goto posix_error;
5813
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005815
Victor Stinner8c62be82010-05-06 00:08:46 +00005816 /* change permission of slave */
5817 if (grantpt(master_fd) < 0) {
5818 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005819 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005820 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005821
Victor Stinner8c62be82010-05-06 00:08:46 +00005822 /* unlock slave */
5823 if (unlockpt(master_fd) < 0) {
5824 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005825 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005826 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005827
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005829
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 slave_name = ptsname(master_fd); /* get name of slave */
5831 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005832 goto posix_error;
5833
5834 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005835 if (slave_fd == -1)
5836 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005837
5838 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5839 goto posix_error;
5840
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005841#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005842 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5843 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005844#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005845 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005846#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005847#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005848#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005849
Victor Stinner8c62be82010-05-06 00:08:46 +00005850 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005851
Victor Stinnerdaf45552013-08-28 00:53:59 +02005852posix_error:
5853 posix_error();
5854error:
5855 if (master_fd != -1)
5856 close(master_fd);
5857 if (slave_fd != -1)
5858 close(slave_fd);
5859 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005860}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005861#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005862
Larry Hastings2f936352014-08-05 14:04:04 +10005863
Fred Drake8cef4cf2000-06-28 16:40:38 +00005864#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005865/*[clinic input]
5866os.forkpty
5867
5868Fork a new process with a new pseudo-terminal as controlling tty.
5869
5870Returns a tuple of (pid, master_fd).
5871Like fork(), return pid of 0 to the child process,
5872and pid of child to the parent process.
5873To both, return fd of newly opened pseudo-terminal.
5874[clinic start generated code]*/
5875
Larry Hastings2f936352014-08-05 14:04:04 +10005876static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005877os_forkpty_impl(PyObject *module)
5878/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005879{
Victor Stinner8c62be82010-05-06 00:08:46 +00005880 int master_fd = -1, result = 0;
5881 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005882
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 _PyImport_AcquireLock();
5884 pid = forkpty(&master_fd, NULL, NULL, NULL);
5885 if (pid == 0) {
5886 /* child: this clobbers and resets the import lock. */
5887 PyOS_AfterFork();
5888 } else {
5889 /* parent: release the import lock. */
5890 result = _PyImport_ReleaseLock();
5891 }
5892 if (pid == -1)
5893 return posix_error();
5894 if (result < 0) {
5895 /* Don't clobber the OSError if the fork failed. */
5896 PyErr_SetString(PyExc_RuntimeError,
5897 "not holding the import lock");
5898 return NULL;
5899 }
5900 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005901}
Larry Hastings2f936352014-08-05 14:04:04 +10005902#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005903
Ross Lagerwall7807c352011-03-17 20:20:30 +02005904
Guido van Rossumad0ee831995-03-01 10:34:45 +00005905#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005906/*[clinic input]
5907os.getegid
5908
5909Return the current process's effective group id.
5910[clinic start generated code]*/
5911
Larry Hastings2f936352014-08-05 14:04:04 +10005912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005913os_getegid_impl(PyObject *module)
5914/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005915{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005916 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005917}
Larry Hastings2f936352014-08-05 14:04:04 +10005918#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005919
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005920
Guido van Rossumad0ee831995-03-01 10:34:45 +00005921#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005922/*[clinic input]
5923os.geteuid
5924
5925Return the current process's effective user id.
5926[clinic start generated code]*/
5927
Larry Hastings2f936352014-08-05 14:04:04 +10005928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005929os_geteuid_impl(PyObject *module)
5930/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005931{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005932 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005933}
Larry Hastings2f936352014-08-05 14:04:04 +10005934#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005936
Guido van Rossumad0ee831995-03-01 10:34:45 +00005937#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005938/*[clinic input]
5939os.getgid
5940
5941Return the current process's group id.
5942[clinic start generated code]*/
5943
Larry Hastings2f936352014-08-05 14:04:04 +10005944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005945os_getgid_impl(PyObject *module)
5946/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005947{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005948 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005949}
Larry Hastings2f936352014-08-05 14:04:04 +10005950#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005952
Berker Peksag39404992016-09-15 20:45:16 +03005953#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10005954/*[clinic input]
5955os.getpid
5956
5957Return the current process id.
5958[clinic start generated code]*/
5959
Larry Hastings2f936352014-08-05 14:04:04 +10005960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005961os_getpid_impl(PyObject *module)
5962/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005963{
Victor Stinner8c62be82010-05-06 00:08:46 +00005964 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005965}
Berker Peksag39404992016-09-15 20:45:16 +03005966#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005967
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005968#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005969
5970/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005971PyDoc_STRVAR(posix_getgrouplist__doc__,
5972"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5973Returns a list of groups to which a user belongs.\n\n\
5974 user: username to lookup\n\
5975 group: base group id of the user");
5976
5977static PyObject *
5978posix_getgrouplist(PyObject *self, PyObject *args)
5979{
5980#ifdef NGROUPS_MAX
5981#define MAX_GROUPS NGROUPS_MAX
5982#else
5983 /* defined to be 16 on Solaris7, so this should be a small number */
5984#define MAX_GROUPS 64
5985#endif
5986
5987 const char *user;
5988 int i, ngroups;
5989 PyObject *list;
5990#ifdef __APPLE__
5991 int *groups, basegid;
5992#else
5993 gid_t *groups, basegid;
5994#endif
5995 ngroups = MAX_GROUPS;
5996
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005997#ifdef __APPLE__
5998 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005999 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006000#else
6001 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6002 _Py_Gid_Converter, &basegid))
6003 return NULL;
6004#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006005
6006#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006007 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006008#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006009 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006010#endif
6011 if (groups == NULL)
6012 return PyErr_NoMemory();
6013
6014 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6015 PyMem_Del(groups);
6016 return posix_error();
6017 }
6018
6019 list = PyList_New(ngroups);
6020 if (list == NULL) {
6021 PyMem_Del(groups);
6022 return NULL;
6023 }
6024
6025 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006026#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006027 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006028#else
6029 PyObject *o = _PyLong_FromGid(groups[i]);
6030#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006031 if (o == NULL) {
6032 Py_DECREF(list);
6033 PyMem_Del(groups);
6034 return NULL;
6035 }
6036 PyList_SET_ITEM(list, i, o);
6037 }
6038
6039 PyMem_Del(groups);
6040
6041 return list;
6042}
Larry Hastings2f936352014-08-05 14:04:04 +10006043#endif /* HAVE_GETGROUPLIST */
6044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006045
Fred Drakec9680921999-12-13 16:37:25 +00006046#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006047/*[clinic input]
6048os.getgroups
6049
6050Return list of supplemental group IDs for the process.
6051[clinic start generated code]*/
6052
Larry Hastings2f936352014-08-05 14:04:04 +10006053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006054os_getgroups_impl(PyObject *module)
6055/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006056{
6057 PyObject *result = NULL;
6058
Fred Drakec9680921999-12-13 16:37:25 +00006059#ifdef NGROUPS_MAX
6060#define MAX_GROUPS NGROUPS_MAX
6061#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006062 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006063#define MAX_GROUPS 64
6064#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006066
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006067 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006068 * This is a helper variable to store the intermediate result when
6069 * that happens.
6070 *
6071 * To keep the code readable the OSX behaviour is unconditional,
6072 * according to the POSIX spec this should be safe on all unix-y
6073 * systems.
6074 */
6075 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006076 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006077
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006078#ifdef __APPLE__
6079 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6080 * there are more groups than can fit in grouplist. Therefore, on OS X
6081 * always first call getgroups with length 0 to get the actual number
6082 * of groups.
6083 */
6084 n = getgroups(0, NULL);
6085 if (n < 0) {
6086 return posix_error();
6087 } else if (n <= MAX_GROUPS) {
6088 /* groups will fit in existing array */
6089 alt_grouplist = grouplist;
6090 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006091 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006092 if (alt_grouplist == NULL) {
6093 errno = EINVAL;
6094 return posix_error();
6095 }
6096 }
6097
6098 n = getgroups(n, alt_grouplist);
6099 if (n == -1) {
6100 if (alt_grouplist != grouplist) {
6101 PyMem_Free(alt_grouplist);
6102 }
6103 return posix_error();
6104 }
6105#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006107 if (n < 0) {
6108 if (errno == EINVAL) {
6109 n = getgroups(0, NULL);
6110 if (n == -1) {
6111 return posix_error();
6112 }
6113 if (n == 0) {
6114 /* Avoid malloc(0) */
6115 alt_grouplist = grouplist;
6116 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006117 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006118 if (alt_grouplist == NULL) {
6119 errno = EINVAL;
6120 return posix_error();
6121 }
6122 n = getgroups(n, alt_grouplist);
6123 if (n == -1) {
6124 PyMem_Free(alt_grouplist);
6125 return posix_error();
6126 }
6127 }
6128 } else {
6129 return posix_error();
6130 }
6131 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006132#endif
6133
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006134 result = PyList_New(n);
6135 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006136 int i;
6137 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006138 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006140 Py_DECREF(result);
6141 result = NULL;
6142 break;
Fred Drakec9680921999-12-13 16:37:25 +00006143 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006144 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006145 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006146 }
6147
6148 if (alt_grouplist != grouplist) {
6149 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006151
Fred Drakec9680921999-12-13 16:37:25 +00006152 return result;
6153}
Larry Hastings2f936352014-08-05 14:04:04 +10006154#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006155
Antoine Pitroub7572f02009-12-02 20:46:48 +00006156#ifdef HAVE_INITGROUPS
6157PyDoc_STRVAR(posix_initgroups__doc__,
6158"initgroups(username, gid) -> None\n\n\
6159Call the system initgroups() to initialize the group access list with all of\n\
6160the groups of which the specified username is a member, plus the specified\n\
6161group id.");
6162
Larry Hastings2f936352014-08-05 14:04:04 +10006163/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006164static PyObject *
6165posix_initgroups(PyObject *self, PyObject *args)
6166{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006167 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006168 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006169 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006170#ifdef __APPLE__
6171 int gid;
6172#else
6173 gid_t gid;
6174#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006175
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006176#ifdef __APPLE__
6177 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6178 PyUnicode_FSConverter, &oname,
6179 &gid))
6180#else
6181 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6182 PyUnicode_FSConverter, &oname,
6183 _Py_Gid_Converter, &gid))
6184#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006185 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006186 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006187
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006188 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006189 Py_DECREF(oname);
6190 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006191 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006192
Victor Stinner8c62be82010-05-06 00:08:46 +00006193 Py_INCREF(Py_None);
6194 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006195}
Larry Hastings2f936352014-08-05 14:04:04 +10006196#endif /* HAVE_INITGROUPS */
6197
Antoine Pitroub7572f02009-12-02 20:46:48 +00006198
Martin v. Löwis606edc12002-06-13 21:09:11 +00006199#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006200/*[clinic input]
6201os.getpgid
6202
6203 pid: pid_t
6204
6205Call the system call getpgid(), and return the result.
6206[clinic start generated code]*/
6207
Larry Hastings2f936352014-08-05 14:04:04 +10006208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006209os_getpgid_impl(PyObject *module, pid_t pid)
6210/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006211{
6212 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006213 if (pgid < 0)
6214 return posix_error();
6215 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006216}
6217#endif /* HAVE_GETPGID */
6218
6219
Guido van Rossumb6775db1994-08-01 11:34:53 +00006220#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006221/*[clinic input]
6222os.getpgrp
6223
6224Return the current process group id.
6225[clinic start generated code]*/
6226
Larry Hastings2f936352014-08-05 14:04:04 +10006227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006228os_getpgrp_impl(PyObject *module)
6229/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006230{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006231#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006233#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006235#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006236}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006237#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006239
Guido van Rossumb6775db1994-08-01 11:34:53 +00006240#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006241/*[clinic input]
6242os.setpgrp
6243
6244Make the current process the leader of its process group.
6245[clinic start generated code]*/
6246
Larry Hastings2f936352014-08-05 14:04:04 +10006247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006248os_setpgrp_impl(PyObject *module)
6249/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006250{
Guido van Rossum64933891994-10-20 21:56:42 +00006251#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006253#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006255#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 return posix_error();
6257 Py_INCREF(Py_None);
6258 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006259}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006260#endif /* HAVE_SETPGRP */
6261
Guido van Rossumad0ee831995-03-01 10:34:45 +00006262#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006263
6264#ifdef MS_WINDOWS
6265#include <tlhelp32.h>
6266
6267static PyObject*
6268win32_getppid()
6269{
6270 HANDLE snapshot;
6271 pid_t mypid;
6272 PyObject* result = NULL;
6273 BOOL have_record;
6274 PROCESSENTRY32 pe;
6275
6276 mypid = getpid(); /* This function never fails */
6277
6278 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6279 if (snapshot == INVALID_HANDLE_VALUE)
6280 return PyErr_SetFromWindowsErr(GetLastError());
6281
6282 pe.dwSize = sizeof(pe);
6283 have_record = Process32First(snapshot, &pe);
6284 while (have_record) {
6285 if (mypid == (pid_t)pe.th32ProcessID) {
6286 /* We could cache the ulong value in a static variable. */
6287 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6288 break;
6289 }
6290
6291 have_record = Process32Next(snapshot, &pe);
6292 }
6293
6294 /* If our loop exits and our pid was not found (result will be NULL)
6295 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6296 * error anyway, so let's raise it. */
6297 if (!result)
6298 result = PyErr_SetFromWindowsErr(GetLastError());
6299
6300 CloseHandle(snapshot);
6301
6302 return result;
6303}
6304#endif /*MS_WINDOWS*/
6305
Larry Hastings2f936352014-08-05 14:04:04 +10006306
6307/*[clinic input]
6308os.getppid
6309
6310Return the parent's process id.
6311
6312If the parent process has already exited, Windows machines will still
6313return its id; others systems will return the id of the 'init' process (1).
6314[clinic start generated code]*/
6315
Larry Hastings2f936352014-08-05 14:04:04 +10006316static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006317os_getppid_impl(PyObject *module)
6318/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006319{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006320#ifdef MS_WINDOWS
6321 return win32_getppid();
6322#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006324#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006325}
6326#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006328
Fred Drake12c6e2d1999-12-14 21:25:03 +00006329#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006330/*[clinic input]
6331os.getlogin
6332
6333Return the actual login name.
6334[clinic start generated code]*/
6335
Larry Hastings2f936352014-08-05 14:04:04 +10006336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006337os_getlogin_impl(PyObject *module)
6338/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006339{
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006341#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006342 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006343 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006344
6345 if (GetUserNameW(user_name, &num_chars)) {
6346 /* num_chars is the number of unicode chars plus null terminator */
6347 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006348 }
6349 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006350 result = PyErr_SetFromWindowsErr(GetLastError());
6351#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 char *name;
6353 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006354
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 errno = 0;
6356 name = getlogin();
6357 if (name == NULL) {
6358 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006359 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006360 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006361 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 }
6363 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006364 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006366#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006367 return result;
6368}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006369#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006370
Larry Hastings2f936352014-08-05 14:04:04 +10006371
Guido van Rossumad0ee831995-03-01 10:34:45 +00006372#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006373/*[clinic input]
6374os.getuid
6375
6376Return the current process's user id.
6377[clinic start generated code]*/
6378
Larry Hastings2f936352014-08-05 14:04:04 +10006379static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006380os_getuid_impl(PyObject *module)
6381/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006382{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006383 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006384}
Larry Hastings2f936352014-08-05 14:04:04 +10006385#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006387
Brian Curtineb24d742010-04-12 17:16:38 +00006388#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006389#define HAVE_KILL
6390#endif /* MS_WINDOWS */
6391
6392#ifdef HAVE_KILL
6393/*[clinic input]
6394os.kill
6395
6396 pid: pid_t
6397 signal: Py_ssize_t
6398 /
6399
6400Kill a process with a signal.
6401[clinic start generated code]*/
6402
Larry Hastings2f936352014-08-05 14:04:04 +10006403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006404os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6405/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006406#ifndef MS_WINDOWS
6407{
6408 if (kill(pid, (int)signal) == -1)
6409 return posix_error();
6410 Py_RETURN_NONE;
6411}
6412#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006413{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006414 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006415 DWORD sig = (DWORD)signal;
6416 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006418
Victor Stinner8c62be82010-05-06 00:08:46 +00006419 /* Console processes which share a common console can be sent CTRL+C or
6420 CTRL+BREAK events, provided they handle said events. */
6421 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006422 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 err = GetLastError();
6424 PyErr_SetFromWindowsErr(err);
6425 }
6426 else
6427 Py_RETURN_NONE;
6428 }
Brian Curtineb24d742010-04-12 17:16:38 +00006429
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6431 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006432 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 if (handle == NULL) {
6434 err = GetLastError();
6435 return PyErr_SetFromWindowsErr(err);
6436 }
Brian Curtineb24d742010-04-12 17:16:38 +00006437
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 if (TerminateProcess(handle, sig) == 0) {
6439 err = GetLastError();
6440 result = PyErr_SetFromWindowsErr(err);
6441 } else {
6442 Py_INCREF(Py_None);
6443 result = Py_None;
6444 }
Brian Curtineb24d742010-04-12 17:16:38 +00006445
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 CloseHandle(handle);
6447 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006448}
Larry Hastings2f936352014-08-05 14:04:04 +10006449#endif /* !MS_WINDOWS */
6450#endif /* HAVE_KILL */
6451
6452
6453#ifdef HAVE_KILLPG
6454/*[clinic input]
6455os.killpg
6456
6457 pgid: pid_t
6458 signal: int
6459 /
6460
6461Kill a process group with a signal.
6462[clinic start generated code]*/
6463
Larry Hastings2f936352014-08-05 14:04:04 +10006464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006465os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6466/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006467{
6468 /* XXX some man pages make the `pgid` parameter an int, others
6469 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6470 take the same type. Moreover, pid_t is always at least as wide as
6471 int (else compilation of this module fails), which is safe. */
6472 if (killpg(pgid, signal) == -1)
6473 return posix_error();
6474 Py_RETURN_NONE;
6475}
6476#endif /* HAVE_KILLPG */
6477
Brian Curtineb24d742010-04-12 17:16:38 +00006478
Guido van Rossumc0125471996-06-28 18:55:32 +00006479#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006480#ifdef HAVE_SYS_LOCK_H
6481#include <sys/lock.h>
6482#endif
6483
Larry Hastings2f936352014-08-05 14:04:04 +10006484/*[clinic input]
6485os.plock
6486 op: int
6487 /
6488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006489Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006490[clinic start generated code]*/
6491
Larry Hastings2f936352014-08-05 14:04:04 +10006492static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006493os_plock_impl(PyObject *module, int op)
6494/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006495{
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 if (plock(op) == -1)
6497 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006498 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006499}
Larry Hastings2f936352014-08-05 14:04:04 +10006500#endif /* HAVE_PLOCK */
6501
Guido van Rossumc0125471996-06-28 18:55:32 +00006502
Guido van Rossumb6775db1994-08-01 11:34:53 +00006503#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006504/*[clinic input]
6505os.setuid
6506
6507 uid: uid_t
6508 /
6509
6510Set the current process's user id.
6511[clinic start generated code]*/
6512
Larry Hastings2f936352014-08-05 14:04:04 +10006513static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006514os_setuid_impl(PyObject *module, uid_t uid)
6515/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006516{
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 if (setuid(uid) < 0)
6518 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006519 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006520}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006521#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006522
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006523
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006524#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006525/*[clinic input]
6526os.seteuid
6527
6528 euid: uid_t
6529 /
6530
6531Set the current process's effective user id.
6532[clinic start generated code]*/
6533
Larry Hastings2f936352014-08-05 14:04:04 +10006534static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006535os_seteuid_impl(PyObject *module, uid_t euid)
6536/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006537{
6538 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006540 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006541}
6542#endif /* HAVE_SETEUID */
6543
Larry Hastings2f936352014-08-05 14:04:04 +10006544
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006545#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006546/*[clinic input]
6547os.setegid
6548
6549 egid: gid_t
6550 /
6551
6552Set the current process's effective group id.
6553[clinic start generated code]*/
6554
Larry Hastings2f936352014-08-05 14:04:04 +10006555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006556os_setegid_impl(PyObject *module, gid_t egid)
6557/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006558{
6559 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006561 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006562}
6563#endif /* HAVE_SETEGID */
6564
Larry Hastings2f936352014-08-05 14:04:04 +10006565
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006566#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006567/*[clinic input]
6568os.setreuid
6569
6570 ruid: uid_t
6571 euid: uid_t
6572 /
6573
6574Set the current process's real and effective user ids.
6575[clinic start generated code]*/
6576
Larry Hastings2f936352014-08-05 14:04:04 +10006577static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006578os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6579/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006580{
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 if (setreuid(ruid, euid) < 0) {
6582 return posix_error();
6583 } else {
6584 Py_INCREF(Py_None);
6585 return Py_None;
6586 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006587}
6588#endif /* HAVE_SETREUID */
6589
Larry Hastings2f936352014-08-05 14:04:04 +10006590
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006591#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006592/*[clinic input]
6593os.setregid
6594
6595 rgid: gid_t
6596 egid: gid_t
6597 /
6598
6599Set the current process's real and effective group ids.
6600[clinic start generated code]*/
6601
Larry Hastings2f936352014-08-05 14:04:04 +10006602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006603os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6604/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006605{
6606 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006608 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006609}
6610#endif /* HAVE_SETREGID */
6611
Larry Hastings2f936352014-08-05 14:04:04 +10006612
Guido van Rossumb6775db1994-08-01 11:34:53 +00006613#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006614/*[clinic input]
6615os.setgid
6616 gid: gid_t
6617 /
6618
6619Set the current process's group id.
6620[clinic start generated code]*/
6621
Larry Hastings2f936352014-08-05 14:04:04 +10006622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006623os_setgid_impl(PyObject *module, gid_t gid)
6624/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006625{
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 if (setgid(gid) < 0)
6627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006628 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006629}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006630#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006631
Larry Hastings2f936352014-08-05 14:04:04 +10006632
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006633#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006634/*[clinic input]
6635os.setgroups
6636
6637 groups: object
6638 /
6639
6640Set the groups of the current process to list.
6641[clinic start generated code]*/
6642
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006644os_setgroups(PyObject *module, PyObject *groups)
6645/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006646{
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 int i, len;
6648 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006649
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 if (!PySequence_Check(groups)) {
6651 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6652 return NULL;
6653 }
6654 len = PySequence_Size(groups);
6655 if (len > MAX_GROUPS) {
6656 PyErr_SetString(PyExc_ValueError, "too many groups");
6657 return NULL;
6658 }
6659 for(i = 0; i < len; i++) {
6660 PyObject *elem;
6661 elem = PySequence_GetItem(groups, i);
6662 if (!elem)
6663 return NULL;
6664 if (!PyLong_Check(elem)) {
6665 PyErr_SetString(PyExc_TypeError,
6666 "groups must be integers");
6667 Py_DECREF(elem);
6668 return NULL;
6669 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006670 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 Py_DECREF(elem);
6672 return NULL;
6673 }
6674 }
6675 Py_DECREF(elem);
6676 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006677
Victor Stinner8c62be82010-05-06 00:08:46 +00006678 if (setgroups(len, grouplist) < 0)
6679 return posix_error();
6680 Py_INCREF(Py_None);
6681 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006682}
6683#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006684
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006685#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6686static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006687wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006688{
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 PyObject *result;
6690 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006691 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006692
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 if (pid == -1)
6694 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006695
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 if (struct_rusage == NULL) {
6697 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6698 if (m == NULL)
6699 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006700 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 Py_DECREF(m);
6702 if (struct_rusage == NULL)
6703 return NULL;
6704 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006705
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6707 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6708 if (!result)
6709 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006710
6711#ifndef doubletime
6712#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6713#endif
6714
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006716 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006718 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006719#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6721 SET_INT(result, 2, ru->ru_maxrss);
6722 SET_INT(result, 3, ru->ru_ixrss);
6723 SET_INT(result, 4, ru->ru_idrss);
6724 SET_INT(result, 5, ru->ru_isrss);
6725 SET_INT(result, 6, ru->ru_minflt);
6726 SET_INT(result, 7, ru->ru_majflt);
6727 SET_INT(result, 8, ru->ru_nswap);
6728 SET_INT(result, 9, ru->ru_inblock);
6729 SET_INT(result, 10, ru->ru_oublock);
6730 SET_INT(result, 11, ru->ru_msgsnd);
6731 SET_INT(result, 12, ru->ru_msgrcv);
6732 SET_INT(result, 13, ru->ru_nsignals);
6733 SET_INT(result, 14, ru->ru_nvcsw);
6734 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006735#undef SET_INT
6736
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 if (PyErr_Occurred()) {
6738 Py_DECREF(result);
6739 return NULL;
6740 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006741
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006743}
6744#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6745
Larry Hastings2f936352014-08-05 14:04:04 +10006746
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006747#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006748/*[clinic input]
6749os.wait3
6750
6751 options: int
6752Wait for completion of a child process.
6753
6754Returns a tuple of information about the child process:
6755 (pid, status, rusage)
6756[clinic start generated code]*/
6757
Larry Hastings2f936352014-08-05 14:04:04 +10006758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006759os_wait3_impl(PyObject *module, int options)
6760/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006761{
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006764 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 WAIT_TYPE status;
6766 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006767
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006768 do {
6769 Py_BEGIN_ALLOW_THREADS
6770 pid = wait3(&status, options, &ru);
6771 Py_END_ALLOW_THREADS
6772 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6773 if (pid < 0)
6774 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006775
Victor Stinner4195b5c2012-02-08 23:03:19 +01006776 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006777}
6778#endif /* HAVE_WAIT3 */
6779
Larry Hastings2f936352014-08-05 14:04:04 +10006780
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006781#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006782/*[clinic input]
6783
6784os.wait4
6785
6786 pid: pid_t
6787 options: int
6788
6789Wait for completion of a specific child process.
6790
6791Returns a tuple of information about the child process:
6792 (pid, status, rusage)
6793[clinic start generated code]*/
6794
Larry Hastings2f936352014-08-05 14:04:04 +10006795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006796os_wait4_impl(PyObject *module, pid_t pid, int options)
6797/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006798{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006799 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006801 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 WAIT_TYPE status;
6803 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006804
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006805 do {
6806 Py_BEGIN_ALLOW_THREADS
6807 res = wait4(pid, &status, options, &ru);
6808 Py_END_ALLOW_THREADS
6809 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6810 if (res < 0)
6811 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006812
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006813 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006814}
6815#endif /* HAVE_WAIT4 */
6816
Larry Hastings2f936352014-08-05 14:04:04 +10006817
Ross Lagerwall7807c352011-03-17 20:20:30 +02006818#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006819/*[clinic input]
6820os.waitid
6821
6822 idtype: idtype_t
6823 Must be one of be P_PID, P_PGID or P_ALL.
6824 id: id_t
6825 The id to wait on.
6826 options: int
6827 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6828 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6829 /
6830
6831Returns the result of waiting for a process or processes.
6832
6833Returns either waitid_result or None if WNOHANG is specified and there are
6834no children in a waitable state.
6835[clinic start generated code]*/
6836
Larry Hastings2f936352014-08-05 14:04:04 +10006837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006838os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6839/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006840{
6841 PyObject *result;
6842 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006843 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006844 siginfo_t si;
6845 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006846
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006847 do {
6848 Py_BEGIN_ALLOW_THREADS
6849 res = waitid(idtype, id, &si, options);
6850 Py_END_ALLOW_THREADS
6851 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6852 if (res < 0)
6853 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006854
6855 if (si.si_pid == 0)
6856 Py_RETURN_NONE;
6857
6858 result = PyStructSequence_New(&WaitidResultType);
6859 if (!result)
6860 return NULL;
6861
6862 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006863 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006864 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6865 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6866 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6867 if (PyErr_Occurred()) {
6868 Py_DECREF(result);
6869 return NULL;
6870 }
6871
6872 return result;
6873}
Larry Hastings2f936352014-08-05 14:04:04 +10006874#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006875
Larry Hastings2f936352014-08-05 14:04:04 +10006876
6877#if defined(HAVE_WAITPID)
6878/*[clinic input]
6879os.waitpid
6880 pid: pid_t
6881 options: int
6882 /
6883
6884Wait for completion of a given child process.
6885
6886Returns a tuple of information regarding the child process:
6887 (pid, status)
6888
6889The options argument is ignored on Windows.
6890[clinic start generated code]*/
6891
Larry Hastings2f936352014-08-05 14:04:04 +10006892static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006893os_waitpid_impl(PyObject *module, pid_t pid, int options)
6894/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006895{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006896 pid_t res;
6897 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 WAIT_TYPE status;
6899 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006900
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006901 do {
6902 Py_BEGIN_ALLOW_THREADS
6903 res = waitpid(pid, &status, options);
6904 Py_END_ALLOW_THREADS
6905 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6906 if (res < 0)
6907 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006908
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006909 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006910}
Tim Petersab034fa2002-02-01 11:27:43 +00006911#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006912/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006913/*[clinic input]
6914os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006915 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006916 options: int
6917 /
6918
6919Wait for completion of a given process.
6920
6921Returns a tuple of information regarding the process:
6922 (pid, status << 8)
6923
6924The options argument is ignored on Windows.
6925[clinic start generated code]*/
6926
Larry Hastings2f936352014-08-05 14:04:04 +10006927static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006928os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006929/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006930{
6931 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006932 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006933 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 do {
6936 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006937 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006938 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006939 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006940 Py_END_ALLOW_THREADS
6941 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006942 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006943 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006944
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006947}
Larry Hastings2f936352014-08-05 14:04:04 +10006948#endif
6949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006950
Guido van Rossumad0ee831995-03-01 10:34:45 +00006951#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006952/*[clinic input]
6953os.wait
6954
6955Wait for completion of a child process.
6956
6957Returns a tuple of information about the child process:
6958 (pid, status)
6959[clinic start generated code]*/
6960
Larry Hastings2f936352014-08-05 14:04:04 +10006961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006962os_wait_impl(PyObject *module)
6963/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006964{
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006966 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 WAIT_TYPE status;
6968 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006969
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006970 do {
6971 Py_BEGIN_ALLOW_THREADS
6972 pid = wait(&status);
6973 Py_END_ALLOW_THREADS
6974 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6975 if (pid < 0)
6976 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006977
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006979}
Larry Hastings2f936352014-08-05 14:04:04 +10006980#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006982
Larry Hastings9cf065c2012-06-22 16:30:09 -07006983#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6984PyDoc_STRVAR(readlink__doc__,
6985"readlink(path, *, dir_fd=None) -> path\n\n\
6986Return a string representing the path to which the symbolic link points.\n\
6987\n\
6988If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6989 and path should be relative; path will then be relative to that directory.\n\
6990dir_fd may not be implemented on your platform.\n\
6991 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006992#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006993
Guido van Rossumb6775db1994-08-01 11:34:53 +00006994#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006995
Larry Hastings2f936352014-08-05 14:04:04 +10006996/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006997static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006998posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006999{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007000 path_t path;
7001 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007002 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007003 ssize_t length;
7004 PyObject *return_value = NULL;
7005 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007006
Larry Hastings9cf065c2012-06-22 16:30:09 -07007007 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007008 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007009 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7010 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007011 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007013
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007015#ifdef HAVE_READLINKAT
7016 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007017 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007018 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007019#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007020 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007021 Py_END_ALLOW_THREADS
7022
7023 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007024 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007025 goto exit;
7026 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007027 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007028
7029 if (PyUnicode_Check(path.object))
7030 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7031 else
7032 return_value = PyBytes_FromStringAndSize(buffer, length);
7033exit:
7034 path_cleanup(&path);
7035 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007036}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007037
Guido van Rossumb6775db1994-08-01 11:34:53 +00007038#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007039
Larry Hastings2f936352014-08-05 14:04:04 +10007040#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7041
7042static PyObject *
7043win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7044{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007045 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007046 DWORD n_bytes_returned;
7047 DWORD io_result;
7048 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007049 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007050 HANDLE reparse_point_handle;
7051
Martin Panter70214ad2016-08-04 02:38:59 +00007052 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7053 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007054 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007055
7056 static char *keywords[] = {"path", "dir_fd", NULL};
7057
7058 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7059 &po,
7060 dir_fd_unavailable, &dir_fd
7061 ))
7062 return NULL;
7063
7064 path = PyUnicode_AsUnicode(po);
7065 if (path == NULL)
7066 return NULL;
7067
7068 /* First get a handle to the reparse point */
7069 Py_BEGIN_ALLOW_THREADS
7070 reparse_point_handle = CreateFileW(
7071 path,
7072 0,
7073 0,
7074 0,
7075 OPEN_EXISTING,
7076 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7077 0);
7078 Py_END_ALLOW_THREADS
7079
7080 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7081 return win32_error_object("readlink", po);
7082
7083 Py_BEGIN_ALLOW_THREADS
7084 /* New call DeviceIoControl to read the reparse point */
7085 io_result = DeviceIoControl(
7086 reparse_point_handle,
7087 FSCTL_GET_REPARSE_POINT,
7088 0, 0, /* in buffer */
7089 target_buffer, sizeof(target_buffer),
7090 &n_bytes_returned,
7091 0 /* we're not using OVERLAPPED_IO */
7092 );
7093 CloseHandle(reparse_point_handle);
7094 Py_END_ALLOW_THREADS
7095
7096 if (io_result==0)
7097 return win32_error_object("readlink", po);
7098
7099 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7100 {
7101 PyErr_SetString(PyExc_ValueError,
7102 "not a symbolic link");
7103 return NULL;
7104 }
7105 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7106 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7107
7108 result = PyUnicode_FromWideChar(print_name,
7109 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7110 return result;
7111}
7112
7113#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7114
7115
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007116
Larry Hastings9cf065c2012-06-22 16:30:09 -07007117#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118
7119#if defined(MS_WINDOWS)
7120
7121/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007122static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007123
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007125check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126{
7127 HINSTANCE hKernel32;
7128 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007129 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130 return 1;
7131 hKernel32 = GetModuleHandleW(L"KERNEL32");
7132 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7133 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007134 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135}
7136
Victor Stinner31b3b922013-06-05 01:49:17 +02007137/* Remove the last portion of the path */
7138static void
7139_dirnameW(WCHAR *path)
7140{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007141 WCHAR *ptr;
7142
7143 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007144 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007145 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007146 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007147 }
7148 *ptr = 0;
7149}
7150
Victor Stinner31b3b922013-06-05 01:49:17 +02007151/* Is this path absolute? */
7152static int
7153_is_absW(const WCHAR *path)
7154{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007155 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7156
7157}
7158
Victor Stinner31b3b922013-06-05 01:49:17 +02007159/* join root and rest with a backslash */
7160static void
7161_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7162{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007163 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007164
Victor Stinner31b3b922013-06-05 01:49:17 +02007165 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007166 wcscpy(dest_path, rest);
7167 return;
7168 }
7169
7170 root_len = wcslen(root);
7171
7172 wcscpy(dest_path, root);
7173 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007174 dest_path[root_len] = L'\\';
7175 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007176 }
7177 wcscpy(dest_path+root_len, rest);
7178}
7179
Victor Stinner31b3b922013-06-05 01:49:17 +02007180/* Return True if the path at src relative to dest is a directory */
7181static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007182_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007183{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007184 WIN32_FILE_ATTRIBUTE_DATA src_info;
7185 WCHAR dest_parent[MAX_PATH];
7186 WCHAR src_resolved[MAX_PATH] = L"";
7187
7188 /* dest_parent = os.path.dirname(dest) */
7189 wcscpy(dest_parent, dest);
7190 _dirnameW(dest_parent);
7191 /* src_resolved = os.path.join(dest_parent, src) */
7192 _joinW(src_resolved, dest_parent, src);
7193 return (
7194 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7195 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7196 );
7197}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007198#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007199
Larry Hastings2f936352014-08-05 14:04:04 +10007200
7201/*[clinic input]
7202os.symlink
7203 src: path_t
7204 dst: path_t
7205 target_is_directory: bool = False
7206 *
7207 dir_fd: dir_fd(requires='symlinkat')=None
7208
7209# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7210
7211Create a symbolic link pointing to src named dst.
7212
7213target_is_directory is required on Windows if the target is to be
7214 interpreted as a directory. (On Windows, symlink requires
7215 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7216 target_is_directory is ignored on non-Windows platforms.
7217
7218If dir_fd is not None, it should be a file descriptor open to a directory,
7219 and path should be relative; path will then be relative to that directory.
7220dir_fd may not be implemented on your platform.
7221 If it is unavailable, using it will raise a NotImplementedError.
7222
7223[clinic start generated code]*/
7224
Larry Hastings2f936352014-08-05 14:04:04 +10007225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007226os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007227 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007228/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007229{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007230#ifdef MS_WINDOWS
7231 DWORD result;
7232#else
7233 int result;
7234#endif
7235
Larry Hastings9cf065c2012-06-22 16:30:09 -07007236#ifdef MS_WINDOWS
7237 if (!check_CreateSymbolicLink()) {
7238 PyErr_SetString(PyExc_NotImplementedError,
7239 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007240 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007241 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007242 if (!win32_can_symlink) {
7243 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007244 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007245 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007246#endif
7247
Larry Hastings2f936352014-08-05 14:04:04 +10007248 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007249 PyErr_SetString(PyExc_ValueError,
7250 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007251 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007252 }
7253
7254#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007255
Larry Hastings9cf065c2012-06-22 16:30:09 -07007256 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007257 /* if src is a directory, ensure target_is_directory==1 */
7258 target_is_directory |= _check_dirW(src->wide, dst->wide);
7259 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7260 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007261 Py_END_ALLOW_THREADS
7262
Larry Hastings2f936352014-08-05 14:04:04 +10007263 if (!result)
7264 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265
7266#else
7267
7268 Py_BEGIN_ALLOW_THREADS
7269#if HAVE_SYMLINKAT
7270 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007271 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007272 else
7273#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007274 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275 Py_END_ALLOW_THREADS
7276
Larry Hastings2f936352014-08-05 14:04:04 +10007277 if (result)
7278 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007279#endif
7280
Larry Hastings2f936352014-08-05 14:04:04 +10007281 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007282}
7283#endif /* HAVE_SYMLINK */
7284
Larry Hastings9cf065c2012-06-22 16:30:09 -07007285
Brian Curtind40e6f72010-07-08 21:39:08 +00007286
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007287
Larry Hastings605a62d2012-06-24 04:33:36 -07007288static PyStructSequence_Field times_result_fields[] = {
7289 {"user", "user time"},
7290 {"system", "system time"},
7291 {"children_user", "user time of children"},
7292 {"children_system", "system time of children"},
7293 {"elapsed", "elapsed time since an arbitrary point in the past"},
7294 {NULL}
7295};
7296
7297PyDoc_STRVAR(times_result__doc__,
7298"times_result: Result from os.times().\n\n\
7299This object may be accessed either as a tuple of\n\
7300 (user, system, children_user, children_system, elapsed),\n\
7301or via the attributes user, system, children_user, children_system,\n\
7302and elapsed.\n\
7303\n\
7304See os.times for more information.");
7305
7306static PyStructSequence_Desc times_result_desc = {
7307 "times_result", /* name */
7308 times_result__doc__, /* doc */
7309 times_result_fields,
7310 5
7311};
7312
7313static PyTypeObject TimesResultType;
7314
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007315#ifdef MS_WINDOWS
7316#define HAVE_TIMES /* mandatory, for the method table */
7317#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007318
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007319#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007320
7321static PyObject *
7322build_times_result(double user, double system,
7323 double children_user, double children_system,
7324 double elapsed)
7325{
7326 PyObject *value = PyStructSequence_New(&TimesResultType);
7327 if (value == NULL)
7328 return NULL;
7329
7330#define SET(i, field) \
7331 { \
7332 PyObject *o = PyFloat_FromDouble(field); \
7333 if (!o) { \
7334 Py_DECREF(value); \
7335 return NULL; \
7336 } \
7337 PyStructSequence_SET_ITEM(value, i, o); \
7338 } \
7339
7340 SET(0, user);
7341 SET(1, system);
7342 SET(2, children_user);
7343 SET(3, children_system);
7344 SET(4, elapsed);
7345
7346#undef SET
7347
7348 return value;
7349}
7350
Larry Hastings605a62d2012-06-24 04:33:36 -07007351
Larry Hastings2f936352014-08-05 14:04:04 +10007352#ifndef MS_WINDOWS
7353#define NEED_TICKS_PER_SECOND
7354static long ticks_per_second = -1;
7355#endif /* MS_WINDOWS */
7356
7357/*[clinic input]
7358os.times
7359
7360Return a collection containing process timing information.
7361
7362The object returned behaves like a named tuple with these fields:
7363 (utime, stime, cutime, cstime, elapsed_time)
7364All fields are floating point numbers.
7365[clinic start generated code]*/
7366
Larry Hastings2f936352014-08-05 14:04:04 +10007367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007368os_times_impl(PyObject *module)
7369/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007370#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007371{
Victor Stinner8c62be82010-05-06 00:08:46 +00007372 FILETIME create, exit, kernel, user;
7373 HANDLE hProc;
7374 hProc = GetCurrentProcess();
7375 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7376 /* The fields of a FILETIME structure are the hi and lo part
7377 of a 64-bit value expressed in 100 nanosecond units.
7378 1e7 is one second in such units; 1e-7 the inverse.
7379 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7380 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007381 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007382 (double)(user.dwHighDateTime*429.4967296 +
7383 user.dwLowDateTime*1e-7),
7384 (double)(kernel.dwHighDateTime*429.4967296 +
7385 kernel.dwLowDateTime*1e-7),
7386 (double)0,
7387 (double)0,
7388 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007389}
Larry Hastings2f936352014-08-05 14:04:04 +10007390#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007391{
Larry Hastings2f936352014-08-05 14:04:04 +10007392
7393
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007394 struct tms t;
7395 clock_t c;
7396 errno = 0;
7397 c = times(&t);
7398 if (c == (clock_t) -1)
7399 return posix_error();
7400 return build_times_result(
7401 (double)t.tms_utime / ticks_per_second,
7402 (double)t.tms_stime / ticks_per_second,
7403 (double)t.tms_cutime / ticks_per_second,
7404 (double)t.tms_cstime / ticks_per_second,
7405 (double)c / ticks_per_second);
7406}
Larry Hastings2f936352014-08-05 14:04:04 +10007407#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007408#endif /* HAVE_TIMES */
7409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007410
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007411#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007412/*[clinic input]
7413os.getsid
7414
7415 pid: pid_t
7416 /
7417
7418Call the system call getsid(pid) and return the result.
7419[clinic start generated code]*/
7420
Larry Hastings2f936352014-08-05 14:04:04 +10007421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007422os_getsid_impl(PyObject *module, pid_t pid)
7423/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007424{
Victor Stinner8c62be82010-05-06 00:08:46 +00007425 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 sid = getsid(pid);
7427 if (sid < 0)
7428 return posix_error();
7429 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007430}
7431#endif /* HAVE_GETSID */
7432
7433
Guido van Rossumb6775db1994-08-01 11:34:53 +00007434#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007435/*[clinic input]
7436os.setsid
7437
7438Call the system call setsid().
7439[clinic start generated code]*/
7440
Larry Hastings2f936352014-08-05 14:04:04 +10007441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007442os_setsid_impl(PyObject *module)
7443/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007444{
Victor Stinner8c62be82010-05-06 00:08:46 +00007445 if (setsid() < 0)
7446 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007447 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007448}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007449#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007450
Larry Hastings2f936352014-08-05 14:04:04 +10007451
Guido van Rossumb6775db1994-08-01 11:34:53 +00007452#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007453/*[clinic input]
7454os.setpgid
7455
7456 pid: pid_t
7457 pgrp: pid_t
7458 /
7459
7460Call the system call setpgid(pid, pgrp).
7461[clinic start generated code]*/
7462
Larry Hastings2f936352014-08-05 14:04:04 +10007463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007464os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7465/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007466{
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 if (setpgid(pid, pgrp) < 0)
7468 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007469 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007470}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007471#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007472
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007473
Guido van Rossumb6775db1994-08-01 11:34:53 +00007474#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007475/*[clinic input]
7476os.tcgetpgrp
7477
7478 fd: int
7479 /
7480
7481Return the process group associated with the terminal specified by fd.
7482[clinic start generated code]*/
7483
Larry Hastings2f936352014-08-05 14:04:04 +10007484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007485os_tcgetpgrp_impl(PyObject *module, int fd)
7486/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007487{
7488 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007489 if (pgid < 0)
7490 return posix_error();
7491 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007492}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007493#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007494
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007495
Guido van Rossumb6775db1994-08-01 11:34:53 +00007496#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007497/*[clinic input]
7498os.tcsetpgrp
7499
7500 fd: int
7501 pgid: pid_t
7502 /
7503
7504Set the process group associated with the terminal specified by fd.
7505[clinic start generated code]*/
7506
Larry Hastings2f936352014-08-05 14:04:04 +10007507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007508os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7509/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007510{
Victor Stinner8c62be82010-05-06 00:08:46 +00007511 if (tcsetpgrp(fd, pgid) < 0)
7512 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007513 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007514}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007515#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007516
Guido van Rossum687dd131993-05-17 08:34:16 +00007517/* Functions acting on file descriptors */
7518
Victor Stinnerdaf45552013-08-28 00:53:59 +02007519#ifdef O_CLOEXEC
7520extern int _Py_open_cloexec_works;
7521#endif
7522
Larry Hastings2f936352014-08-05 14:04:04 +10007523
7524/*[clinic input]
7525os.open -> int
7526 path: path_t
7527 flags: int
7528 mode: int = 0o777
7529 *
7530 dir_fd: dir_fd(requires='openat') = None
7531
7532# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7533
7534Open a file for low level IO. Returns a file descriptor (integer).
7535
7536If dir_fd is not None, it should be a file descriptor open to a directory,
7537 and path should be relative; path will then be relative to that directory.
7538dir_fd may not be implemented on your platform.
7539 If it is unavailable, using it will raise a NotImplementedError.
7540[clinic start generated code]*/
7541
Larry Hastings2f936352014-08-05 14:04:04 +10007542static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007543os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7544/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007545{
7546 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007547 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007548
Victor Stinnerdaf45552013-08-28 00:53:59 +02007549#ifdef O_CLOEXEC
7550 int *atomic_flag_works = &_Py_open_cloexec_works;
7551#elif !defined(MS_WINDOWS)
7552 int *atomic_flag_works = NULL;
7553#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007554
Victor Stinnerdaf45552013-08-28 00:53:59 +02007555#ifdef MS_WINDOWS
7556 flags |= O_NOINHERIT;
7557#elif defined(O_CLOEXEC)
7558 flags |= O_CLOEXEC;
7559#endif
7560
Steve Dower8fc89802015-04-12 00:26:27 -04007561 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007562 do {
7563 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007564#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007565 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007566#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007567#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007568 if (dir_fd != DEFAULT_DIR_FD)
7569 fd = openat(dir_fd, path->narrow, flags, mode);
7570 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007571#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007572 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007573#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007574 Py_END_ALLOW_THREADS
7575 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007576 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007577
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007578 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007579 if (!async_err)
7580 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007581 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007582 }
7583
Victor Stinnerdaf45552013-08-28 00:53:59 +02007584#ifndef MS_WINDOWS
7585 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7586 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007587 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007588 }
7589#endif
7590
Larry Hastings2f936352014-08-05 14:04:04 +10007591 return fd;
7592}
7593
7594
7595/*[clinic input]
7596os.close
7597
7598 fd: int
7599
7600Close a file descriptor.
7601[clinic start generated code]*/
7602
Barry Warsaw53699e91996-12-10 23:23:01 +00007603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007604os_close_impl(PyObject *module, int fd)
7605/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007606{
Larry Hastings2f936352014-08-05 14:04:04 +10007607 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007608 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7609 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7610 * for more details.
7611 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007612 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007613 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007614 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007615 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 Py_END_ALLOW_THREADS
7617 if (res < 0)
7618 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007619 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007620}
7621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007622
Larry Hastings2f936352014-08-05 14:04:04 +10007623/*[clinic input]
7624os.closerange
7625
7626 fd_low: int
7627 fd_high: int
7628 /
7629
7630Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7631[clinic start generated code]*/
7632
Larry Hastings2f936352014-08-05 14:04:04 +10007633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007634os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7635/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007636{
7637 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007639 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007640 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007641 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007642 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 Py_END_ALLOW_THREADS
7644 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007645}
7646
7647
Larry Hastings2f936352014-08-05 14:04:04 +10007648/*[clinic input]
7649os.dup -> int
7650
7651 fd: int
7652 /
7653
7654Return a duplicate of a file descriptor.
7655[clinic start generated code]*/
7656
Larry Hastings2f936352014-08-05 14:04:04 +10007657static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007658os_dup_impl(PyObject *module, int fd)
7659/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007660{
7661 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007662}
7663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Larry Hastings2f936352014-08-05 14:04:04 +10007665/*[clinic input]
7666os.dup2
7667 fd: int
7668 fd2: int
7669 inheritable: bool=True
7670
7671Duplicate file descriptor.
7672[clinic start generated code]*/
7673
Larry Hastings2f936352014-08-05 14:04:04 +10007674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007675os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7676/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007677{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007678 int res;
7679#if defined(HAVE_DUP3) && \
7680 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7681 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7682 int dup3_works = -1;
7683#endif
7684
Steve Dower940f33a2016-09-08 11:21:54 -07007685 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007687
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007688 /* dup2() can fail with EINTR if the target FD is already open, because it
7689 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7690 * upon close(), and therefore below.
7691 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007692#ifdef MS_WINDOWS
7693 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007694 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007696 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007697 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 if (res < 0)
7699 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007700
7701 /* Character files like console cannot be make non-inheritable */
7702 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7703 close(fd2);
7704 return NULL;
7705 }
7706
7707#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7708 Py_BEGIN_ALLOW_THREADS
7709 if (!inheritable)
7710 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7711 else
7712 res = dup2(fd, fd2);
7713 Py_END_ALLOW_THREADS
7714 if (res < 0)
7715 return posix_error();
7716
7717#else
7718
7719#ifdef HAVE_DUP3
7720 if (!inheritable && dup3_works != 0) {
7721 Py_BEGIN_ALLOW_THREADS
7722 res = dup3(fd, fd2, O_CLOEXEC);
7723 Py_END_ALLOW_THREADS
7724 if (res < 0) {
7725 if (dup3_works == -1)
7726 dup3_works = (errno != ENOSYS);
7727 if (dup3_works)
7728 return posix_error();
7729 }
7730 }
7731
7732 if (inheritable || dup3_works == 0)
7733 {
7734#endif
7735 Py_BEGIN_ALLOW_THREADS
7736 res = dup2(fd, fd2);
7737 Py_END_ALLOW_THREADS
7738 if (res < 0)
7739 return posix_error();
7740
7741 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7742 close(fd2);
7743 return NULL;
7744 }
7745#ifdef HAVE_DUP3
7746 }
7747#endif
7748
7749#endif
7750
Larry Hastings2f936352014-08-05 14:04:04 +10007751 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007752}
7753
Larry Hastings2f936352014-08-05 14:04:04 +10007754
Ross Lagerwall7807c352011-03-17 20:20:30 +02007755#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007756/*[clinic input]
7757os.lockf
7758
7759 fd: int
7760 An open file descriptor.
7761 command: int
7762 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7763 length: Py_off_t
7764 The number of bytes to lock, starting at the current position.
7765 /
7766
7767Apply, test or remove a POSIX lock on an open file descriptor.
7768
7769[clinic start generated code]*/
7770
Larry Hastings2f936352014-08-05 14:04:04 +10007771static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007772os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7773/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007774{
7775 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007776
7777 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007778 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007779 Py_END_ALLOW_THREADS
7780
7781 if (res < 0)
7782 return posix_error();
7783
7784 Py_RETURN_NONE;
7785}
Larry Hastings2f936352014-08-05 14:04:04 +10007786#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007788
Larry Hastings2f936352014-08-05 14:04:04 +10007789/*[clinic input]
7790os.lseek -> Py_off_t
7791
7792 fd: int
7793 position: Py_off_t
7794 how: int
7795 /
7796
7797Set the position of a file descriptor. Return the new position.
7798
7799Return the new cursor position in number of bytes
7800relative to the beginning of the file.
7801[clinic start generated code]*/
7802
Larry Hastings2f936352014-08-05 14:04:04 +10007803static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007804os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7805/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007806{
7807 Py_off_t result;
7808
Guido van Rossum687dd131993-05-17 08:34:16 +00007809#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7811 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007812 case 0: how = SEEK_SET; break;
7813 case 1: how = SEEK_CUR; break;
7814 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007816#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007817
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007819 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007820
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007822 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007823#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007824 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007825#else
Larry Hastings2f936352014-08-05 14:04:04 +10007826 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007827#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007828 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007830 if (result < 0)
7831 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007832
Larry Hastings2f936352014-08-05 14:04:04 +10007833 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007834}
7835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007836
Larry Hastings2f936352014-08-05 14:04:04 +10007837/*[clinic input]
7838os.read
7839 fd: int
7840 length: Py_ssize_t
7841 /
7842
7843Read from a file descriptor. Returns a bytes object.
7844[clinic start generated code]*/
7845
Larry Hastings2f936352014-08-05 14:04:04 +10007846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007847os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7848/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007849{
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 Py_ssize_t n;
7851 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007852
7853 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 errno = EINVAL;
7855 return posix_error();
7856 }
Larry Hastings2f936352014-08-05 14:04:04 +10007857
7858#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007859 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007860 if (length > INT_MAX)
7861 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007862#endif
7863
7864 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 if (buffer == NULL)
7866 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007867
Victor Stinner66aab0c2015-03-19 22:53:20 +01007868 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7869 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007871 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 }
Larry Hastings2f936352014-08-05 14:04:04 +10007873
7874 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007876
Victor Stinner8c62be82010-05-06 00:08:46 +00007877 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007878}
7879
Ross Lagerwall7807c352011-03-17 20:20:30 +02007880#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7881 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007882static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007883iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7884{
7885 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007886 Py_ssize_t blen, total = 0;
7887
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007888 *iov = PyMem_New(struct iovec, cnt);
7889 if (*iov == NULL) {
7890 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007891 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007892 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007893
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007894 *buf = PyMem_New(Py_buffer, cnt);
7895 if (*buf == NULL) {
7896 PyMem_Del(*iov);
7897 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007898 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007899 }
7900
7901 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007902 PyObject *item = PySequence_GetItem(seq, i);
7903 if (item == NULL)
7904 goto fail;
7905 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7906 Py_DECREF(item);
7907 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007908 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007909 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007910 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007911 blen = (*buf)[i].len;
7912 (*iov)[i].iov_len = blen;
7913 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007914 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007915 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007916
7917fail:
7918 PyMem_Del(*iov);
7919 for (j = 0; j < i; j++) {
7920 PyBuffer_Release(&(*buf)[j]);
7921 }
7922 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007923 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007924}
7925
7926static void
7927iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7928{
7929 int i;
7930 PyMem_Del(iov);
7931 for (i = 0; i < cnt; i++) {
7932 PyBuffer_Release(&buf[i]);
7933 }
7934 PyMem_Del(buf);
7935}
7936#endif
7937
Larry Hastings2f936352014-08-05 14:04:04 +10007938
Ross Lagerwall7807c352011-03-17 20:20:30 +02007939#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007940/*[clinic input]
7941os.readv -> Py_ssize_t
7942
7943 fd: int
7944 buffers: object
7945 /
7946
7947Read from a file descriptor fd into an iterable of buffers.
7948
7949The buffers should be mutable buffers accepting bytes.
7950readv will transfer data into each buffer until it is full
7951and then move on to the next buffer in the sequence to hold
7952the rest of the data.
7953
7954readv returns the total number of bytes read,
7955which may be less than the total capacity of all the buffers.
7956[clinic start generated code]*/
7957
Larry Hastings2f936352014-08-05 14:04:04 +10007958static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007959os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7960/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007961{
7962 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007963 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007964 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007965 struct iovec *iov;
7966 Py_buffer *buf;
7967
Larry Hastings2f936352014-08-05 14:04:04 +10007968 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007969 PyErr_SetString(PyExc_TypeError,
7970 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007971 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007973
Larry Hastings2f936352014-08-05 14:04:04 +10007974 cnt = PySequence_Size(buffers);
7975
7976 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7977 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007978
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007979 do {
7980 Py_BEGIN_ALLOW_THREADS
7981 n = readv(fd, iov, cnt);
7982 Py_END_ALLOW_THREADS
7983 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007984
7985 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007986 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007987 if (!async_err)
7988 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007989 return -1;
7990 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007991
Larry Hastings2f936352014-08-05 14:04:04 +10007992 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007993}
Larry Hastings2f936352014-08-05 14:04:04 +10007994#endif /* HAVE_READV */
7995
Ross Lagerwall7807c352011-03-17 20:20:30 +02007996
7997#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007998/*[clinic input]
7999# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8000os.pread
8001
8002 fd: int
8003 length: int
8004 offset: Py_off_t
8005 /
8006
8007Read a number of bytes from a file descriptor starting at a particular offset.
8008
8009Read length bytes from file descriptor fd, starting at offset bytes from
8010the beginning of the file. The file offset remains unchanged.
8011[clinic start generated code]*/
8012
Larry Hastings2f936352014-08-05 14:04:04 +10008013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008014os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8015/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008016{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008017 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008018 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008019 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008020
Larry Hastings2f936352014-08-05 14:04:04 +10008021 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008022 errno = EINVAL;
8023 return posix_error();
8024 }
Larry Hastings2f936352014-08-05 14:04:04 +10008025 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008026 if (buffer == NULL)
8027 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008028
8029 do {
8030 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008031 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008032 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008033 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008034 Py_END_ALLOW_THREADS
8035 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8036
Ross Lagerwall7807c352011-03-17 20:20:30 +02008037 if (n < 0) {
8038 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008039 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008040 }
Larry Hastings2f936352014-08-05 14:04:04 +10008041 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008042 _PyBytes_Resize(&buffer, n);
8043 return buffer;
8044}
Larry Hastings2f936352014-08-05 14:04:04 +10008045#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008046
Larry Hastings2f936352014-08-05 14:04:04 +10008047
8048/*[clinic input]
8049os.write -> Py_ssize_t
8050
8051 fd: int
8052 data: Py_buffer
8053 /
8054
8055Write a bytes object to a file descriptor.
8056[clinic start generated code]*/
8057
Larry Hastings2f936352014-08-05 14:04:04 +10008058static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008059os_write_impl(PyObject *module, int fd, Py_buffer *data)
8060/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008061{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008062 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008063}
8064
8065#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008067"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008068sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008069 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008070Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071
Larry Hastings2f936352014-08-05 14:04:04 +10008072/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008073static PyObject *
8074posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8075{
8076 int in, out;
8077 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008078 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 off_t offset;
8080
8081#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8082#ifndef __APPLE__
8083 Py_ssize_t len;
8084#endif
8085 PyObject *headers = NULL, *trailers = NULL;
8086 Py_buffer *hbuf, *tbuf;
8087 off_t sbytes;
8088 struct sf_hdtr sf;
8089 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008090 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008091 static char *keywords[] = {"out", "in",
8092 "offset", "count",
8093 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008094
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008095 sf.headers = NULL;
8096 sf.trailers = NULL;
8097
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008098#ifdef __APPLE__
8099 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008100 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008101#else
8102 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008103 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104#endif
8105 &headers, &trailers, &flags))
8106 return NULL;
8107 if (headers != NULL) {
8108 if (!PySequence_Check(headers)) {
8109 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008110 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008111 return NULL;
8112 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008113 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008114 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008115 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008116 (i = iov_setup(&(sf.headers), &hbuf,
8117 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008118 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008119#ifdef __APPLE__
8120 sbytes += i;
8121#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008122 }
8123 }
8124 if (trailers != NULL) {
8125 if (!PySequence_Check(trailers)) {
8126 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008127 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008128 return NULL;
8129 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008130 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008131 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008132 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008133 (i = iov_setup(&(sf.trailers), &tbuf,
8134 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008135 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008136#ifdef __APPLE__
8137 sbytes += i;
8138#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008139 }
8140 }
8141
Steve Dower8fc89802015-04-12 00:26:27 -04008142 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008143 do {
8144 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008145#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008146 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008147#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008148 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008149#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008150 Py_END_ALLOW_THREADS
8151 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008152 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008153
8154 if (sf.headers != NULL)
8155 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8156 if (sf.trailers != NULL)
8157 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8158
8159 if (ret < 0) {
8160 if ((errno == EAGAIN) || (errno == EBUSY)) {
8161 if (sbytes != 0) {
8162 // some data has been sent
8163 goto done;
8164 }
8165 else {
8166 // no data has been sent; upper application is supposed
8167 // to retry on EAGAIN or EBUSY
8168 return posix_error();
8169 }
8170 }
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 }
8173 goto done;
8174
8175done:
8176 #if !defined(HAVE_LARGEFILE_SUPPORT)
8177 return Py_BuildValue("l", sbytes);
8178 #else
8179 return Py_BuildValue("L", sbytes);
8180 #endif
8181
8182#else
8183 Py_ssize_t count;
8184 PyObject *offobj;
8185 static char *keywords[] = {"out", "in",
8186 "offset", "count", NULL};
8187 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8188 keywords, &out, &in, &offobj, &count))
8189 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008190#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008191 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008192 do {
8193 Py_BEGIN_ALLOW_THREADS
8194 ret = sendfile(out, in, NULL, count);
8195 Py_END_ALLOW_THREADS
8196 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008197 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008198 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008199 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008200 }
8201#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008202 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008203 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008204
8205 do {
8206 Py_BEGIN_ALLOW_THREADS
8207 ret = sendfile(out, in, &offset, count);
8208 Py_END_ALLOW_THREADS
8209 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008210 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008211 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008212 return Py_BuildValue("n", ret);
8213#endif
8214}
Larry Hastings2f936352014-08-05 14:04:04 +10008215#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008216
Larry Hastings2f936352014-08-05 14:04:04 +10008217
8218/*[clinic input]
8219os.fstat
8220
8221 fd : int
8222
8223Perform a stat system call on the given file descriptor.
8224
8225Like stat(), but for an open file descriptor.
8226Equivalent to os.stat(fd).
8227[clinic start generated code]*/
8228
Larry Hastings2f936352014-08-05 14:04:04 +10008229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008230os_fstat_impl(PyObject *module, int fd)
8231/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008232{
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 STRUCT_STAT st;
8234 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008235 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008236
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008237 do {
8238 Py_BEGIN_ALLOW_THREADS
8239 res = FSTAT(fd, &st);
8240 Py_END_ALLOW_THREADS
8241 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008243#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008244 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008245#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008246 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008247#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 }
Tim Peters5aa91602002-01-30 05:46:57 +00008249
Victor Stinner4195b5c2012-02-08 23:03:19 +01008250 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008251}
8252
Larry Hastings2f936352014-08-05 14:04:04 +10008253
8254/*[clinic input]
8255os.isatty -> bool
8256 fd: int
8257 /
8258
8259Return True if the fd is connected to a terminal.
8260
8261Return True if the file descriptor is an open file descriptor
8262connected to the slave end of a terminal.
8263[clinic start generated code]*/
8264
Larry Hastings2f936352014-08-05 14:04:04 +10008265static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008266os_isatty_impl(PyObject *module, int fd)
8267/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008268{
Steve Dower8fc89802015-04-12 00:26:27 -04008269 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008270 _Py_BEGIN_SUPPRESS_IPH
8271 return_value = isatty(fd);
8272 _Py_END_SUPPRESS_IPH
8273 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008274}
8275
8276
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008277#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008278/*[clinic input]
8279os.pipe
8280
8281Create a pipe.
8282
8283Returns a tuple of two file descriptors:
8284 (read_fd, write_fd)
8285[clinic start generated code]*/
8286
Larry Hastings2f936352014-08-05 14:04:04 +10008287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008288os_pipe_impl(PyObject *module)
8289/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008290{
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008292#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008294 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008296#else
8297 int res;
8298#endif
8299
8300#ifdef MS_WINDOWS
8301 attr.nLength = sizeof(attr);
8302 attr.lpSecurityDescriptor = NULL;
8303 attr.bInheritHandle = FALSE;
8304
8305 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008306 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008307 ok = CreatePipe(&read, &write, &attr, 0);
8308 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008309 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8310 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008311 if (fds[0] == -1 || fds[1] == -1) {
8312 CloseHandle(read);
8313 CloseHandle(write);
8314 ok = 0;
8315 }
8316 }
Steve Dowerc3630612016-11-19 18:41:16 -08008317 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008318 Py_END_ALLOW_THREADS
8319
Victor Stinner8c62be82010-05-06 00:08:46 +00008320 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008321 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008322#else
8323
8324#ifdef HAVE_PIPE2
8325 Py_BEGIN_ALLOW_THREADS
8326 res = pipe2(fds, O_CLOEXEC);
8327 Py_END_ALLOW_THREADS
8328
8329 if (res != 0 && errno == ENOSYS)
8330 {
8331#endif
8332 Py_BEGIN_ALLOW_THREADS
8333 res = pipe(fds);
8334 Py_END_ALLOW_THREADS
8335
8336 if (res == 0) {
8337 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8338 close(fds[0]);
8339 close(fds[1]);
8340 return NULL;
8341 }
8342 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8343 close(fds[0]);
8344 close(fds[1]);
8345 return NULL;
8346 }
8347 }
8348#ifdef HAVE_PIPE2
8349 }
8350#endif
8351
8352 if (res != 0)
8353 return PyErr_SetFromErrno(PyExc_OSError);
8354#endif /* !MS_WINDOWS */
8355 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008356}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008357#endif /* HAVE_PIPE */
8358
Larry Hastings2f936352014-08-05 14:04:04 +10008359
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008360#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008361/*[clinic input]
8362os.pipe2
8363
8364 flags: int
8365 /
8366
8367Create a pipe with flags set atomically.
8368
8369Returns a tuple of two file descriptors:
8370 (read_fd, write_fd)
8371
8372flags can be constructed by ORing together one or more of these values:
8373O_NONBLOCK, O_CLOEXEC.
8374[clinic start generated code]*/
8375
Larry Hastings2f936352014-08-05 14:04:04 +10008376static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008377os_pipe2_impl(PyObject *module, int flags)
8378/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008379{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008380 int fds[2];
8381 int res;
8382
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008383 res = pipe2(fds, flags);
8384 if (res != 0)
8385 return posix_error();
8386 return Py_BuildValue("(ii)", fds[0], fds[1]);
8387}
8388#endif /* HAVE_PIPE2 */
8389
Larry Hastings2f936352014-08-05 14:04:04 +10008390
Ross Lagerwall7807c352011-03-17 20:20:30 +02008391#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008392/*[clinic input]
8393os.writev -> Py_ssize_t
8394 fd: int
8395 buffers: object
8396 /
8397
8398Iterate over buffers, and write the contents of each to a file descriptor.
8399
8400Returns the total number of bytes written.
8401buffers must be a sequence of bytes-like objects.
8402[clinic start generated code]*/
8403
Larry Hastings2f936352014-08-05 14:04:04 +10008404static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008405os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8406/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008407{
8408 int cnt;
8409 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008410 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008411 struct iovec *iov;
8412 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008413
8414 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008415 PyErr_SetString(PyExc_TypeError,
8416 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008417 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008418 }
Larry Hastings2f936352014-08-05 14:04:04 +10008419 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008420
Larry Hastings2f936352014-08-05 14:04:04 +10008421 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8422 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008423 }
8424
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008425 do {
8426 Py_BEGIN_ALLOW_THREADS
8427 result = writev(fd, iov, cnt);
8428 Py_END_ALLOW_THREADS
8429 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008430
8431 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008432 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008433 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008434
Georg Brandl306336b2012-06-24 12:55:33 +02008435 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008436}
Larry Hastings2f936352014-08-05 14:04:04 +10008437#endif /* HAVE_WRITEV */
8438
8439
8440#ifdef HAVE_PWRITE
8441/*[clinic input]
8442os.pwrite -> Py_ssize_t
8443
8444 fd: int
8445 buffer: Py_buffer
8446 offset: Py_off_t
8447 /
8448
8449Write bytes to a file descriptor starting at a particular offset.
8450
8451Write buffer to fd, starting at offset bytes from the beginning of
8452the file. Returns the number of bytes writte. Does not change the
8453current file offset.
8454[clinic start generated code]*/
8455
Larry Hastings2f936352014-08-05 14:04:04 +10008456static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008457os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8458/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008459{
8460 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008461 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008462
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008463 do {
8464 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008465 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008466 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008467 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008468 Py_END_ALLOW_THREADS
8469 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008470
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008471 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008472 posix_error();
8473 return size;
8474}
8475#endif /* HAVE_PWRITE */
8476
8477
8478#ifdef HAVE_MKFIFO
8479/*[clinic input]
8480os.mkfifo
8481
8482 path: path_t
8483 mode: int=0o666
8484 *
8485 dir_fd: dir_fd(requires='mkfifoat')=None
8486
8487Create a "fifo" (a POSIX named pipe).
8488
8489If dir_fd is not None, it should be a file descriptor open to a directory,
8490 and path should be relative; path will then be relative to that directory.
8491dir_fd may not be implemented on your platform.
8492 If it is unavailable, using it will raise a NotImplementedError.
8493[clinic start generated code]*/
8494
Larry Hastings2f936352014-08-05 14:04:04 +10008495static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008496os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8497/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008498{
8499 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008500 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008501
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008502 do {
8503 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008504#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008505 if (dir_fd != DEFAULT_DIR_FD)
8506 result = mkfifoat(dir_fd, path->narrow, mode);
8507 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008508#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008509 result = mkfifo(path->narrow, mode);
8510 Py_END_ALLOW_THREADS
8511 } while (result != 0 && errno == EINTR &&
8512 !(async_err = PyErr_CheckSignals()));
8513 if (result != 0)
8514 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008515
8516 Py_RETURN_NONE;
8517}
8518#endif /* HAVE_MKFIFO */
8519
8520
8521#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8522/*[clinic input]
8523os.mknod
8524
8525 path: path_t
8526 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008527 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008528 *
8529 dir_fd: dir_fd(requires='mknodat')=None
8530
8531Create a node in the file system.
8532
8533Create a node in the file system (file, device special file or named pipe)
8534at path. mode specifies both the permissions to use and the
8535type of node to be created, being combined (bitwise OR) with one of
8536S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8537device defines the newly created device special file (probably using
8538os.makedev()). Otherwise device is ignored.
8539
8540If dir_fd is not None, it should be a file descriptor open to a directory,
8541 and path should be relative; path will then be relative to that directory.
8542dir_fd may not be implemented on your platform.
8543 If it is unavailable, using it will raise a NotImplementedError.
8544[clinic start generated code]*/
8545
Larry Hastings2f936352014-08-05 14:04:04 +10008546static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008547os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008548 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008549/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008550{
8551 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008552 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008553
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008554 do {
8555 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008556#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008557 if (dir_fd != DEFAULT_DIR_FD)
8558 result = mknodat(dir_fd, path->narrow, mode, device);
8559 else
Larry Hastings2f936352014-08-05 14:04:04 +10008560#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008561 result = mknod(path->narrow, mode, device);
8562 Py_END_ALLOW_THREADS
8563 } while (result != 0 && errno == EINTR &&
8564 !(async_err = PyErr_CheckSignals()));
8565 if (result != 0)
8566 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008567
8568 Py_RETURN_NONE;
8569}
8570#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8571
8572
8573#ifdef HAVE_DEVICE_MACROS
8574/*[clinic input]
8575os.major -> unsigned_int
8576
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008577 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008578 /
8579
8580Extracts a device major number from a raw device number.
8581[clinic start generated code]*/
8582
Larry Hastings2f936352014-08-05 14:04:04 +10008583static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008584os_major_impl(PyObject *module, dev_t device)
8585/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008586{
8587 return major(device);
8588}
8589
8590
8591/*[clinic input]
8592os.minor -> unsigned_int
8593
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008594 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008595 /
8596
8597Extracts a device minor number from a raw device number.
8598[clinic start generated code]*/
8599
Larry Hastings2f936352014-08-05 14:04:04 +10008600static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008601os_minor_impl(PyObject *module, dev_t device)
8602/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008603{
8604 return minor(device);
8605}
8606
8607
8608/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008609os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008610
8611 major: int
8612 minor: int
8613 /
8614
8615Composes a raw device number from the major and minor device numbers.
8616[clinic start generated code]*/
8617
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008618static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008619os_makedev_impl(PyObject *module, int major, int minor)
8620/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008621{
8622 return makedev(major, minor);
8623}
8624#endif /* HAVE_DEVICE_MACROS */
8625
8626
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008627#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008628/*[clinic input]
8629os.ftruncate
8630
8631 fd: int
8632 length: Py_off_t
8633 /
8634
8635Truncate a file, specified by file descriptor, to a specific length.
8636[clinic start generated code]*/
8637
Larry Hastings2f936352014-08-05 14:04:04 +10008638static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008639os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8640/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008641{
8642 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008643 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008644
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008645 do {
8646 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008647 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008648#ifdef MS_WINDOWS
8649 result = _chsize_s(fd, length);
8650#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008651 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008652#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008653 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008654 Py_END_ALLOW_THREADS
8655 } while (result != 0 && errno == EINTR &&
8656 !(async_err = PyErr_CheckSignals()));
8657 if (result != 0)
8658 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008659 Py_RETURN_NONE;
8660}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008661#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008662
8663
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008664#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008665/*[clinic input]
8666os.truncate
8667 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8668 length: Py_off_t
8669
8670Truncate a file, specified by path, to a specific length.
8671
8672On some platforms, path may also be specified as an open file descriptor.
8673 If this functionality is unavailable, using it raises an exception.
8674[clinic start generated code]*/
8675
Larry Hastings2f936352014-08-05 14:04:04 +10008676static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008677os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8678/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008679{
8680 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008681#ifdef MS_WINDOWS
8682 int fd;
8683#endif
8684
8685 if (path->fd != -1)
8686 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008687
8688 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008689 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008690#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008691 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008692 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008693 result = -1;
8694 else {
8695 result = _chsize_s(fd, length);
8696 close(fd);
8697 if (result < 0)
8698 errno = result;
8699 }
8700#else
8701 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008702#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008703 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008704 Py_END_ALLOW_THREADS
8705 if (result < 0)
8706 return path_error(path);
8707
8708 Py_RETURN_NONE;
8709}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008710#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008711
Ross Lagerwall7807c352011-03-17 20:20:30 +02008712
Victor Stinnerd6b17692014-09-30 12:20:05 +02008713/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8714 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8715 defined, which is the case in Python on AIX. AIX bug report:
8716 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8717#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8718# define POSIX_FADVISE_AIX_BUG
8719#endif
8720
Victor Stinnerec39e262014-09-30 12:35:58 +02008721
Victor Stinnerd6b17692014-09-30 12:20:05 +02008722#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008723/*[clinic input]
8724os.posix_fallocate
8725
8726 fd: int
8727 offset: Py_off_t
8728 length: Py_off_t
8729 /
8730
8731Ensure a file has allocated at least a particular number of bytes on disk.
8732
8733Ensure that the file specified by fd encompasses a range of bytes
8734starting at offset bytes from the beginning and continuing for length bytes.
8735[clinic start generated code]*/
8736
Larry Hastings2f936352014-08-05 14:04:04 +10008737static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008738os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008739 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008740/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008741{
8742 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008743 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008744
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008745 do {
8746 Py_BEGIN_ALLOW_THREADS
8747 result = posix_fallocate(fd, offset, length);
8748 Py_END_ALLOW_THREADS
8749 } while (result != 0 && errno == EINTR &&
8750 !(async_err = PyErr_CheckSignals()));
8751 if (result != 0)
8752 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008753 Py_RETURN_NONE;
8754}
Victor Stinnerec39e262014-09-30 12:35:58 +02008755#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008756
Ross Lagerwall7807c352011-03-17 20:20:30 +02008757
Victor Stinnerd6b17692014-09-30 12:20:05 +02008758#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008759/*[clinic input]
8760os.posix_fadvise
8761
8762 fd: int
8763 offset: Py_off_t
8764 length: Py_off_t
8765 advice: int
8766 /
8767
8768Announce an intention to access data in a specific pattern.
8769
8770Announce an intention to access data in a specific pattern, thus allowing
8771the kernel to make optimizations.
8772The advice applies to the region of the file specified by fd starting at
8773offset and continuing for length bytes.
8774advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8775POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8776POSIX_FADV_DONTNEED.
8777[clinic start generated code]*/
8778
Larry Hastings2f936352014-08-05 14:04:04 +10008779static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008780os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008781 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008782/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008783{
8784 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008785 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008786
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008787 do {
8788 Py_BEGIN_ALLOW_THREADS
8789 result = posix_fadvise(fd, offset, length, advice);
8790 Py_END_ALLOW_THREADS
8791 } while (result != 0 && errno == EINTR &&
8792 !(async_err = PyErr_CheckSignals()));
8793 if (result != 0)
8794 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008795 Py_RETURN_NONE;
8796}
Victor Stinnerec39e262014-09-30 12:35:58 +02008797#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008798
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008799#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008800
Fred Drake762e2061999-08-26 17:23:54 +00008801/* Save putenv() parameters as values here, so we can collect them when they
8802 * get re-set with another call for the same key. */
8803static PyObject *posix_putenv_garbage;
8804
Larry Hastings2f936352014-08-05 14:04:04 +10008805static void
8806posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008807{
Larry Hastings2f936352014-08-05 14:04:04 +10008808 /* Install the first arg and newstr in posix_putenv_garbage;
8809 * this will cause previous value to be collected. This has to
8810 * happen after the real putenv() call because the old value
8811 * was still accessible until then. */
8812 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8813 /* really not much we can do; just leak */
8814 PyErr_Clear();
8815 else
8816 Py_DECREF(value);
8817}
8818
8819
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008820#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008821/*[clinic input]
8822os.putenv
8823
8824 name: unicode
8825 value: unicode
8826 /
8827
8828Change or add an environment variable.
8829[clinic start generated code]*/
8830
Larry Hastings2f936352014-08-05 14:04:04 +10008831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008832os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8833/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008834{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008835 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008836
8837 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8838 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008839 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008840 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008841 }
Larry Hastings2f936352014-08-05 14:04:04 +10008842 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008843 PyErr_Format(PyExc_ValueError,
8844 "the environment variable is longer than %u characters",
8845 _MAX_ENV);
8846 goto error;
8847 }
8848
Larry Hastings2f936352014-08-05 14:04:04 +10008849 env = PyUnicode_AsUnicode(unicode);
8850 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008851 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008852 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008854 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008856
Larry Hastings2f936352014-08-05 14:04:04 +10008857 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008858 Py_RETURN_NONE;
8859
8860error:
Larry Hastings2f936352014-08-05 14:04:04 +10008861 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008862 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008863}
Larry Hastings2f936352014-08-05 14:04:04 +10008864#else /* MS_WINDOWS */
8865/*[clinic input]
8866os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008867
Larry Hastings2f936352014-08-05 14:04:04 +10008868 name: FSConverter
8869 value: FSConverter
8870 /
8871
8872Change or add an environment variable.
8873[clinic start generated code]*/
8874
Larry Hastings2f936352014-08-05 14:04:04 +10008875static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008876os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8877/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008878{
8879 PyObject *bytes = NULL;
8880 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008881 const char *name_string = PyBytes_AsString(name);
8882 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008883
8884 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8885 if (bytes == NULL) {
8886 PyErr_NoMemory();
8887 return NULL;
8888 }
8889
8890 env = PyBytes_AS_STRING(bytes);
8891 if (putenv(env)) {
8892 Py_DECREF(bytes);
8893 return posix_error();
8894 }
8895
8896 posix_putenv_garbage_setitem(name, bytes);
8897 Py_RETURN_NONE;
8898}
8899#endif /* MS_WINDOWS */
8900#endif /* HAVE_PUTENV */
8901
8902
8903#ifdef HAVE_UNSETENV
8904/*[clinic input]
8905os.unsetenv
8906 name: FSConverter
8907 /
8908
8909Delete an environment variable.
8910[clinic start generated code]*/
8911
Larry Hastings2f936352014-08-05 14:04:04 +10008912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008913os_unsetenv_impl(PyObject *module, PyObject *name)
8914/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008915{
Victor Stinner984890f2011-11-24 13:53:38 +01008916#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008917 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008918#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008919
Victor Stinner984890f2011-11-24 13:53:38 +01008920#ifdef HAVE_BROKEN_UNSETENV
8921 unsetenv(PyBytes_AS_STRING(name));
8922#else
Victor Stinner65170952011-11-22 22:16:17 +01008923 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008924 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008925 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008926#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008927
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 /* Remove the key from posix_putenv_garbage;
8929 * this will cause it to be collected. This has to
8930 * happen after the real unsetenv() call because the
8931 * old value was still accessible until then.
8932 */
Victor Stinner65170952011-11-22 22:16:17 +01008933 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 /* really not much we can do; just leak */
8935 PyErr_Clear();
8936 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008937 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008938}
Larry Hastings2f936352014-08-05 14:04:04 +10008939#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008940
Larry Hastings2f936352014-08-05 14:04:04 +10008941
8942/*[clinic input]
8943os.strerror
8944
8945 code: int
8946 /
8947
8948Translate an error code to a message string.
8949[clinic start generated code]*/
8950
Larry Hastings2f936352014-08-05 14:04:04 +10008951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008952os_strerror_impl(PyObject *module, int code)
8953/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008954{
8955 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008956 if (message == NULL) {
8957 PyErr_SetString(PyExc_ValueError,
8958 "strerror() argument out of range");
8959 return NULL;
8960 }
Victor Stinner1b579672011-12-17 05:47:23 +01008961 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008962}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008963
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008964
Guido van Rossumc9641791998-08-04 15:26:23 +00008965#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008966#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008967/*[clinic input]
8968os.WCOREDUMP -> bool
8969
8970 status: int
8971 /
8972
8973Return True if the process returning status was dumped to a core file.
8974[clinic start generated code]*/
8975
Larry Hastings2f936352014-08-05 14:04:04 +10008976static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008977os_WCOREDUMP_impl(PyObject *module, int status)
8978/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008979{
8980 WAIT_TYPE wait_status;
8981 WAIT_STATUS_INT(wait_status) = status;
8982 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008983}
8984#endif /* WCOREDUMP */
8985
Larry Hastings2f936352014-08-05 14:04:04 +10008986
Fred Drake106c1a02002-04-23 15:58:02 +00008987#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008988/*[clinic input]
8989os.WIFCONTINUED -> bool
8990
8991 status: int
8992
8993Return True if a particular process was continued from a job control stop.
8994
8995Return True if the process returning status was continued from a
8996job control stop.
8997[clinic start generated code]*/
8998
Larry Hastings2f936352014-08-05 14:04:04 +10008999static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009000os_WIFCONTINUED_impl(PyObject *module, int status)
9001/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009002{
9003 WAIT_TYPE wait_status;
9004 WAIT_STATUS_INT(wait_status) = status;
9005 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009006}
9007#endif /* WIFCONTINUED */
9008
Larry Hastings2f936352014-08-05 14:04:04 +10009009
Guido van Rossumc9641791998-08-04 15:26:23 +00009010#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009011/*[clinic input]
9012os.WIFSTOPPED -> bool
9013
9014 status: int
9015
9016Return True if the process returning status was stopped.
9017[clinic start generated code]*/
9018
Larry Hastings2f936352014-08-05 14:04:04 +10009019static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009020os_WIFSTOPPED_impl(PyObject *module, int status)
9021/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009022{
9023 WAIT_TYPE wait_status;
9024 WAIT_STATUS_INT(wait_status) = status;
9025 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009026}
9027#endif /* WIFSTOPPED */
9028
Larry Hastings2f936352014-08-05 14:04:04 +10009029
Guido van Rossumc9641791998-08-04 15:26:23 +00009030#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009031/*[clinic input]
9032os.WIFSIGNALED -> bool
9033
9034 status: int
9035
9036Return True if the process returning status was terminated by a signal.
9037[clinic start generated code]*/
9038
Larry Hastings2f936352014-08-05 14:04:04 +10009039static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009040os_WIFSIGNALED_impl(PyObject *module, int status)
9041/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009042{
9043 WAIT_TYPE wait_status;
9044 WAIT_STATUS_INT(wait_status) = status;
9045 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009046}
9047#endif /* WIFSIGNALED */
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049
Guido van Rossumc9641791998-08-04 15:26:23 +00009050#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009051/*[clinic input]
9052os.WIFEXITED -> bool
9053
9054 status: int
9055
9056Return True if the process returning status exited via the exit() system call.
9057[clinic start generated code]*/
9058
Larry Hastings2f936352014-08-05 14:04:04 +10009059static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009060os_WIFEXITED_impl(PyObject *module, int status)
9061/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009062{
9063 WAIT_TYPE wait_status;
9064 WAIT_STATUS_INT(wait_status) = status;
9065 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009066}
9067#endif /* WIFEXITED */
9068
Larry Hastings2f936352014-08-05 14:04:04 +10009069
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009070#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009071/*[clinic input]
9072os.WEXITSTATUS -> int
9073
9074 status: int
9075
9076Return the process return code from status.
9077[clinic start generated code]*/
9078
Larry Hastings2f936352014-08-05 14:04:04 +10009079static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009080os_WEXITSTATUS_impl(PyObject *module, int status)
9081/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009082{
9083 WAIT_TYPE wait_status;
9084 WAIT_STATUS_INT(wait_status) = status;
9085 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009086}
9087#endif /* WEXITSTATUS */
9088
Larry Hastings2f936352014-08-05 14:04:04 +10009089
Guido van Rossumc9641791998-08-04 15:26:23 +00009090#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009091/*[clinic input]
9092os.WTERMSIG -> int
9093
9094 status: int
9095
9096Return the signal that terminated the process that provided the status value.
9097[clinic start generated code]*/
9098
Larry Hastings2f936352014-08-05 14:04:04 +10009099static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009100os_WTERMSIG_impl(PyObject *module, int status)
9101/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009102{
9103 WAIT_TYPE wait_status;
9104 WAIT_STATUS_INT(wait_status) = status;
9105 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009106}
9107#endif /* WTERMSIG */
9108
Larry Hastings2f936352014-08-05 14:04:04 +10009109
Guido van Rossumc9641791998-08-04 15:26:23 +00009110#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009111/*[clinic input]
9112os.WSTOPSIG -> int
9113
9114 status: int
9115
9116Return the signal that stopped the process that provided the status value.
9117[clinic start generated code]*/
9118
Larry Hastings2f936352014-08-05 14:04:04 +10009119static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009120os_WSTOPSIG_impl(PyObject *module, int status)
9121/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009122{
9123 WAIT_TYPE wait_status;
9124 WAIT_STATUS_INT(wait_status) = status;
9125 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009126}
9127#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009128#endif /* HAVE_SYS_WAIT_H */
9129
9130
Thomas Wouters477c8d52006-05-27 19:21:47 +00009131#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009132#ifdef _SCO_DS
9133/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9134 needed definitions in sys/statvfs.h */
9135#define _SVID3
9136#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009137#include <sys/statvfs.h>
9138
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009139static PyObject*
9140_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9142 if (v == NULL)
9143 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009144
9145#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9147 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9148 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9149 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9150 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9151 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9152 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9153 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9154 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9155 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009156#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009157 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9158 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9159 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009160 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009162 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009163 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009164 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009166 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009168 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009169 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009170 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9172 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009173#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009174 if (PyErr_Occurred()) {
9175 Py_DECREF(v);
9176 return NULL;
9177 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009178
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009180}
9181
Larry Hastings2f936352014-08-05 14:04:04 +10009182
9183/*[clinic input]
9184os.fstatvfs
9185 fd: int
9186 /
9187
9188Perform an fstatvfs system call on the given fd.
9189
9190Equivalent to statvfs(fd).
9191[clinic start generated code]*/
9192
Larry Hastings2f936352014-08-05 14:04:04 +10009193static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009194os_fstatvfs_impl(PyObject *module, int fd)
9195/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009196{
9197 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009198 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009200
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009201 do {
9202 Py_BEGIN_ALLOW_THREADS
9203 result = fstatvfs(fd, &st);
9204 Py_END_ALLOW_THREADS
9205 } while (result != 0 && errno == EINTR &&
9206 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009207 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009208 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009209
Victor Stinner8c62be82010-05-06 00:08:46 +00009210 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009211}
Larry Hastings2f936352014-08-05 14:04:04 +10009212#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009213
9214
Thomas Wouters477c8d52006-05-27 19:21:47 +00009215#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009216#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009217/*[clinic input]
9218os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009219
Larry Hastings2f936352014-08-05 14:04:04 +10009220 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9221
9222Perform a statvfs system call on the given path.
9223
9224path may always be specified as a string.
9225On some platforms, path may also be specified as an open file descriptor.
9226 If this functionality is unavailable, using it raises an exception.
9227[clinic start generated code]*/
9228
Larry Hastings2f936352014-08-05 14:04:04 +10009229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009230os_statvfs_impl(PyObject *module, path_t *path)
9231/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009232{
9233 int result;
9234 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009235
9236 Py_BEGIN_ALLOW_THREADS
9237#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009238 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009239#ifdef __APPLE__
9240 /* handle weak-linking on Mac OS X 10.3 */
9241 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009242 fd_specified("statvfs", path->fd);
9243 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009244 }
9245#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009246 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009247 }
9248 else
9249#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009250 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009251 Py_END_ALLOW_THREADS
9252
9253 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009254 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009255 }
9256
Larry Hastings2f936352014-08-05 14:04:04 +10009257 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009258}
Larry Hastings2f936352014-08-05 14:04:04 +10009259#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9260
Guido van Rossum94f6f721999-01-06 18:42:14 +00009261
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009262#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009263/*[clinic input]
9264os._getdiskusage
9265
9266 path: Py_UNICODE
9267
9268Return disk usage statistics about the given path as a (total, free) tuple.
9269[clinic start generated code]*/
9270
Larry Hastings2f936352014-08-05 14:04:04 +10009271static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009272os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9273/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009274{
9275 BOOL retval;
9276 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009277
9278 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009279 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009280 Py_END_ALLOW_THREADS
9281 if (retval == 0)
9282 return PyErr_SetFromWindowsErr(0);
9283
9284 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9285}
Larry Hastings2f936352014-08-05 14:04:04 +10009286#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009287
9288
Fred Drakec9680921999-12-13 16:37:25 +00009289/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9290 * It maps strings representing configuration variable names to
9291 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009292 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009293 * rarely-used constants. There are three separate tables that use
9294 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009295 *
9296 * This code is always included, even if none of the interfaces that
9297 * need it are included. The #if hackery needed to avoid it would be
9298 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009299 */
9300struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009301 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009302 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009303};
9304
Fred Drake12c6e2d1999-12-14 21:25:03 +00009305static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009306conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009307 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009308{
Christian Heimes217cfd12007-12-02 14:31:20 +00009309 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009310 int value = _PyLong_AsInt(arg);
9311 if (value == -1 && PyErr_Occurred())
9312 return 0;
9313 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009314 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009315 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009316 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009317 /* look up the value in the table using a binary search */
9318 size_t lo = 0;
9319 size_t mid;
9320 size_t hi = tablesize;
9321 int cmp;
9322 const char *confname;
9323 if (!PyUnicode_Check(arg)) {
9324 PyErr_SetString(PyExc_TypeError,
9325 "configuration names must be strings or integers");
9326 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009328 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009329 if (confname == NULL)
9330 return 0;
9331 while (lo < hi) {
9332 mid = (lo + hi) / 2;
9333 cmp = strcmp(confname, table[mid].name);
9334 if (cmp < 0)
9335 hi = mid;
9336 else if (cmp > 0)
9337 lo = mid + 1;
9338 else {
9339 *valuep = table[mid].value;
9340 return 1;
9341 }
9342 }
9343 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9344 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009346}
9347
9348
9349#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9350static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009351#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009353#endif
9354#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009356#endif
Fred Drakec9680921999-12-13 16:37:25 +00009357#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009359#endif
9360#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009362#endif
9363#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009402#ifdef _PC_ACL_ENABLED
9403 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9404#endif
9405#ifdef _PC_MIN_HOLE_SIZE
9406 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9407#endif
9408#ifdef _PC_ALLOC_SIZE_MIN
9409 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9410#endif
9411#ifdef _PC_REC_INCR_XFER_SIZE
9412 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9413#endif
9414#ifdef _PC_REC_MAX_XFER_SIZE
9415 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9416#endif
9417#ifdef _PC_REC_MIN_XFER_SIZE
9418 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9419#endif
9420#ifdef _PC_REC_XFER_ALIGN
9421 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9422#endif
9423#ifdef _PC_SYMLINK_MAX
9424 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9425#endif
9426#ifdef _PC_XATTR_ENABLED
9427 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9428#endif
9429#ifdef _PC_XATTR_EXISTS
9430 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9431#endif
9432#ifdef _PC_TIMESTAMP_RESOLUTION
9433 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9434#endif
Fred Drakec9680921999-12-13 16:37:25 +00009435};
9436
Fred Drakec9680921999-12-13 16:37:25 +00009437static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009438conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009439{
9440 return conv_confname(arg, valuep, posix_constants_pathconf,
9441 sizeof(posix_constants_pathconf)
9442 / sizeof(struct constdef));
9443}
9444#endif
9445
Larry Hastings2f936352014-08-05 14:04:04 +10009446
Fred Drakec9680921999-12-13 16:37:25 +00009447#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009448/*[clinic input]
9449os.fpathconf -> long
9450
9451 fd: int
9452 name: path_confname
9453 /
9454
9455Return the configuration limit name for the file descriptor fd.
9456
9457If there is no limit, return -1.
9458[clinic start generated code]*/
9459
Larry Hastings2f936352014-08-05 14:04:04 +10009460static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009461os_fpathconf_impl(PyObject *module, int fd, int name)
9462/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009463{
9464 long limit;
9465
9466 errno = 0;
9467 limit = fpathconf(fd, name);
9468 if (limit == -1 && errno != 0)
9469 posix_error();
9470
9471 return limit;
9472}
9473#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009474
9475
9476#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009477/*[clinic input]
9478os.pathconf -> long
9479 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9480 name: path_confname
9481
9482Return the configuration limit name for the file or directory path.
9483
9484If there is no limit, return -1.
9485On some platforms, path may also be specified as an open file descriptor.
9486 If this functionality is unavailable, using it raises an exception.
9487[clinic start generated code]*/
9488
Larry Hastings2f936352014-08-05 14:04:04 +10009489static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009490os_pathconf_impl(PyObject *module, path_t *path, int name)
9491/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009492{
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009494
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009496#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009497 if (path->fd != -1)
9498 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009499 else
9500#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009501 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 if (limit == -1 && errno != 0) {
9503 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009504 /* could be a path or name problem */
9505 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009506 else
Larry Hastings2f936352014-08-05 14:04:04 +10009507 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 }
Larry Hastings2f936352014-08-05 14:04:04 +10009509
9510 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009511}
Larry Hastings2f936352014-08-05 14:04:04 +10009512#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009513
9514#ifdef HAVE_CONFSTR
9515static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009516#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009518#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009519#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009521#endif
9522#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009524#endif
Fred Draked86ed291999-12-15 15:34:33 +00009525#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009527#endif
9528#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009530#endif
9531#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009533#endif
9534#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
Fred Drakec9680921999-12-13 16:37:25 +00009537#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
Fred Draked86ed291999-12-15 15:34:33 +00009561#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009563#endif
Fred Drakec9680921999-12-13 16:37:25 +00009564#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
Fred Draked86ed291999-12-15 15:34:33 +00009567#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009569#endif
9570#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009572#endif
9573#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009575#endif
9576#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009578#endif
Fred Drakec9680921999-12-13 16:37:25 +00009579#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
Fred Draked86ed291999-12-15 15:34:33 +00009627#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009629#endif
9630#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009632#endif
9633#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009635#endif
9636#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009638#endif
9639#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
9642#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009644#endif
9645#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
9648#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
9654#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
9657#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
9663#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009665#endif
Fred Drakec9680921999-12-13 16:37:25 +00009666};
9667
9668static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009669conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009670{
9671 return conv_confname(arg, valuep, posix_constants_confstr,
9672 sizeof(posix_constants_confstr)
9673 / sizeof(struct constdef));
9674}
9675
Larry Hastings2f936352014-08-05 14:04:04 +10009676
9677/*[clinic input]
9678os.confstr
9679
9680 name: confstr_confname
9681 /
9682
9683Return a string-valued system configuration variable.
9684[clinic start generated code]*/
9685
Larry Hastings2f936352014-08-05 14:04:04 +10009686static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009687os_confstr_impl(PyObject *module, int name)
9688/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009689{
9690 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009691 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009692 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009693
Victor Stinnercb043522010-09-10 23:49:04 +00009694 errno = 0;
9695 len = confstr(name, buffer, sizeof(buffer));
9696 if (len == 0) {
9697 if (errno) {
9698 posix_error();
9699 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009700 }
9701 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009702 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009703 }
9704 }
Victor Stinnercb043522010-09-10 23:49:04 +00009705
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009706 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009707 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009708 char *buf = PyMem_Malloc(len);
9709 if (buf == NULL)
9710 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009711 len2 = confstr(name, buf, len);
9712 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009713 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009714 PyMem_Free(buf);
9715 }
9716 else
9717 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009718 return result;
9719}
Larry Hastings2f936352014-08-05 14:04:04 +10009720#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009721
9722
9723#ifdef HAVE_SYSCONF
9724static struct constdef posix_constants_sysconf[] = {
9725#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
Fred Draked86ed291999-12-15 15:34:33 +00009755#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
Fred Drakec9680921999-12-13 16:37:25 +00009761#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
Fred Draked86ed291999-12-15 15:34:33 +00009779#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009781#endif
Fred Drakec9680921999-12-13 16:37:25 +00009782#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
Fred Draked86ed291999-12-15 15:34:33 +00009797#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
Fred Drakec9680921999-12-13 16:37:25 +00009800#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
Fred Draked86ed291999-12-15 15:34:33 +00009869#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009871#endif
Fred Drakec9680921999-12-13 16:37:25 +00009872#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
Fred Draked86ed291999-12-15 15:34:33 +00009881#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009883#endif
Fred Drakec9680921999-12-13 16:37:25 +00009884#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
Fred Draked86ed291999-12-15 15:34:33 +00009887#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009889#endif
9890#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009892#endif
Fred Drakec9680921999-12-13 16:37:25 +00009893#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
Fred Draked86ed291999-12-15 15:34:33 +00009905#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009907#endif
Fred Drakec9680921999-12-13 16:37:25 +00009908#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
Fred Draked86ed291999-12-15 15:34:33 +00009929#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009931#endif
Fred Drakec9680921999-12-13 16:37:25 +00009932#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
Fred Draked86ed291999-12-15 15:34:33 +00009938#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009940#endif
Fred Drakec9680921999-12-13 16:37:25 +00009941#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
Fred Draked86ed291999-12-15 15:34:33 +00009968#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009970#endif
9971#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
Fred Drakec9680921999-12-13 16:37:25 +00009974#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
Fred Draked86ed291999-12-15 15:34:33 +000010079#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010081#endif
Fred Drakec9680921999-12-13 16:37:25 +000010082#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217};
10218
10219static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010220conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010221{
10222 return conv_confname(arg, valuep, posix_constants_sysconf,
10223 sizeof(posix_constants_sysconf)
10224 / sizeof(struct constdef));
10225}
10226
Larry Hastings2f936352014-08-05 14:04:04 +100010227
10228/*[clinic input]
10229os.sysconf -> long
10230 name: sysconf_confname
10231 /
10232
10233Return an integer-valued system configuration variable.
10234[clinic start generated code]*/
10235
Larry Hastings2f936352014-08-05 14:04:04 +100010236static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010237os_sysconf_impl(PyObject *module, int name)
10238/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010239{
10240 long value;
10241
10242 errno = 0;
10243 value = sysconf(name);
10244 if (value == -1 && errno != 0)
10245 posix_error();
10246 return value;
10247}
10248#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010249
10250
Fred Drakebec628d1999-12-15 18:31:10 +000010251/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010252 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010253 * the exported dictionaries that are used to publish information about the
10254 * names available on the host platform.
10255 *
10256 * Sorting the table at runtime ensures that the table is properly ordered
10257 * when used, even for platforms we're not able to test on. It also makes
10258 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010259 */
Fred Drakebec628d1999-12-15 18:31:10 +000010260
10261static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010262cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010263{
10264 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010266 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010268
10269 return strcmp(c1->name, c2->name);
10270}
10271
10272static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010273setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010274 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010275{
Fred Drakebec628d1999-12-15 18:31:10 +000010276 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010277 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010278
10279 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10280 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010281 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010283
Barry Warsaw3155db32000-04-13 15:20:40 +000010284 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 PyObject *o = PyLong_FromLong(table[i].value);
10286 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10287 Py_XDECREF(o);
10288 Py_DECREF(d);
10289 return -1;
10290 }
10291 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010292 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010293 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010294}
10295
Fred Drakebec628d1999-12-15 18:31:10 +000010296/* Return -1 on failure, 0 on success. */
10297static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010298setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010299{
10300#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010301 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010302 sizeof(posix_constants_pathconf)
10303 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010304 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010305 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010306#endif
10307#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010308 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010309 sizeof(posix_constants_confstr)
10310 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010311 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010312 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010313#endif
10314#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010315 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010316 sizeof(posix_constants_sysconf)
10317 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010318 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010319 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010320#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010321 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010322}
Fred Draked86ed291999-12-15 15:34:33 +000010323
10324
Larry Hastings2f936352014-08-05 14:04:04 +100010325/*[clinic input]
10326os.abort
10327
10328Abort the interpreter immediately.
10329
10330This function 'dumps core' or otherwise fails in the hardest way possible
10331on the hosting operating system. This function never returns.
10332[clinic start generated code]*/
10333
Larry Hastings2f936352014-08-05 14:04:04 +100010334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010335os_abort_impl(PyObject *module)
10336/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010337{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010338 abort();
10339 /*NOTREACHED*/
10340 Py_FatalError("abort() called from Python code didn't abort!");
10341 return NULL;
10342}
Fred Drakebec628d1999-12-15 18:31:10 +000010343
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010344#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010345/* Grab ShellExecute dynamically from shell32 */
10346static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010347static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10348 LPCWSTR, INT);
10349static int
10350check_ShellExecute()
10351{
10352 HINSTANCE hShell32;
10353
10354 /* only recheck */
10355 if (-1 == has_ShellExecute) {
10356 Py_BEGIN_ALLOW_THREADS
10357 hShell32 = LoadLibraryW(L"SHELL32");
10358 Py_END_ALLOW_THREADS
10359 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010360 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10361 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010362 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010363 } else {
10364 has_ShellExecute = 0;
10365 }
10366 }
10367 return has_ShellExecute;
10368}
10369
10370
Steve Dowercc16be82016-09-08 10:35:16 -070010371/*[clinic input]
10372os.startfile
10373 filepath: path_t
10374 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010375
Steve Dowercc16be82016-09-08 10:35:16 -070010376startfile(filepath [, operation])
10377
10378Start a file with its associated application.
10379
10380When "operation" is not specified or "open", this acts like
10381double-clicking the file in Explorer, or giving the file name as an
10382argument to the DOS "start" command: the file is opened with whatever
10383application (if any) its extension is associated.
10384When another "operation" is given, it specifies what should be done with
10385the file. A typical operation is "print".
10386
10387startfile returns as soon as the associated application is launched.
10388There is no option to wait for the application to close, and no way
10389to retrieve the application's exit status.
10390
10391The filepath is relative to the current directory. If you want to use
10392an absolute path, make sure the first character is not a slash ("/");
10393the underlying Win32 ShellExecute function doesn't work if it is.
10394[clinic start generated code]*/
10395
10396static PyObject *
10397os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10398/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10399{
10400 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010401
10402 if(!check_ShellExecute()) {
10403 /* If the OS doesn't have ShellExecute, return a
10404 NotImplementedError. */
10405 return PyErr_Format(PyExc_NotImplementedError,
10406 "startfile not available on this platform");
10407 }
10408
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010410 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010411 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 Py_END_ALLOW_THREADS
10413
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010415 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010416 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 }
Steve Dowercc16be82016-09-08 10:35:16 -070010418 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010419}
Larry Hastings2f936352014-08-05 14:04:04 +100010420#endif /* MS_WINDOWS */
10421
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010422
Martin v. Löwis438b5342002-12-27 10:16:42 +000010423#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010424/*[clinic input]
10425os.getloadavg
10426
10427Return average recent system load information.
10428
10429Return the number of processes in the system run queue averaged over
10430the last 1, 5, and 15 minutes as a tuple of three floats.
10431Raises OSError if the load average was unobtainable.
10432[clinic start generated code]*/
10433
Larry Hastings2f936352014-08-05 14:04:04 +100010434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010435os_getloadavg_impl(PyObject *module)
10436/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010437{
10438 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010439 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010440 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10441 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010442 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010443 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010444}
Larry Hastings2f936352014-08-05 14:04:04 +100010445#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010446
Larry Hastings2f936352014-08-05 14:04:04 +100010447
10448/*[clinic input]
10449os.device_encoding
10450 fd: int
10451
10452Return a string describing the encoding of a terminal's file descriptor.
10453
10454The file descriptor must be attached to a terminal.
10455If the device is not a terminal, return None.
10456[clinic start generated code]*/
10457
Larry Hastings2f936352014-08-05 14:04:04 +100010458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010459os_device_encoding_impl(PyObject *module, int fd)
10460/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010461{
Brett Cannonefb00c02012-02-29 18:31:31 -050010462 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010463}
10464
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010465
Larry Hastings2f936352014-08-05 14:04:04 +100010466#ifdef HAVE_SETRESUID
10467/*[clinic input]
10468os.setresuid
10469
10470 ruid: uid_t
10471 euid: uid_t
10472 suid: uid_t
10473 /
10474
10475Set the current process's real, effective, and saved user ids.
10476[clinic start generated code]*/
10477
Larry Hastings2f936352014-08-05 14:04:04 +100010478static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010479os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10480/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010481{
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 if (setresuid(ruid, euid, suid) < 0)
10483 return posix_error();
10484 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010485}
Larry Hastings2f936352014-08-05 14:04:04 +100010486#endif /* HAVE_SETRESUID */
10487
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010488
10489#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010490/*[clinic input]
10491os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010492
Larry Hastings2f936352014-08-05 14:04:04 +100010493 rgid: gid_t
10494 egid: gid_t
10495 sgid: gid_t
10496 /
10497
10498Set the current process's real, effective, and saved group ids.
10499[clinic start generated code]*/
10500
Larry Hastings2f936352014-08-05 14:04:04 +100010501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010502os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10503/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010504{
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 if (setresgid(rgid, egid, sgid) < 0)
10506 return posix_error();
10507 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010508}
Larry Hastings2f936352014-08-05 14:04:04 +100010509#endif /* HAVE_SETRESGID */
10510
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010511
10512#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010513/*[clinic input]
10514os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010515
Larry Hastings2f936352014-08-05 14:04:04 +100010516Return a tuple of the current process's real, effective, and saved user ids.
10517[clinic start generated code]*/
10518
Larry Hastings2f936352014-08-05 14:04:04 +100010519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010520os_getresuid_impl(PyObject *module)
10521/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010522{
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 if (getresuid(&ruid, &euid, &suid) < 0)
10525 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010526 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10527 _PyLong_FromUid(euid),
10528 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010529}
Larry Hastings2f936352014-08-05 14:04:04 +100010530#endif /* HAVE_GETRESUID */
10531
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010532
10533#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010534/*[clinic input]
10535os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010536
Larry Hastings2f936352014-08-05 14:04:04 +100010537Return a tuple of the current process's real, effective, and saved group ids.
10538[clinic start generated code]*/
10539
Larry Hastings2f936352014-08-05 14:04:04 +100010540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010541os_getresgid_impl(PyObject *module)
10542/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010543{
10544 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 if (getresgid(&rgid, &egid, &sgid) < 0)
10546 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010547 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10548 _PyLong_FromGid(egid),
10549 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010550}
Larry Hastings2f936352014-08-05 14:04:04 +100010551#endif /* HAVE_GETRESGID */
10552
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010553
Benjamin Peterson9428d532011-09-14 11:45:52 -040010554#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010555/*[clinic input]
10556os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010557
Larry Hastings2f936352014-08-05 14:04:04 +100010558 path: path_t(allow_fd=True)
10559 attribute: path_t
10560 *
10561 follow_symlinks: bool = True
10562
10563Return the value of extended attribute attribute on path.
10564
10565path may be either a string or an open file descriptor.
10566If follow_symlinks is False, and the last element of the path is a symbolic
10567 link, getxattr will examine the symbolic link itself instead of the file
10568 the link points to.
10569
10570[clinic start generated code]*/
10571
Larry Hastings2f936352014-08-05 14:04:04 +100010572static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010573os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010574 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010575/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010576{
10577 Py_ssize_t i;
10578 PyObject *buffer = NULL;
10579
10580 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10581 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582
Larry Hastings9cf065c2012-06-22 16:30:09 -070010583 for (i = 0; ; i++) {
10584 void *ptr;
10585 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010586 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010587 Py_ssize_t buffer_size = buffer_sizes[i];
10588 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010589 path_error(path);
10590 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010591 }
10592 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10593 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010594 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010596
Larry Hastings9cf065c2012-06-22 16:30:09 -070010597 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010598 if (path->fd >= 0)
10599 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010600 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010601 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010602 else
Larry Hastings2f936352014-08-05 14:04:04 +100010603 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010604 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010605
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 if (result < 0) {
10607 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 if (errno == ERANGE)
10609 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010610 path_error(path);
10611 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010613
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 if (result != buffer_size) {
10615 /* Can only shrink. */
10616 _PyBytes_Resize(&buffer, result);
10617 }
10618 break;
10619 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010620
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622}
10623
Larry Hastings2f936352014-08-05 14:04:04 +100010624
10625/*[clinic input]
10626os.setxattr
10627
10628 path: path_t(allow_fd=True)
10629 attribute: path_t
10630 value: Py_buffer
10631 flags: int = 0
10632 *
10633 follow_symlinks: bool = True
10634
10635Set extended attribute attribute on path to value.
10636
10637path may be either a string or an open file descriptor.
10638If follow_symlinks is False, and the last element of the path is a symbolic
10639 link, setxattr will modify the symbolic link itself instead of the file
10640 the link points to.
10641
10642[clinic start generated code]*/
10643
Benjamin Peterson799bd802011-08-31 22:15:17 -040010644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010645os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010646 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010647/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648{
Larry Hastings2f936352014-08-05 14:04:04 +100010649 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650
Larry Hastings2f936352014-08-05 14:04:04 +100010651 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010653
Benjamin Peterson799bd802011-08-31 22:15:17 -040010654 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010655 if (path->fd > -1)
10656 result = fsetxattr(path->fd, attribute->narrow,
10657 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010658 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010659 result = setxattr(path->narrow, attribute->narrow,
10660 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661 else
Larry Hastings2f936352014-08-05 14:04:04 +100010662 result = lsetxattr(path->narrow, attribute->narrow,
10663 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010664 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010665
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010667 path_error(path);
10668 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010669 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670
Larry Hastings2f936352014-08-05 14:04:04 +100010671 Py_RETURN_NONE;
10672}
10673
10674
10675/*[clinic input]
10676os.removexattr
10677
10678 path: path_t(allow_fd=True)
10679 attribute: path_t
10680 *
10681 follow_symlinks: bool = True
10682
10683Remove extended attribute attribute on path.
10684
10685path may be either a string or an open file descriptor.
10686If follow_symlinks is False, and the last element of the path is a symbolic
10687 link, removexattr will modify the symbolic link itself instead of the file
10688 the link points to.
10689
10690[clinic start generated code]*/
10691
Larry Hastings2f936352014-08-05 14:04:04 +100010692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010693os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010694 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010695/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010696{
10697 ssize_t result;
10698
10699 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10700 return NULL;
10701
10702 Py_BEGIN_ALLOW_THREADS;
10703 if (path->fd > -1)
10704 result = fremovexattr(path->fd, attribute->narrow);
10705 else if (follow_symlinks)
10706 result = removexattr(path->narrow, attribute->narrow);
10707 else
10708 result = lremovexattr(path->narrow, attribute->narrow);
10709 Py_END_ALLOW_THREADS;
10710
10711 if (result) {
10712 return path_error(path);
10713 }
10714
10715 Py_RETURN_NONE;
10716}
10717
10718
10719/*[clinic input]
10720os.listxattr
10721
10722 path: path_t(allow_fd=True, nullable=True) = None
10723 *
10724 follow_symlinks: bool = True
10725
10726Return a list of extended attributes on path.
10727
10728path may be either None, a string, or an open file descriptor.
10729if path is None, listxattr will examine the current directory.
10730If follow_symlinks is False, and the last element of the path is a symbolic
10731 link, listxattr will examine the symbolic link itself instead of the file
10732 the link points to.
10733[clinic start generated code]*/
10734
Larry Hastings2f936352014-08-05 14:04:04 +100010735static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010736os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10737/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010738{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 Py_ssize_t i;
10740 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010741 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743
Larry Hastings2f936352014-08-05 14:04:04 +100010744 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010746
Larry Hastings2f936352014-08-05 14:04:04 +100010747 name = path->narrow ? path->narrow : ".";
10748
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010750 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010752 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 Py_ssize_t buffer_size = buffer_sizes[i];
10754 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010755 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010756 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 break;
10758 }
10759 buffer = PyMem_MALLOC(buffer_size);
10760 if (!buffer) {
10761 PyErr_NoMemory();
10762 break;
10763 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010764
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010766 if (path->fd > -1)
10767 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 else if (follow_symlinks)
10769 length = listxattr(name, buffer, buffer_size);
10770 else
10771 length = llistxattr(name, buffer, buffer_size);
10772 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010773
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010775 if (errno == ERANGE) {
10776 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010777 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010779 }
Larry Hastings2f936352014-08-05 14:04:04 +100010780 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 break;
10782 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783
Larry Hastings9cf065c2012-06-22 16:30:09 -070010784 result = PyList_New(0);
10785 if (!result) {
10786 goto exit;
10787 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010788
Larry Hastings9cf065c2012-06-22 16:30:09 -070010789 end = buffer + length;
10790 for (trace = start = buffer; trace != end; trace++) {
10791 if (!*trace) {
10792 int error;
10793 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10794 trace - start);
10795 if (!attribute) {
10796 Py_DECREF(result);
10797 result = NULL;
10798 goto exit;
10799 }
10800 error = PyList_Append(result, attribute);
10801 Py_DECREF(attribute);
10802 if (error) {
10803 Py_DECREF(result);
10804 result = NULL;
10805 goto exit;
10806 }
10807 start = trace + 1;
10808 }
10809 }
10810 break;
10811 }
10812exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010813 if (buffer)
10814 PyMem_FREE(buffer);
10815 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010816}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010817#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010819
Larry Hastings2f936352014-08-05 14:04:04 +100010820/*[clinic input]
10821os.urandom
10822
10823 size: Py_ssize_t
10824 /
10825
10826Return a bytes object containing random bytes suitable for cryptographic use.
10827[clinic start generated code]*/
10828
Larry Hastings2f936352014-08-05 14:04:04 +100010829static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010830os_urandom_impl(PyObject *module, Py_ssize_t size)
10831/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010832{
10833 PyObject *bytes;
10834 int result;
10835
Georg Brandl2fb477c2012-02-21 00:33:36 +010010836 if (size < 0)
10837 return PyErr_Format(PyExc_ValueError,
10838 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010839 bytes = PyBytes_FromStringAndSize(NULL, size);
10840 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010841 return NULL;
10842
Victor Stinnere66987e2016-09-06 16:33:52 -070010843 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010844 if (result == -1) {
10845 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010846 return NULL;
10847 }
Larry Hastings2f936352014-08-05 14:04:04 +100010848 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010849}
10850
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010851/* Terminal size querying */
10852
10853static PyTypeObject TerminalSizeType;
10854
10855PyDoc_STRVAR(TerminalSize_docstring,
10856 "A tuple of (columns, lines) for holding terminal window size");
10857
10858static PyStructSequence_Field TerminalSize_fields[] = {
10859 {"columns", "width of the terminal window in characters"},
10860 {"lines", "height of the terminal window in characters"},
10861 {NULL, NULL}
10862};
10863
10864static PyStructSequence_Desc TerminalSize_desc = {
10865 "os.terminal_size",
10866 TerminalSize_docstring,
10867 TerminalSize_fields,
10868 2,
10869};
10870
10871#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010872/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010873PyDoc_STRVAR(termsize__doc__,
10874 "Return the size of the terminal window as (columns, lines).\n" \
10875 "\n" \
10876 "The optional argument fd (default standard output) specifies\n" \
10877 "which file descriptor should be queried.\n" \
10878 "\n" \
10879 "If the file descriptor is not connected to a terminal, an OSError\n" \
10880 "is thrown.\n" \
10881 "\n" \
10882 "This function will only be defined if an implementation is\n" \
10883 "available for this system.\n" \
10884 "\n" \
10885 "shutil.get_terminal_size is the high-level function which should \n" \
10886 "normally be used, os.get_terminal_size is the low-level implementation.");
10887
10888static PyObject*
10889get_terminal_size(PyObject *self, PyObject *args)
10890{
10891 int columns, lines;
10892 PyObject *termsize;
10893
10894 int fd = fileno(stdout);
10895 /* Under some conditions stdout may not be connected and
10896 * fileno(stdout) may point to an invalid file descriptor. For example
10897 * GUI apps don't have valid standard streams by default.
10898 *
10899 * If this happens, and the optional fd argument is not present,
10900 * the ioctl below will fail returning EBADF. This is what we want.
10901 */
10902
10903 if (!PyArg_ParseTuple(args, "|i", &fd))
10904 return NULL;
10905
10906#ifdef TERMSIZE_USE_IOCTL
10907 {
10908 struct winsize w;
10909 if (ioctl(fd, TIOCGWINSZ, &w))
10910 return PyErr_SetFromErrno(PyExc_OSError);
10911 columns = w.ws_col;
10912 lines = w.ws_row;
10913 }
10914#endif /* TERMSIZE_USE_IOCTL */
10915
10916#ifdef TERMSIZE_USE_CONIO
10917 {
10918 DWORD nhandle;
10919 HANDLE handle;
10920 CONSOLE_SCREEN_BUFFER_INFO csbi;
10921 switch (fd) {
10922 case 0: nhandle = STD_INPUT_HANDLE;
10923 break;
10924 case 1: nhandle = STD_OUTPUT_HANDLE;
10925 break;
10926 case 2: nhandle = STD_ERROR_HANDLE;
10927 break;
10928 default:
10929 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10930 }
10931 handle = GetStdHandle(nhandle);
10932 if (handle == NULL)
10933 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10934 if (handle == INVALID_HANDLE_VALUE)
10935 return PyErr_SetFromWindowsErr(0);
10936
10937 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10938 return PyErr_SetFromWindowsErr(0);
10939
10940 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10941 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10942 }
10943#endif /* TERMSIZE_USE_CONIO */
10944
10945 termsize = PyStructSequence_New(&TerminalSizeType);
10946 if (termsize == NULL)
10947 return NULL;
10948 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10949 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10950 if (PyErr_Occurred()) {
10951 Py_DECREF(termsize);
10952 return NULL;
10953 }
10954 return termsize;
10955}
10956#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10957
Larry Hastings2f936352014-08-05 14:04:04 +100010958
10959/*[clinic input]
10960os.cpu_count
10961
Charles-François Natali80d62e62015-08-13 20:37:08 +010010962Return the number of CPUs in the system; return None if indeterminable.
10963
10964This number is not equivalent to the number of CPUs the current process can
10965use. The number of usable CPUs can be obtained with
10966``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010967[clinic start generated code]*/
10968
Larry Hastings2f936352014-08-05 14:04:04 +100010969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010970os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010971/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010972{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010973 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010974#ifdef MS_WINDOWS
10975 SYSTEM_INFO sysinfo;
10976 GetSystemInfo(&sysinfo);
10977 ncpu = sysinfo.dwNumberOfProcessors;
10978#elif defined(__hpux)
10979 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10980#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10981 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010982#elif defined(__DragonFly__) || \
10983 defined(__OpenBSD__) || \
10984 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010985 defined(__NetBSD__) || \
10986 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010987 int mib[2];
10988 size_t len = sizeof(ncpu);
10989 mib[0] = CTL_HW;
10990 mib[1] = HW_NCPU;
10991 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10992 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010993#endif
10994 if (ncpu >= 1)
10995 return PyLong_FromLong(ncpu);
10996 else
10997 Py_RETURN_NONE;
10998}
10999
Victor Stinnerdaf45552013-08-28 00:53:59 +020011000
Larry Hastings2f936352014-08-05 14:04:04 +100011001/*[clinic input]
11002os.get_inheritable -> bool
11003
11004 fd: int
11005 /
11006
11007Get the close-on-exe flag of the specified file descriptor.
11008[clinic start generated code]*/
11009
Larry Hastings2f936352014-08-05 14:04:04 +100011010static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011011os_get_inheritable_impl(PyObject *module, int fd)
11012/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011013{
Steve Dower8fc89802015-04-12 00:26:27 -040011014 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011015 _Py_BEGIN_SUPPRESS_IPH
11016 return_value = _Py_get_inheritable(fd);
11017 _Py_END_SUPPRESS_IPH
11018 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011019}
11020
11021
11022/*[clinic input]
11023os.set_inheritable
11024 fd: int
11025 inheritable: int
11026 /
11027
11028Set the inheritable flag of the specified file descriptor.
11029[clinic start generated code]*/
11030
Larry Hastings2f936352014-08-05 14:04:04 +100011031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011032os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11033/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011034{
Steve Dower8fc89802015-04-12 00:26:27 -040011035 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011036
Steve Dower8fc89802015-04-12 00:26:27 -040011037 _Py_BEGIN_SUPPRESS_IPH
11038 result = _Py_set_inheritable(fd, inheritable, NULL);
11039 _Py_END_SUPPRESS_IPH
11040 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011041 return NULL;
11042 Py_RETURN_NONE;
11043}
11044
11045
11046#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011047/*[clinic input]
11048os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011049 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011050 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011051
Larry Hastings2f936352014-08-05 14:04:04 +100011052Get the close-on-exe flag of the specified file descriptor.
11053[clinic start generated code]*/
11054
Larry Hastings2f936352014-08-05 14:04:04 +100011055static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011056os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011057/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011058{
11059 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011060
11061 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11062 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011063 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011064 }
11065
Larry Hastings2f936352014-08-05 14:04:04 +100011066 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011067}
11068
Victor Stinnerdaf45552013-08-28 00:53:59 +020011069
Larry Hastings2f936352014-08-05 14:04:04 +100011070/*[clinic input]
11071os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011072 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011073 inheritable: bool
11074 /
11075
11076Set the inheritable flag of the specified handle.
11077[clinic start generated code]*/
11078
Larry Hastings2f936352014-08-05 14:04:04 +100011079static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011080os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011081 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011082/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011083{
11084 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011085 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11086 PyErr_SetFromWindowsErr(0);
11087 return NULL;
11088 }
11089 Py_RETURN_NONE;
11090}
Larry Hastings2f936352014-08-05 14:04:04 +100011091#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011092
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011093#ifndef MS_WINDOWS
11094PyDoc_STRVAR(get_blocking__doc__,
11095 "get_blocking(fd) -> bool\n" \
11096 "\n" \
11097 "Get the blocking mode of the file descriptor:\n" \
11098 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11099
11100static PyObject*
11101posix_get_blocking(PyObject *self, PyObject *args)
11102{
11103 int fd;
11104 int blocking;
11105
11106 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11107 return NULL;
11108
Steve Dower8fc89802015-04-12 00:26:27 -040011109 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011110 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011111 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011112 if (blocking < 0)
11113 return NULL;
11114 return PyBool_FromLong(blocking);
11115}
11116
11117PyDoc_STRVAR(set_blocking__doc__,
11118 "set_blocking(fd, blocking)\n" \
11119 "\n" \
11120 "Set the blocking mode of the specified file descriptor.\n" \
11121 "Set the O_NONBLOCK flag if blocking is False,\n" \
11122 "clear the O_NONBLOCK flag otherwise.");
11123
11124static PyObject*
11125posix_set_blocking(PyObject *self, PyObject *args)
11126{
Steve Dower8fc89802015-04-12 00:26:27 -040011127 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011128
11129 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11130 return NULL;
11131
Steve Dower8fc89802015-04-12 00:26:27 -040011132 _Py_BEGIN_SUPPRESS_IPH
11133 result = _Py_set_blocking(fd, blocking);
11134 _Py_END_SUPPRESS_IPH
11135 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011136 return NULL;
11137 Py_RETURN_NONE;
11138}
11139#endif /* !MS_WINDOWS */
11140
11141
Victor Stinner6036e442015-03-08 01:58:04 +010011142PyDoc_STRVAR(posix_scandir__doc__,
11143"scandir(path='.') -> iterator of DirEntry objects for given path");
11144
11145static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11146
11147typedef struct {
11148 PyObject_HEAD
11149 PyObject *name;
11150 PyObject *path;
11151 PyObject *stat;
11152 PyObject *lstat;
11153#ifdef MS_WINDOWS
11154 struct _Py_stat_struct win32_lstat;
11155 __int64 win32_file_index;
11156 int got_file_index;
11157#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011158#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011159 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011160#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011161 ino_t d_ino;
11162#endif
11163} DirEntry;
11164
11165static void
11166DirEntry_dealloc(DirEntry *entry)
11167{
11168 Py_XDECREF(entry->name);
11169 Py_XDECREF(entry->path);
11170 Py_XDECREF(entry->stat);
11171 Py_XDECREF(entry->lstat);
11172 Py_TYPE(entry)->tp_free((PyObject *)entry);
11173}
11174
11175/* Forward reference */
11176static int
11177DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11178
11179/* Set exception and return -1 on error, 0 for False, 1 for True */
11180static int
11181DirEntry_is_symlink(DirEntry *self)
11182{
11183#ifdef MS_WINDOWS
11184 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011185#elif defined(HAVE_DIRENT_D_TYPE)
11186 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011187 if (self->d_type != DT_UNKNOWN)
11188 return self->d_type == DT_LNK;
11189 else
11190 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011191#else
11192 /* POSIX without d_type */
11193 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011194#endif
11195}
11196
11197static PyObject *
11198DirEntry_py_is_symlink(DirEntry *self)
11199{
11200 int result;
11201
11202 result = DirEntry_is_symlink(self);
11203 if (result == -1)
11204 return NULL;
11205 return PyBool_FromLong(result);
11206}
11207
11208static PyObject *
11209DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11210{
11211 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011212 STRUCT_STAT st;
11213 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011214
11215#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011216 if (PyUnicode_FSDecoder(self->path, &ub)) {
11217 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011218#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011219 if (PyUnicode_FSConverter(self->path, &ub)) {
11220 const char *path = PyBytes_AS_STRING(ub);
11221#endif
11222 if (follow_symlinks)
11223 result = STAT(path, &st);
11224 else
11225 result = LSTAT(path, &st);
11226 Py_DECREF(ub);
11227 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011228 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011229
11230 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011231 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011232
11233 return _pystat_fromstructstat(&st);
11234}
11235
11236static PyObject *
11237DirEntry_get_lstat(DirEntry *self)
11238{
11239 if (!self->lstat) {
11240#ifdef MS_WINDOWS
11241 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11242#else /* POSIX */
11243 self->lstat = DirEntry_fetch_stat(self, 0);
11244#endif
11245 }
11246 Py_XINCREF(self->lstat);
11247 return self->lstat;
11248}
11249
11250static PyObject *
11251DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11252{
11253 if (!follow_symlinks)
11254 return DirEntry_get_lstat(self);
11255
11256 if (!self->stat) {
11257 int result = DirEntry_is_symlink(self);
11258 if (result == -1)
11259 return NULL;
11260 else if (result)
11261 self->stat = DirEntry_fetch_stat(self, 1);
11262 else
11263 self->stat = DirEntry_get_lstat(self);
11264 }
11265
11266 Py_XINCREF(self->stat);
11267 return self->stat;
11268}
11269
11270static PyObject *
11271DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11272{
11273 int follow_symlinks = 1;
11274
11275 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11276 follow_symlinks_keywords, &follow_symlinks))
11277 return NULL;
11278
11279 return DirEntry_get_stat(self, follow_symlinks);
11280}
11281
11282/* Set exception and return -1 on error, 0 for False, 1 for True */
11283static int
11284DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11285{
11286 PyObject *stat = NULL;
11287 PyObject *st_mode = NULL;
11288 long mode;
11289 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011290#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011291 int is_symlink;
11292 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011293#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011294#ifdef MS_WINDOWS
11295 unsigned long dir_bits;
11296#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011297 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011298
11299#ifdef MS_WINDOWS
11300 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11301 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011302#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011303 is_symlink = self->d_type == DT_LNK;
11304 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11305#endif
11306
Victor Stinner35a97c02015-03-08 02:59:09 +010011307#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011308 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011309#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011310 stat = DirEntry_get_stat(self, follow_symlinks);
11311 if (!stat) {
11312 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11313 /* If file doesn't exist (anymore), then return False
11314 (i.e., say it's not a file/directory) */
11315 PyErr_Clear();
11316 return 0;
11317 }
11318 goto error;
11319 }
11320 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11321 if (!st_mode)
11322 goto error;
11323
11324 mode = PyLong_AsLong(st_mode);
11325 if (mode == -1 && PyErr_Occurred())
11326 goto error;
11327 Py_CLEAR(st_mode);
11328 Py_CLEAR(stat);
11329 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011330#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011331 }
11332 else if (is_symlink) {
11333 assert(mode_bits != S_IFLNK);
11334 result = 0;
11335 }
11336 else {
11337 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11338#ifdef MS_WINDOWS
11339 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11340 if (mode_bits == S_IFDIR)
11341 result = dir_bits != 0;
11342 else
11343 result = dir_bits == 0;
11344#else /* POSIX */
11345 if (mode_bits == S_IFDIR)
11346 result = self->d_type == DT_DIR;
11347 else
11348 result = self->d_type == DT_REG;
11349#endif
11350 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011351#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011352
11353 return result;
11354
11355error:
11356 Py_XDECREF(st_mode);
11357 Py_XDECREF(stat);
11358 return -1;
11359}
11360
11361static PyObject *
11362DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11363{
11364 int result;
11365
11366 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11367 if (result == -1)
11368 return NULL;
11369 return PyBool_FromLong(result);
11370}
11371
11372static PyObject *
11373DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11374{
11375 int follow_symlinks = 1;
11376
11377 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11378 follow_symlinks_keywords, &follow_symlinks))
11379 return NULL;
11380
11381 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11382}
11383
11384static PyObject *
11385DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11386{
11387 int follow_symlinks = 1;
11388
11389 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11390 follow_symlinks_keywords, &follow_symlinks))
11391 return NULL;
11392
11393 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11394}
11395
11396static PyObject *
11397DirEntry_inode(DirEntry *self)
11398{
11399#ifdef MS_WINDOWS
11400 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011401 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011402 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011403 STRUCT_STAT stat;
11404 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011405
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011406 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011407 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011408 path = PyUnicode_AsUnicode(unicode);
11409 result = LSTAT(path, &stat);
11410 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011411
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011412 if (result != 0)
11413 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011414
11415 self->win32_file_index = stat.st_ino;
11416 self->got_file_index = 1;
11417 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011418 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011419#else /* POSIX */
11420#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011421 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011422#else
11423 return PyLong_FromLong((long)self->d_ino);
11424#endif
11425#endif
11426}
11427
11428static PyObject *
11429DirEntry_repr(DirEntry *self)
11430{
11431 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11432}
11433
Brett Cannon96881cd2016-06-10 14:37:21 -070011434static PyObject *
11435DirEntry_fspath(DirEntry *self)
11436{
11437 Py_INCREF(self->path);
11438 return self->path;
11439}
11440
Victor Stinner6036e442015-03-08 01:58:04 +010011441static PyMemberDef DirEntry_members[] = {
11442 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11443 "the entry's base filename, relative to scandir() \"path\" argument"},
11444 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11445 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11446 {NULL}
11447};
11448
11449static PyMethodDef DirEntry_methods[] = {
11450 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11451 "return True if the entry is a directory; cached per entry"
11452 },
11453 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11454 "return True if the entry is a file; cached per entry"
11455 },
11456 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11457 "return True if the entry is a symbolic link; cached per entry"
11458 },
11459 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11460 "return stat_result object for the entry; cached per entry"
11461 },
11462 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11463 "return inode of the entry; cached per entry",
11464 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011465 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11466 "returns the path for the entry",
11467 },
Victor Stinner6036e442015-03-08 01:58:04 +010011468 {NULL}
11469};
11470
Benjamin Peterson5646de42015-04-12 17:56:34 -040011471static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011472 PyVarObject_HEAD_INIT(NULL, 0)
11473 MODNAME ".DirEntry", /* tp_name */
11474 sizeof(DirEntry), /* tp_basicsize */
11475 0, /* tp_itemsize */
11476 /* methods */
11477 (destructor)DirEntry_dealloc, /* tp_dealloc */
11478 0, /* tp_print */
11479 0, /* tp_getattr */
11480 0, /* tp_setattr */
11481 0, /* tp_compare */
11482 (reprfunc)DirEntry_repr, /* tp_repr */
11483 0, /* tp_as_number */
11484 0, /* tp_as_sequence */
11485 0, /* tp_as_mapping */
11486 0, /* tp_hash */
11487 0, /* tp_call */
11488 0, /* tp_str */
11489 0, /* tp_getattro */
11490 0, /* tp_setattro */
11491 0, /* tp_as_buffer */
11492 Py_TPFLAGS_DEFAULT, /* tp_flags */
11493 0, /* tp_doc */
11494 0, /* tp_traverse */
11495 0, /* tp_clear */
11496 0, /* tp_richcompare */
11497 0, /* tp_weaklistoffset */
11498 0, /* tp_iter */
11499 0, /* tp_iternext */
11500 DirEntry_methods, /* tp_methods */
11501 DirEntry_members, /* tp_members */
11502};
11503
11504#ifdef MS_WINDOWS
11505
11506static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011507join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011508{
11509 Py_ssize_t path_len;
11510 Py_ssize_t size;
11511 wchar_t *result;
11512 wchar_t ch;
11513
11514 if (!path_wide) { /* Default arg: "." */
11515 path_wide = L".";
11516 path_len = 1;
11517 }
11518 else {
11519 path_len = wcslen(path_wide);
11520 }
11521
11522 /* The +1's are for the path separator and the NUL */
11523 size = path_len + 1 + wcslen(filename) + 1;
11524 result = PyMem_New(wchar_t, size);
11525 if (!result) {
11526 PyErr_NoMemory();
11527 return NULL;
11528 }
11529 wcscpy(result, path_wide);
11530 if (path_len > 0) {
11531 ch = result[path_len - 1];
11532 if (ch != SEP && ch != ALTSEP && ch != L':')
11533 result[path_len++] = SEP;
11534 wcscpy(result + path_len, filename);
11535 }
11536 return result;
11537}
11538
11539static PyObject *
11540DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11541{
11542 DirEntry *entry;
11543 BY_HANDLE_FILE_INFORMATION file_info;
11544 ULONG reparse_tag;
11545 wchar_t *joined_path;
11546
11547 entry = PyObject_New(DirEntry, &DirEntryType);
11548 if (!entry)
11549 return NULL;
11550 entry->name = NULL;
11551 entry->path = NULL;
11552 entry->stat = NULL;
11553 entry->lstat = NULL;
11554 entry->got_file_index = 0;
11555
11556 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11557 if (!entry->name)
11558 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011559 if (path->narrow) {
11560 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11561 if (!entry->name)
11562 goto error;
11563 }
Victor Stinner6036e442015-03-08 01:58:04 +010011564
11565 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11566 if (!joined_path)
11567 goto error;
11568
11569 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11570 PyMem_Free(joined_path);
11571 if (!entry->path)
11572 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011573 if (path->narrow) {
11574 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11575 if (!entry->path)
11576 goto error;
11577 }
Victor Stinner6036e442015-03-08 01:58:04 +010011578
Steve Dowercc16be82016-09-08 10:35:16 -070011579 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011580 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11581
11582 return (PyObject *)entry;
11583
11584error:
11585 Py_DECREF(entry);
11586 return NULL;
11587}
11588
11589#else /* POSIX */
11590
11591static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011592join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011593{
11594 Py_ssize_t path_len;
11595 Py_ssize_t size;
11596 char *result;
11597
11598 if (!path_narrow) { /* Default arg: "." */
11599 path_narrow = ".";
11600 path_len = 1;
11601 }
11602 else {
11603 path_len = strlen(path_narrow);
11604 }
11605
11606 if (filename_len == -1)
11607 filename_len = strlen(filename);
11608
11609 /* The +1's are for the path separator and the NUL */
11610 size = path_len + 1 + filename_len + 1;
11611 result = PyMem_New(char, size);
11612 if (!result) {
11613 PyErr_NoMemory();
11614 return NULL;
11615 }
11616 strcpy(result, path_narrow);
11617 if (path_len > 0 && result[path_len - 1] != '/')
11618 result[path_len++] = '/';
11619 strcpy(result + path_len, filename);
11620 return result;
11621}
11622
11623static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011624DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011625 ino_t d_ino
11626#ifdef HAVE_DIRENT_D_TYPE
11627 , unsigned char d_type
11628#endif
11629 )
Victor Stinner6036e442015-03-08 01:58:04 +010011630{
11631 DirEntry *entry;
11632 char *joined_path;
11633
11634 entry = PyObject_New(DirEntry, &DirEntryType);
11635 if (!entry)
11636 return NULL;
11637 entry->name = NULL;
11638 entry->path = NULL;
11639 entry->stat = NULL;
11640 entry->lstat = NULL;
11641
11642 joined_path = join_path_filename(path->narrow, name, name_len);
11643 if (!joined_path)
11644 goto error;
11645
11646 if (!path->narrow || !PyBytes_Check(path->object)) {
11647 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11648 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11649 }
11650 else {
11651 entry->name = PyBytes_FromStringAndSize(name, name_len);
11652 entry->path = PyBytes_FromString(joined_path);
11653 }
11654 PyMem_Free(joined_path);
11655 if (!entry->name || !entry->path)
11656 goto error;
11657
Victor Stinner35a97c02015-03-08 02:59:09 +010011658#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011659 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011660#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011661 entry->d_ino = d_ino;
11662
11663 return (PyObject *)entry;
11664
11665error:
11666 Py_XDECREF(entry);
11667 return NULL;
11668}
11669
11670#endif
11671
11672
11673typedef struct {
11674 PyObject_HEAD
11675 path_t path;
11676#ifdef MS_WINDOWS
11677 HANDLE handle;
11678 WIN32_FIND_DATAW file_data;
11679 int first_time;
11680#else /* POSIX */
11681 DIR *dirp;
11682#endif
11683} ScandirIterator;
11684
11685#ifdef MS_WINDOWS
11686
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011687static int
11688ScandirIterator_is_closed(ScandirIterator *iterator)
11689{
11690 return iterator->handle == INVALID_HANDLE_VALUE;
11691}
11692
Victor Stinner6036e442015-03-08 01:58:04 +010011693static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011694ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011695{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011696 HANDLE handle = iterator->handle;
11697
11698 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011699 return;
11700
Victor Stinner6036e442015-03-08 01:58:04 +010011701 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011702 Py_BEGIN_ALLOW_THREADS
11703 FindClose(handle);
11704 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011705}
11706
11707static PyObject *
11708ScandirIterator_iternext(ScandirIterator *iterator)
11709{
11710 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11711 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011712 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011713
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011714 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011715 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011716 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011717
11718 while (1) {
11719 if (!iterator->first_time) {
11720 Py_BEGIN_ALLOW_THREADS
11721 success = FindNextFileW(iterator->handle, file_data);
11722 Py_END_ALLOW_THREADS
11723 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011724 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011725 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011726 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011727 break;
11728 }
11729 }
11730 iterator->first_time = 0;
11731
11732 /* Skip over . and .. */
11733 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011734 wcscmp(file_data->cFileName, L"..") != 0) {
11735 entry = DirEntry_from_find_data(&iterator->path, file_data);
11736 if (!entry)
11737 break;
11738 return entry;
11739 }
Victor Stinner6036e442015-03-08 01:58:04 +010011740
11741 /* Loop till we get a non-dot directory or finish iterating */
11742 }
11743
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011744 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011745 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011746 return NULL;
11747}
11748
11749#else /* POSIX */
11750
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011751static int
11752ScandirIterator_is_closed(ScandirIterator *iterator)
11753{
11754 return !iterator->dirp;
11755}
11756
Victor Stinner6036e442015-03-08 01:58:04 +010011757static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011758ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011759{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011760 DIR *dirp = iterator->dirp;
11761
11762 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011763 return;
11764
Victor Stinner6036e442015-03-08 01:58:04 +010011765 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011766 Py_BEGIN_ALLOW_THREADS
11767 closedir(dirp);
11768 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011769 return;
11770}
11771
11772static PyObject *
11773ScandirIterator_iternext(ScandirIterator *iterator)
11774{
11775 struct dirent *direntp;
11776 Py_ssize_t name_len;
11777 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011778 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011779
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011780 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011781 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011782 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011783
11784 while (1) {
11785 errno = 0;
11786 Py_BEGIN_ALLOW_THREADS
11787 direntp = readdir(iterator->dirp);
11788 Py_END_ALLOW_THREADS
11789
11790 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011791 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011792 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011793 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011794 break;
11795 }
11796
11797 /* Skip over . and .. */
11798 name_len = NAMLEN(direntp);
11799 is_dot = direntp->d_name[0] == '.' &&
11800 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11801 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011802 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011803 name_len, direntp->d_ino
11804#ifdef HAVE_DIRENT_D_TYPE
11805 , direntp->d_type
11806#endif
11807 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011808 if (!entry)
11809 break;
11810 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011811 }
11812
11813 /* Loop till we get a non-dot directory or finish iterating */
11814 }
11815
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011816 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011817 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011818 return NULL;
11819}
11820
11821#endif
11822
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011823static PyObject *
11824ScandirIterator_close(ScandirIterator *self, PyObject *args)
11825{
11826 ScandirIterator_closedir(self);
11827 Py_RETURN_NONE;
11828}
11829
11830static PyObject *
11831ScandirIterator_enter(PyObject *self, PyObject *args)
11832{
11833 Py_INCREF(self);
11834 return self;
11835}
11836
11837static PyObject *
11838ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11839{
11840 ScandirIterator_closedir(self);
11841 Py_RETURN_NONE;
11842}
11843
Victor Stinner6036e442015-03-08 01:58:04 +010011844static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011845ScandirIterator_finalize(ScandirIterator *iterator)
11846{
11847 PyObject *error_type, *error_value, *error_traceback;
11848
11849 /* Save the current exception, if any. */
11850 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11851
11852 if (!ScandirIterator_is_closed(iterator)) {
11853 ScandirIterator_closedir(iterator);
11854
11855 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11856 "unclosed scandir iterator %R", iterator)) {
11857 /* Spurious errors can appear at shutdown */
11858 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11859 PyErr_WriteUnraisable((PyObject *) iterator);
11860 }
11861 }
11862 }
11863
11864 Py_CLEAR(iterator->path.object);
11865 path_cleanup(&iterator->path);
11866
11867 /* Restore the saved exception. */
11868 PyErr_Restore(error_type, error_value, error_traceback);
11869}
11870
11871static void
Victor Stinner6036e442015-03-08 01:58:04 +010011872ScandirIterator_dealloc(ScandirIterator *iterator)
11873{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011874 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11875 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011876
Victor Stinner6036e442015-03-08 01:58:04 +010011877 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11878}
11879
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011880static PyMethodDef ScandirIterator_methods[] = {
11881 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11882 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11883 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11884 {NULL}
11885};
11886
Benjamin Peterson5646de42015-04-12 17:56:34 -040011887static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011888 PyVarObject_HEAD_INIT(NULL, 0)
11889 MODNAME ".ScandirIterator", /* tp_name */
11890 sizeof(ScandirIterator), /* tp_basicsize */
11891 0, /* tp_itemsize */
11892 /* methods */
11893 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11894 0, /* tp_print */
11895 0, /* tp_getattr */
11896 0, /* tp_setattr */
11897 0, /* tp_compare */
11898 0, /* tp_repr */
11899 0, /* tp_as_number */
11900 0, /* tp_as_sequence */
11901 0, /* tp_as_mapping */
11902 0, /* tp_hash */
11903 0, /* tp_call */
11904 0, /* tp_str */
11905 0, /* tp_getattro */
11906 0, /* tp_setattro */
11907 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011908 Py_TPFLAGS_DEFAULT
11909 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011910 0, /* tp_doc */
11911 0, /* tp_traverse */
11912 0, /* tp_clear */
11913 0, /* tp_richcompare */
11914 0, /* tp_weaklistoffset */
11915 PyObject_SelfIter, /* tp_iter */
11916 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011917 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011918 0, /* tp_members */
11919 0, /* tp_getset */
11920 0, /* tp_base */
11921 0, /* tp_dict */
11922 0, /* tp_descr_get */
11923 0, /* tp_descr_set */
11924 0, /* tp_dictoffset */
11925 0, /* tp_init */
11926 0, /* tp_alloc */
11927 0, /* tp_new */
11928 0, /* tp_free */
11929 0, /* tp_is_gc */
11930 0, /* tp_bases */
11931 0, /* tp_mro */
11932 0, /* tp_cache */
11933 0, /* tp_subclasses */
11934 0, /* tp_weaklist */
11935 0, /* tp_del */
11936 0, /* tp_version_tag */
11937 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011938};
11939
11940static PyObject *
11941posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11942{
11943 ScandirIterator *iterator;
11944 static char *keywords[] = {"path", NULL};
11945#ifdef MS_WINDOWS
11946 wchar_t *path_strW;
11947#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011948 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011949#endif
11950
11951 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11952 if (!iterator)
11953 return NULL;
11954 memset(&iterator->path, 0, sizeof(path_t));
11955 iterator->path.function_name = "scandir";
11956 iterator->path.nullable = 1;
11957
11958#ifdef MS_WINDOWS
11959 iterator->handle = INVALID_HANDLE_VALUE;
11960#else
11961 iterator->dirp = NULL;
11962#endif
11963
11964 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11965 path_converter, &iterator->path))
11966 goto error;
11967
11968 /* path_converter doesn't keep path.object around, so do it
11969 manually for the lifetime of the iterator here (the refcount
11970 is decremented in ScandirIterator_dealloc)
11971 */
11972 Py_XINCREF(iterator->path.object);
11973
11974#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011975 iterator->first_time = 1;
11976
11977 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11978 if (!path_strW)
11979 goto error;
11980
11981 Py_BEGIN_ALLOW_THREADS
11982 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11983 Py_END_ALLOW_THREADS
11984
11985 PyMem_Free(path_strW);
11986
11987 if (iterator->handle == INVALID_HANDLE_VALUE) {
11988 path_error(&iterator->path);
11989 goto error;
11990 }
11991#else /* POSIX */
11992 if (iterator->path.narrow)
11993 path = iterator->path.narrow;
11994 else
11995 path = ".";
11996
11997 errno = 0;
11998 Py_BEGIN_ALLOW_THREADS
11999 iterator->dirp = opendir(path);
12000 Py_END_ALLOW_THREADS
12001
12002 if (!iterator->dirp) {
12003 path_error(&iterator->path);
12004 goto error;
12005 }
12006#endif
12007
12008 return (PyObject *)iterator;
12009
12010error:
12011 Py_DECREF(iterator);
12012 return NULL;
12013}
12014
Ethan Furman410ef8e2016-06-04 12:06:26 -070012015/*
12016 Return the file system path representation of the object.
12017
12018 If the object is str or bytes, then allow it to pass through with
12019 an incremented refcount. If the object defines __fspath__(), then
12020 return the result of that method. All other types raise a TypeError.
12021*/
12022PyObject *
12023PyOS_FSPath(PyObject *path)
12024{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012025 /* For error message reasons, this function is manually inlined in
12026 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012027 _Py_IDENTIFIER(__fspath__);
12028 PyObject *func = NULL;
12029 PyObject *path_repr = NULL;
12030
12031 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12032 Py_INCREF(path);
12033 return path;
12034 }
12035
12036 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12037 if (NULL == func) {
12038 return PyErr_Format(PyExc_TypeError,
12039 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012040 "not %.200s",
12041 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012042 }
12043
12044 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12045 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012046 if (NULL == path_repr) {
12047 return NULL;
12048 }
12049
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012050 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12051 PyErr_Format(PyExc_TypeError,
12052 "expected %.200s.__fspath__() to return str or bytes, "
12053 "not %.200s", Py_TYPE(path)->tp_name,
12054 Py_TYPE(path_repr)->tp_name);
12055 Py_DECREF(path_repr);
12056 return NULL;
12057 }
12058
Ethan Furman410ef8e2016-06-04 12:06:26 -070012059 return path_repr;
12060}
12061
12062/*[clinic input]
12063os.fspath
12064
12065 path: object
12066
12067Return the file system path representation of the object.
12068
Brett Cannonb4f43e92016-06-09 14:32:08 -070012069If the object is str or bytes, then allow it to pass through as-is. If the
12070object defines __fspath__(), then return the result of that method. All other
12071types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012072[clinic start generated code]*/
12073
12074static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012075os_fspath_impl(PyObject *module, PyObject *path)
12076/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012077{
12078 return PyOS_FSPath(path);
12079}
Victor Stinner6036e442015-03-08 01:58:04 +010012080
Victor Stinner9b1f4742016-09-06 16:18:52 -070012081#ifdef HAVE_GETRANDOM_SYSCALL
12082/*[clinic input]
12083os.getrandom
12084
12085 size: Py_ssize_t
12086 flags: int=0
12087
12088Obtain a series of random bytes.
12089[clinic start generated code]*/
12090
12091static PyObject *
12092os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12093/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12094{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012095 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012096 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012097
12098 if (size < 0) {
12099 errno = EINVAL;
12100 return posix_error();
12101 }
12102
Victor Stinnerec2319c2016-09-20 23:00:59 +020012103 bytes = PyBytes_FromStringAndSize(NULL, size);
12104 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012105 PyErr_NoMemory();
12106 return NULL;
12107 }
12108
12109 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012110 n = syscall(SYS_getrandom,
12111 PyBytes_AS_STRING(bytes),
12112 PyBytes_GET_SIZE(bytes),
12113 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012114 if (n < 0 && errno == EINTR) {
12115 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012116 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012117 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012118
12119 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012120 continue;
12121 }
12122 break;
12123 }
12124
12125 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012126 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012127 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012128 }
12129
Victor Stinnerec2319c2016-09-20 23:00:59 +020012130 if (n != size) {
12131 _PyBytes_Resize(&bytes, n);
12132 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012133
12134 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012135
12136error:
12137 Py_DECREF(bytes);
12138 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012139}
12140#endif /* HAVE_GETRANDOM_SYSCALL */
12141
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012142#include "clinic/posixmodule.c.h"
12143
Larry Hastings7726ac92014-01-31 22:03:12 -080012144/*[clinic input]
12145dump buffer
12146[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012147/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012148
Larry Hastings31826802013-10-19 00:09:25 -070012149
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012150static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012151
12152 OS_STAT_METHODDEF
12153 OS_ACCESS_METHODDEF
12154 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012155 OS_CHDIR_METHODDEF
12156 OS_CHFLAGS_METHODDEF
12157 OS_CHMOD_METHODDEF
12158 OS_FCHMOD_METHODDEF
12159 OS_LCHMOD_METHODDEF
12160 OS_CHOWN_METHODDEF
12161 OS_FCHOWN_METHODDEF
12162 OS_LCHOWN_METHODDEF
12163 OS_LCHFLAGS_METHODDEF
12164 OS_CHROOT_METHODDEF
12165 OS_CTERMID_METHODDEF
12166 OS_GETCWD_METHODDEF
12167 OS_GETCWDB_METHODDEF
12168 OS_LINK_METHODDEF
12169 OS_LISTDIR_METHODDEF
12170 OS_LSTAT_METHODDEF
12171 OS_MKDIR_METHODDEF
12172 OS_NICE_METHODDEF
12173 OS_GETPRIORITY_METHODDEF
12174 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012175#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012176 {"readlink", (PyCFunction)posix_readlink,
12177 METH_VARARGS | METH_KEYWORDS,
12178 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012179#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012180#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012181 {"readlink", (PyCFunction)win_readlink,
12182 METH_VARARGS | METH_KEYWORDS,
12183 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012184#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012185 OS_RENAME_METHODDEF
12186 OS_REPLACE_METHODDEF
12187 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012188 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012189 OS_SYMLINK_METHODDEF
12190 OS_SYSTEM_METHODDEF
12191 OS_UMASK_METHODDEF
12192 OS_UNAME_METHODDEF
12193 OS_UNLINK_METHODDEF
12194 OS_REMOVE_METHODDEF
12195 OS_UTIME_METHODDEF
12196 OS_TIMES_METHODDEF
12197 OS__EXIT_METHODDEF
12198 OS_EXECV_METHODDEF
12199 OS_EXECVE_METHODDEF
12200 OS_SPAWNV_METHODDEF
12201 OS_SPAWNVE_METHODDEF
12202 OS_FORK1_METHODDEF
12203 OS_FORK_METHODDEF
12204 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12205 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12206 OS_SCHED_GETPARAM_METHODDEF
12207 OS_SCHED_GETSCHEDULER_METHODDEF
12208 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12209 OS_SCHED_SETPARAM_METHODDEF
12210 OS_SCHED_SETSCHEDULER_METHODDEF
12211 OS_SCHED_YIELD_METHODDEF
12212 OS_SCHED_SETAFFINITY_METHODDEF
12213 OS_SCHED_GETAFFINITY_METHODDEF
12214 OS_OPENPTY_METHODDEF
12215 OS_FORKPTY_METHODDEF
12216 OS_GETEGID_METHODDEF
12217 OS_GETEUID_METHODDEF
12218 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012219#ifdef HAVE_GETGROUPLIST
12220 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12221#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012222 OS_GETGROUPS_METHODDEF
12223 OS_GETPID_METHODDEF
12224 OS_GETPGRP_METHODDEF
12225 OS_GETPPID_METHODDEF
12226 OS_GETUID_METHODDEF
12227 OS_GETLOGIN_METHODDEF
12228 OS_KILL_METHODDEF
12229 OS_KILLPG_METHODDEF
12230 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012231#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012232 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012233#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012234 OS_SETUID_METHODDEF
12235 OS_SETEUID_METHODDEF
12236 OS_SETREUID_METHODDEF
12237 OS_SETGID_METHODDEF
12238 OS_SETEGID_METHODDEF
12239 OS_SETREGID_METHODDEF
12240 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012241#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012242 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012243#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012244 OS_GETPGID_METHODDEF
12245 OS_SETPGRP_METHODDEF
12246 OS_WAIT_METHODDEF
12247 OS_WAIT3_METHODDEF
12248 OS_WAIT4_METHODDEF
12249 OS_WAITID_METHODDEF
12250 OS_WAITPID_METHODDEF
12251 OS_GETSID_METHODDEF
12252 OS_SETSID_METHODDEF
12253 OS_SETPGID_METHODDEF
12254 OS_TCGETPGRP_METHODDEF
12255 OS_TCSETPGRP_METHODDEF
12256 OS_OPEN_METHODDEF
12257 OS_CLOSE_METHODDEF
12258 OS_CLOSERANGE_METHODDEF
12259 OS_DEVICE_ENCODING_METHODDEF
12260 OS_DUP_METHODDEF
12261 OS_DUP2_METHODDEF
12262 OS_LOCKF_METHODDEF
12263 OS_LSEEK_METHODDEF
12264 OS_READ_METHODDEF
12265 OS_READV_METHODDEF
12266 OS_PREAD_METHODDEF
12267 OS_WRITE_METHODDEF
12268 OS_WRITEV_METHODDEF
12269 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012270#ifdef HAVE_SENDFILE
12271 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12272 posix_sendfile__doc__},
12273#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012274 OS_FSTAT_METHODDEF
12275 OS_ISATTY_METHODDEF
12276 OS_PIPE_METHODDEF
12277 OS_PIPE2_METHODDEF
12278 OS_MKFIFO_METHODDEF
12279 OS_MKNOD_METHODDEF
12280 OS_MAJOR_METHODDEF
12281 OS_MINOR_METHODDEF
12282 OS_MAKEDEV_METHODDEF
12283 OS_FTRUNCATE_METHODDEF
12284 OS_TRUNCATE_METHODDEF
12285 OS_POSIX_FALLOCATE_METHODDEF
12286 OS_POSIX_FADVISE_METHODDEF
12287 OS_PUTENV_METHODDEF
12288 OS_UNSETENV_METHODDEF
12289 OS_STRERROR_METHODDEF
12290 OS_FCHDIR_METHODDEF
12291 OS_FSYNC_METHODDEF
12292 OS_SYNC_METHODDEF
12293 OS_FDATASYNC_METHODDEF
12294 OS_WCOREDUMP_METHODDEF
12295 OS_WIFCONTINUED_METHODDEF
12296 OS_WIFSTOPPED_METHODDEF
12297 OS_WIFSIGNALED_METHODDEF
12298 OS_WIFEXITED_METHODDEF
12299 OS_WEXITSTATUS_METHODDEF
12300 OS_WTERMSIG_METHODDEF
12301 OS_WSTOPSIG_METHODDEF
12302 OS_FSTATVFS_METHODDEF
12303 OS_STATVFS_METHODDEF
12304 OS_CONFSTR_METHODDEF
12305 OS_SYSCONF_METHODDEF
12306 OS_FPATHCONF_METHODDEF
12307 OS_PATHCONF_METHODDEF
12308 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012309 OS__GETFULLPATHNAME_METHODDEF
12310 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012311 OS__GETDISKUSAGE_METHODDEF
12312 OS__GETFINALPATHNAME_METHODDEF
12313 OS__GETVOLUMEPATHNAME_METHODDEF
12314 OS_GETLOADAVG_METHODDEF
12315 OS_URANDOM_METHODDEF
12316 OS_SETRESUID_METHODDEF
12317 OS_SETRESGID_METHODDEF
12318 OS_GETRESUID_METHODDEF
12319 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012320
Larry Hastings2f936352014-08-05 14:04:04 +100012321 OS_GETXATTR_METHODDEF
12322 OS_SETXATTR_METHODDEF
12323 OS_REMOVEXATTR_METHODDEF
12324 OS_LISTXATTR_METHODDEF
12325
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012326#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12327 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12328#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012329 OS_CPU_COUNT_METHODDEF
12330 OS_GET_INHERITABLE_METHODDEF
12331 OS_SET_INHERITABLE_METHODDEF
12332 OS_GET_HANDLE_INHERITABLE_METHODDEF
12333 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012334#ifndef MS_WINDOWS
12335 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12336 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12337#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012338 {"scandir", (PyCFunction)posix_scandir,
12339 METH_VARARGS | METH_KEYWORDS,
12340 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012341 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012342 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012343 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012344};
12345
12346
Brian Curtin52173d42010-12-02 18:29:18 +000012347#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012348static int
Brian Curtin52173d42010-12-02 18:29:18 +000012349enable_symlink()
12350{
12351 HANDLE tok;
12352 TOKEN_PRIVILEGES tok_priv;
12353 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012354
12355 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012356 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012357
12358 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012359 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012360
12361 tok_priv.PrivilegeCount = 1;
12362 tok_priv.Privileges[0].Luid = luid;
12363 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12364
12365 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12366 sizeof(TOKEN_PRIVILEGES),
12367 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012368 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012369
Brian Curtin3b4499c2010-12-28 14:31:47 +000012370 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12371 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012372}
12373#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12374
Barry Warsaw4a342091996-12-19 23:50:02 +000012375static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012376all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012377{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012378#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012379 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012380#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012381#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012383#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012384#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012385 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012386#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012387#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012388 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012389#endif
Fred Drakec9680921999-12-13 16:37:25 +000012390#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012391 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012392#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012393#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012394 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012395#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012396#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012397 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012398#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012399#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012401#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012402#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012404#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012405#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012407#endif
12408#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012410#endif
12411#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012413#endif
12414#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012416#endif
12417#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012419#endif
12420#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012422#endif
12423#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012424 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012425#endif
12426#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012428#endif
12429#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012430 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#endif
12432#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012433 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012434#endif
12435#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012437#endif
12438#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012439 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012440#endif
12441#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012442 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012443#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012444#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012445 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012446#endif
12447#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012449#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012450#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012452#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012453#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012454 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012455#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012456#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012457#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012459#endif
12460#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012462#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012463#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012464#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012466#endif
12467#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012468 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012469#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012470#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012472#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012473#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012474 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012475#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012476#ifdef O_TMPFILE
12477 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12478#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012479#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012480 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012481#endif
12482#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012484#endif
12485#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012486 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012487#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012488#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012489 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012490#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012491#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012492 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012493#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012494
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012495
Jesus Cea94363612012-06-22 18:32:07 +020012496#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012498#endif
12499#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012501#endif
12502
Tim Peters5aa91602002-01-30 05:46:57 +000012503/* MS Windows */
12504#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012505 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012507#endif
12508#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012509 /* Optimize for short life (keep in memory). */
12510 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012511 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012512#endif
12513#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012514 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012516#endif
12517#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012518 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012519 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012520#endif
12521#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012522 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012523 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012524#endif
12525
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012526/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012527#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012528 /* Send a SIGIO signal whenever input or output
12529 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012531#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012532#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012533 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012534 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012535#endif
12536#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012537 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012538 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012539#endif
12540#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012541 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012542 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012543#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012544#ifdef O_NOLINKS
12545 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012546 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012547#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012548#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012549 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012550 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012551#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012552
Victor Stinner8c62be82010-05-06 00:08:46 +000012553 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012554#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012556#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012557#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012559#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012560#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012561 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012562#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012563#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012564 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012565#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012566#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012568#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012569#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012571#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012572#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012573 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012574#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012575#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012576 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012577#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012598#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012599#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012601#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012602#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012604#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012605
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012606 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012607#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012609#endif /* ST_RDONLY */
12610#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012612#endif /* ST_NOSUID */
12613
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012614 /* GNU extensions */
12615#ifdef ST_NODEV
12616 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12617#endif /* ST_NODEV */
12618#ifdef ST_NOEXEC
12619 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12620#endif /* ST_NOEXEC */
12621#ifdef ST_SYNCHRONOUS
12622 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12623#endif /* ST_SYNCHRONOUS */
12624#ifdef ST_MANDLOCK
12625 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12626#endif /* ST_MANDLOCK */
12627#ifdef ST_WRITE
12628 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12629#endif /* ST_WRITE */
12630#ifdef ST_APPEND
12631 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12632#endif /* ST_APPEND */
12633#ifdef ST_NOATIME
12634 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12635#endif /* ST_NOATIME */
12636#ifdef ST_NODIRATIME
12637 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12638#endif /* ST_NODIRATIME */
12639#ifdef ST_RELATIME
12640 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12641#endif /* ST_RELATIME */
12642
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012643 /* FreeBSD sendfile() constants */
12644#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012645 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012646#endif
12647#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012648 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012649#endif
12650#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012651 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012652#endif
12653
Ross Lagerwall7807c352011-03-17 20:20:30 +020012654 /* constants for posix_fadvise */
12655#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012657#endif
12658#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012660#endif
12661#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012663#endif
12664#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012666#endif
12667#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012669#endif
12670#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012672#endif
12673
12674 /* constants for waitid */
12675#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012676 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12677 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12678 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012679#endif
12680#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012682#endif
12683#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012685#endif
12686#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012687 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012688#endif
12689#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012691#endif
12692#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012694#endif
12695#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012697#endif
12698#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012699 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012700#endif
12701
12702 /* constants for lockf */
12703#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012705#endif
12706#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012708#endif
12709#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012710 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012711#endif
12712#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012714#endif
12715
Guido van Rossum246bc171999-02-01 23:54:31 +000012716#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12718 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12719 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12720 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12721 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012722#endif
12723
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012724#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012725#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012727#endif
12728#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012730#endif
12731#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012733#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012734#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012736#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012737#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012739#endif
12740#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012742#endif
12743#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012745#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012746#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012748#endif
12749#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012751#endif
12752#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012754#endif
12755#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012757#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012758#endif
12759
Benjamin Peterson9428d532011-09-14 11:45:52 -040012760#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12762 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12763 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012764#endif
12765
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012766#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012768#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012769#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012771#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012772#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012774#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012775#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012777#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012778#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012780#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012781#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012783#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012784#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012786#endif
12787
Victor Stinner9b1f4742016-09-06 16:18:52 -070012788#ifdef HAVE_GETRANDOM_SYSCALL
12789 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12790 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12791#endif
12792
Victor Stinner8c62be82010-05-06 00:08:46 +000012793 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012794}
12795
12796
Martin v. Löwis1a214512008-06-11 05:26:20 +000012797static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012798 PyModuleDef_HEAD_INIT,
12799 MODNAME,
12800 posix__doc__,
12801 -1,
12802 posix_methods,
12803 NULL,
12804 NULL,
12805 NULL,
12806 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012807};
12808
12809
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012810static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012811
12812#ifdef HAVE_FACCESSAT
12813 "HAVE_FACCESSAT",
12814#endif
12815
12816#ifdef HAVE_FCHDIR
12817 "HAVE_FCHDIR",
12818#endif
12819
12820#ifdef HAVE_FCHMOD
12821 "HAVE_FCHMOD",
12822#endif
12823
12824#ifdef HAVE_FCHMODAT
12825 "HAVE_FCHMODAT",
12826#endif
12827
12828#ifdef HAVE_FCHOWN
12829 "HAVE_FCHOWN",
12830#endif
12831
Larry Hastings00964ed2013-08-12 13:49:30 -040012832#ifdef HAVE_FCHOWNAT
12833 "HAVE_FCHOWNAT",
12834#endif
12835
Larry Hastings9cf065c2012-06-22 16:30:09 -070012836#ifdef HAVE_FEXECVE
12837 "HAVE_FEXECVE",
12838#endif
12839
12840#ifdef HAVE_FDOPENDIR
12841 "HAVE_FDOPENDIR",
12842#endif
12843
Georg Brandl306336b2012-06-24 12:55:33 +020012844#ifdef HAVE_FPATHCONF
12845 "HAVE_FPATHCONF",
12846#endif
12847
Larry Hastings9cf065c2012-06-22 16:30:09 -070012848#ifdef HAVE_FSTATAT
12849 "HAVE_FSTATAT",
12850#endif
12851
12852#ifdef HAVE_FSTATVFS
12853 "HAVE_FSTATVFS",
12854#endif
12855
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012856#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012857 "HAVE_FTRUNCATE",
12858#endif
12859
Larry Hastings9cf065c2012-06-22 16:30:09 -070012860#ifdef HAVE_FUTIMENS
12861 "HAVE_FUTIMENS",
12862#endif
12863
12864#ifdef HAVE_FUTIMES
12865 "HAVE_FUTIMES",
12866#endif
12867
12868#ifdef HAVE_FUTIMESAT
12869 "HAVE_FUTIMESAT",
12870#endif
12871
12872#ifdef HAVE_LINKAT
12873 "HAVE_LINKAT",
12874#endif
12875
12876#ifdef HAVE_LCHFLAGS
12877 "HAVE_LCHFLAGS",
12878#endif
12879
12880#ifdef HAVE_LCHMOD
12881 "HAVE_LCHMOD",
12882#endif
12883
12884#ifdef HAVE_LCHOWN
12885 "HAVE_LCHOWN",
12886#endif
12887
12888#ifdef HAVE_LSTAT
12889 "HAVE_LSTAT",
12890#endif
12891
12892#ifdef HAVE_LUTIMES
12893 "HAVE_LUTIMES",
12894#endif
12895
12896#ifdef HAVE_MKDIRAT
12897 "HAVE_MKDIRAT",
12898#endif
12899
12900#ifdef HAVE_MKFIFOAT
12901 "HAVE_MKFIFOAT",
12902#endif
12903
12904#ifdef HAVE_MKNODAT
12905 "HAVE_MKNODAT",
12906#endif
12907
12908#ifdef HAVE_OPENAT
12909 "HAVE_OPENAT",
12910#endif
12911
12912#ifdef HAVE_READLINKAT
12913 "HAVE_READLINKAT",
12914#endif
12915
12916#ifdef HAVE_RENAMEAT
12917 "HAVE_RENAMEAT",
12918#endif
12919
12920#ifdef HAVE_SYMLINKAT
12921 "HAVE_SYMLINKAT",
12922#endif
12923
12924#ifdef HAVE_UNLINKAT
12925 "HAVE_UNLINKAT",
12926#endif
12927
12928#ifdef HAVE_UTIMENSAT
12929 "HAVE_UTIMENSAT",
12930#endif
12931
12932#ifdef MS_WINDOWS
12933 "MS_WINDOWS",
12934#endif
12935
12936 NULL
12937};
12938
12939
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012940PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012941INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012942{
Victor Stinner8c62be82010-05-06 00:08:46 +000012943 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012944 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012945 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012946
Brian Curtin52173d42010-12-02 18:29:18 +000012947#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012948 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012949#endif
12950
Victor Stinner8c62be82010-05-06 00:08:46 +000012951 m = PyModule_Create(&posixmodule);
12952 if (m == NULL)
12953 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012954
Victor Stinner8c62be82010-05-06 00:08:46 +000012955 /* Initialize environ dictionary */
12956 v = convertenviron();
12957 Py_XINCREF(v);
12958 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12959 return NULL;
12960 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012961
Victor Stinner8c62be82010-05-06 00:08:46 +000012962 if (all_ins(m))
12963 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012964
Victor Stinner8c62be82010-05-06 00:08:46 +000012965 if (setup_confname_tables(m))
12966 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012967
Victor Stinner8c62be82010-05-06 00:08:46 +000012968 Py_INCREF(PyExc_OSError);
12969 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012970
Guido van Rossumb3d39562000-01-31 18:41:26 +000012971#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012972 if (posix_putenv_garbage == NULL)
12973 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012974#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012975
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012977#if defined(HAVE_WAITID) && !defined(__APPLE__)
12978 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012979 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12980 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012981#endif
12982
Christian Heimes25827622013-10-12 01:27:08 +020012983 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012984 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12985 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12986 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012987 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12988 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 structseq_new = StatResultType.tp_new;
12990 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012991
Christian Heimes25827622013-10-12 01:27:08 +020012992 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012993 if (PyStructSequence_InitType2(&StatVFSResultType,
12994 &statvfs_result_desc) < 0)
12995 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012996#ifdef NEED_TICKS_PER_SECOND
12997# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012998 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012999# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013000 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013001# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013002 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013003# endif
13004#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013005
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013006#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013007 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013008 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13009 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013010 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013011#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013012
13013 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013014 if (PyStructSequence_InitType2(&TerminalSizeType,
13015 &TerminalSize_desc) < 0)
13016 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013017
13018 /* initialize scandir types */
13019 if (PyType_Ready(&ScandirIteratorType) < 0)
13020 return NULL;
13021 if (PyType_Ready(&DirEntryType) < 0)
13022 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013023 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013024#if defined(HAVE_WAITID) && !defined(__APPLE__)
13025 Py_INCREF((PyObject*) &WaitidResultType);
13026 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13027#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013028 Py_INCREF((PyObject*) &StatResultType);
13029 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13030 Py_INCREF((PyObject*) &StatVFSResultType);
13031 PyModule_AddObject(m, "statvfs_result",
13032 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013033
13034#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013035 Py_INCREF(&SchedParamType);
13036 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013037#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013038
Larry Hastings605a62d2012-06-24 04:33:36 -070013039 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013040 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13041 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013042 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13043
13044 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013045 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13046 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013047 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13048
Thomas Wouters477c8d52006-05-27 19:21:47 +000013049#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013050 /*
13051 * Step 2 of weak-linking support on Mac OS X.
13052 *
13053 * The code below removes functions that are not available on the
13054 * currently active platform.
13055 *
13056 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013057 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013058 * OSX 10.4.
13059 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013060#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013061 if (fstatvfs == NULL) {
13062 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13063 return NULL;
13064 }
13065 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013066#endif /* HAVE_FSTATVFS */
13067
13068#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013069 if (statvfs == NULL) {
13070 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13071 return NULL;
13072 }
13073 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013074#endif /* HAVE_STATVFS */
13075
13076# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013077 if (lchown == NULL) {
13078 if (PyObject_DelAttrString(m, "lchown") == -1) {
13079 return NULL;
13080 }
13081 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013082#endif /* HAVE_LCHOWN */
13083
13084
13085#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013086
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013087 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013088 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13089
Larry Hastings6fe20b32012-04-19 15:07:49 -070013090 billion = PyLong_FromLong(1000000000);
13091 if (!billion)
13092 return NULL;
13093
Larry Hastings9cf065c2012-06-22 16:30:09 -070013094 /* suppress "function not used" warnings */
13095 {
13096 int ignored;
13097 fd_specified("", -1);
13098 follow_symlinks_specified("", 1);
13099 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13100 dir_fd_converter(Py_None, &ignored);
13101 dir_fd_unavailable(Py_None, &ignored);
13102 }
13103
13104 /*
13105 * provide list of locally available functions
13106 * so os.py can populate support_* lists
13107 */
13108 list = PyList_New(0);
13109 if (!list)
13110 return NULL;
13111 for (trace = have_functions; *trace; trace++) {
13112 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13113 if (!unicode)
13114 return NULL;
13115 if (PyList_Append(list, unicode))
13116 return NULL;
13117 Py_DECREF(unicode);
13118 }
13119 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013120
13121 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013122 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013123
13124 initialized = 1;
13125
Victor Stinner8c62be82010-05-06 00:08:46 +000013126 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013127}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013128
13129#ifdef __cplusplus
13130}
13131#endif