blob: 0ae06eb53eaef9d86dab7bc33413c29b78f40591 [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
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000090#ifdef HAVE_SYS_SENDFILE_H
91#include <sys/sendfile.h>
92#endif
93
Benjamin Peterson94b580d2011-08-02 17:30:04 -050094#ifdef HAVE_SCHED_H
95#include <sched.h>
96#endif
97
Benjamin Peterson2dbda072012-03-16 10:12:55 -050098#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050099#undef HAVE_SCHED_SETAFFINITY
100#endif
101
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200102#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400103#define USE_XATTRS
104#endif
105
106#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400107#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400108#endif
109
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
111#ifdef HAVE_SYS_SOCKET_H
112#include <sys/socket.h>
113#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#endif
115
Victor Stinner8b905bd2011-10-25 13:34:04 +0200116#ifdef HAVE_DLFCN_H
117#include <dlfcn.h>
118#endif
119
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200120#ifdef __hpux
121#include <sys/mpctl.h>
122#endif
123
124#if defined(__DragonFly__) || \
125 defined(__OpenBSD__) || \
126 defined(__FreeBSD__) || \
127 defined(__NetBSD__) || \
128 defined(__APPLE__)
129#include <sys/sysctl.h>
130#endif
131
Victor Stinner9b1f4742016-09-06 16:18:52 -0700132#ifdef HAVE_LINUX_RANDOM_H
133# include <linux/random.h>
134#endif
135#ifdef HAVE_GETRANDOM_SYSCALL
136# include <sys/syscall.h>
137#endif
138
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100139#if defined(MS_WINDOWS)
140# define TERMSIZE_USE_CONIO
141#elif defined(HAVE_SYS_IOCTL_H)
142# include <sys/ioctl.h>
143# if defined(HAVE_TERMIOS_H)
144# include <termios.h>
145# endif
146# if defined(TIOCGWINSZ)
147# define TERMSIZE_USE_IOCTL
148# endif
149#endif /* MS_WINDOWS */
150
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000152/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#include <process.h>
157#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000159#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000160#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700163#define HAVE_WSPAWNV 1
164#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000166#define HAVE_SYSTEM 1
167#define HAVE_CWAIT 1
168#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000169#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000170#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171/* Unix functions that the configure script doesn't check for */
172#define HAVE_EXECV 1
173#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000175#define HAVE_FORK1 1
176#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#define HAVE_GETEGID 1
178#define HAVE_GETEUID 1
179#define HAVE_GETGID 1
180#define HAVE_GETPPID 1
181#define HAVE_GETUID 1
182#define HAVE_KILL 1
183#define HAVE_OPENDIR 1
184#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000186#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000187#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000189#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000190
Victor Stinnera2f7c002012-02-08 03:36:25 +0100191
Larry Hastings61272b72014-01-07 12:41:53 -0800192/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000193# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800194module os
Larry Hastings61272b72014-01-07 12:41:53 -0800195[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000196/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100197
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000199
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000200#if defined(__sgi)&&_COMPILER_VERSION>=700
201/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
202 (default) */
203extern char *ctermid_r(char *);
204#endif
205
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000206#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000207#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000210#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000211extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000214#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000215#endif
216#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chdir(char *);
218extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000220extern int chdir(const char *);
221extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000222#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000223extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000224/*#ifdef HAVE_FCHMOD
225extern int fchmod(int, mode_t);
226#endif*/
227/*#ifdef HAVE_LCHMOD
228extern int lchmod(const char *, mode_t);
229#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000230extern int chown(const char *, uid_t, gid_t);
231extern char *getcwd(char *, int);
232extern char *strerror(int);
233extern int link(const char *, const char *);
234extern int rename(const char *, const char *);
235extern int stat(const char *, struct stat *);
236extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000238extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000239#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000241extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000244
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#ifdef HAVE_UTIME_H
248#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000249#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000251#ifdef HAVE_SYS_UTIME_H
252#include <sys/utime.h>
253#define HAVE_UTIME_H /* pretend we do for the rest of this file */
254#endif /* HAVE_SYS_UTIME_H */
255
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#ifdef HAVE_SYS_TIMES_H
257#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000258#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259
260#ifdef HAVE_SYS_PARAM_H
261#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef HAVE_SYS_UTSNAME_H
265#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#define NAMLEN(dirent) strlen((dirent)->d_name)
271#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000272#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#include <direct.h>
274#define NAMLEN(dirent) strlen((dirent)->d_name)
275#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000277#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000278#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#endif
282#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000284#endif
285#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000287#endif
288#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000290#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000292#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293#endif
294#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000296#endif
297#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000299#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000301#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000302#endif
303#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000304#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000305#endif
306#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000307#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000308#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100309#ifndef IO_REPARSE_TAG_MOUNT_POINT
310#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
311#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000313#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000315#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000316#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000317#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
318#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000319static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000320#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000321#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000322
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#if defined(PATH_MAX) && PATH_MAX > 1024
325#define MAXPATHLEN PATH_MAX
326#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#endif /* MAXPATHLEN */
330
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000331#ifdef UNION_WAIT
332/* Emulate some macros on systems that have a union instead of macros */
333
334#ifndef WIFEXITED
335#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
336#endif
337
338#ifndef WEXITSTATUS
339#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
340#endif
341
342#ifndef WTERMSIG
343#define WTERMSIG(u_wait) ((u_wait).w_termsig)
344#endif
345
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000346#define WAIT_TYPE union wait
347#define WAIT_STATUS_INT(s) (s.w_status)
348
349#else /* !UNION_WAIT */
350#define WAIT_TYPE int
351#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000352#endif /* UNION_WAIT */
353
Greg Wardb48bc172000-03-01 21:51:56 +0000354/* Don't use the "_r" form if we don't need it (also, won't have a
355 prototype for it, at least on Solaris -- maybe others as well?). */
356#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
357#define USE_CTERMID_R
358#endif
359
Fred Drake699f3522000-06-29 21:12:41 +0000360/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000361#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000362#undef FSTAT
363#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200364#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700366# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200367# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800368# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000369#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000370# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700371# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000372# define FSTAT fstat
373# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000374#endif
375
Tim Peters11b23062003-04-23 02:39:17 +0000376#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000377#include <sys/mkdev.h>
378#else
379#if defined(MAJOR_IN_SYSMACROS)
380#include <sys/sysmacros.h>
381#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000382#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
383#include <sys/mkdev.h>
384#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000385#endif
Fred Drake699f3522000-06-29 21:12:41 +0000386
Victor Stinner6edddfa2013-11-24 19:22:57 +0100387#define DWORD_MAX 4294967295U
388
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200389#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100390#define INITFUNC PyInit_nt
391#define MODNAME "nt"
392#else
393#define INITFUNC PyInit_posix
394#define MODNAME "posix"
395#endif
396
397#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200398/* defined in fileutils.c */
399PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
400PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
401 ULONG, struct _Py_stat_struct *);
402#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700403
404#ifdef MS_WINDOWS
405static int
406win32_warn_bytes_api()
407{
408 return PyErr_WarnEx(PyExc_DeprecationWarning,
409 "The Windows bytes API has been deprecated, "
410 "use Unicode filenames instead",
411 1);
412}
413#endif
414
415
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200416#ifndef MS_WINDOWS
417PyObject *
418_PyLong_FromUid(uid_t uid)
419{
420 if (uid == (uid_t)-1)
421 return PyLong_FromLong(-1);
422 return PyLong_FromUnsignedLong(uid);
423}
424
425PyObject *
426_PyLong_FromGid(gid_t gid)
427{
428 if (gid == (gid_t)-1)
429 return PyLong_FromLong(-1);
430 return PyLong_FromUnsignedLong(gid);
431}
432
433int
434_Py_Uid_Converter(PyObject *obj, void *p)
435{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700436 uid_t uid;
437 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200438 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200439 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700440 unsigned long uresult;
441
442 index = PyNumber_Index(obj);
443 if (index == NULL) {
444 PyErr_Format(PyExc_TypeError,
445 "uid should be integer, not %.200s",
446 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200447 return 0;
448 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700449
450 /*
451 * Handling uid_t is complicated for two reasons:
452 * * Although uid_t is (always?) unsigned, it still
453 * accepts -1.
454 * * We don't know its size in advance--it may be
455 * bigger than an int, or it may be smaller than
456 * a long.
457 *
458 * So a bit of defensive programming is in order.
459 * Start with interpreting the value passed
460 * in as a signed long and see if it works.
461 */
462
463 result = PyLong_AsLongAndOverflow(index, &overflow);
464
465 if (!overflow) {
466 uid = (uid_t)result;
467
468 if (result == -1) {
469 if (PyErr_Occurred())
470 goto fail;
471 /* It's a legitimate -1, we're done. */
472 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200473 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700474
475 /* Any other negative number is disallowed. */
476 if (result < 0)
477 goto underflow;
478
479 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200480 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700481 (long)uid != result)
482 goto underflow;
483 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200484 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700485
486 if (overflow < 0)
487 goto underflow;
488
489 /*
490 * Okay, the value overflowed a signed long. If it
491 * fits in an *unsigned* long, it may still be okay,
492 * as uid_t may be unsigned long on this platform.
493 */
494 uresult = PyLong_AsUnsignedLong(index);
495 if (PyErr_Occurred()) {
496 if (PyErr_ExceptionMatches(PyExc_OverflowError))
497 goto overflow;
498 goto fail;
499 }
500
501 uid = (uid_t)uresult;
502
503 /*
504 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
505 * but this value would get interpreted as (uid_t)-1 by chown
506 * and its siblings. That's not what the user meant! So we
507 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100508 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700509 */
510 if (uid == (uid_t)-1)
511 goto overflow;
512
513 /* Ensure the value wasn't truncated. */
514 if (sizeof(uid_t) < sizeof(long) &&
515 (unsigned long)uid != uresult)
516 goto overflow;
517 /* fallthrough */
518
519success:
520 Py_DECREF(index);
521 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 return 1;
523
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200525 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 "uid is less than minimum");
527 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200528
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700529overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200530 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700531 "uid is greater than maximum");
532 /* fallthrough */
533
534fail:
535 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200536 return 0;
537}
538
539int
540_Py_Gid_Converter(PyObject *obj, void *p)
541{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700542 gid_t gid;
543 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200544 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200545 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700546 unsigned long uresult;
547
548 index = PyNumber_Index(obj);
549 if (index == NULL) {
550 PyErr_Format(PyExc_TypeError,
551 "gid should be integer, not %.200s",
552 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200553 return 0;
554 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700555
556 /*
557 * Handling gid_t is complicated for two reasons:
558 * * Although gid_t is (always?) unsigned, it still
559 * accepts -1.
560 * * We don't know its size in advance--it may be
561 * bigger than an int, or it may be smaller than
562 * a long.
563 *
564 * So a bit of defensive programming is in order.
565 * Start with interpreting the value passed
566 * in as a signed long and see if it works.
567 */
568
569 result = PyLong_AsLongAndOverflow(index, &overflow);
570
571 if (!overflow) {
572 gid = (gid_t)result;
573
574 if (result == -1) {
575 if (PyErr_Occurred())
576 goto fail;
577 /* It's a legitimate -1, we're done. */
578 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200579 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700580
581 /* Any other negative number is disallowed. */
582 if (result < 0) {
583 goto underflow;
584 }
585
586 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200587 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700588 (long)gid != result)
589 goto underflow;
590 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592
593 if (overflow < 0)
594 goto underflow;
595
596 /*
597 * Okay, the value overflowed a signed long. If it
598 * fits in an *unsigned* long, it may still be okay,
599 * as gid_t may be unsigned long on this platform.
600 */
601 uresult = PyLong_AsUnsignedLong(index);
602 if (PyErr_Occurred()) {
603 if (PyErr_ExceptionMatches(PyExc_OverflowError))
604 goto overflow;
605 goto fail;
606 }
607
608 gid = (gid_t)uresult;
609
610 /*
611 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
612 * but this value would get interpreted as (gid_t)-1 by chown
613 * and its siblings. That's not what the user meant! So we
614 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100615 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700616 */
617 if (gid == (gid_t)-1)
618 goto overflow;
619
620 /* Ensure the value wasn't truncated. */
621 if (sizeof(gid_t) < sizeof(long) &&
622 (unsigned long)gid != uresult)
623 goto overflow;
624 /* fallthrough */
625
626success:
627 Py_DECREF(index);
628 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200629 return 1;
630
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700631underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700633 "gid is less than minimum");
634 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200635
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700636overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200637 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700638 "gid is greater than maximum");
639 /* fallthrough */
640
641fail:
642 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200643 return 0;
644}
645#endif /* MS_WINDOWS */
646
647
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700648#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800649
650
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200651#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
652static int
653_Py_Dev_Converter(PyObject *obj, void *p)
654{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200655 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200656 if (PyErr_Occurred())
657 return 0;
658 return 1;
659}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800660#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200661
662
Larry Hastings9cf065c2012-06-22 16:30:09 -0700663#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400664/*
665 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
666 * without the int cast, the value gets interpreted as uint (4291925331),
667 * which doesn't play nicely with all the initializer lines in this file that
668 * look like this:
669 * int dir_fd = DEFAULT_DIR_FD;
670 */
671#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700672#else
673#define DEFAULT_DIR_FD (-100)
674#endif
675
676static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300677_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200678{
679 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 long long_value;
681
682 PyObject *index = PyNumber_Index(o);
683 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700684 return 0;
685 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700686
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300687 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700688 long_value = PyLong_AsLongAndOverflow(index, &overflow);
689 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300690 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200691 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700692 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700693 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700694 return 0;
695 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200696 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700697 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700698 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700699 return 0;
700 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700701
Larry Hastings9cf065c2012-06-22 16:30:09 -0700702 *p = (int)long_value;
703 return 1;
704}
705
706static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200707dir_fd_converter(PyObject *o, void *p)
708{
709 if (o == Py_None) {
710 *(int *)p = DEFAULT_DIR_FD;
711 return 1;
712 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300713 else if (PyIndex_Check(o)) {
714 return _fd_converter(o, (int *)p);
715 }
716 else {
717 PyErr_Format(PyExc_TypeError,
718 "argument should be integer or None, not %.200s",
719 Py_TYPE(o)->tp_name);
720 return 0;
721 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700722}
723
724
Larry Hastings9cf065c2012-06-22 16:30:09 -0700725/*
726 * A PyArg_ParseTuple "converter" function
727 * that handles filesystem paths in the manner
728 * preferred by the os module.
729 *
730 * path_converter accepts (Unicode) strings and their
731 * subclasses, and bytes and their subclasses. What
732 * it does with the argument depends on the platform:
733 *
734 * * On Windows, if we get a (Unicode) string we
735 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700736 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700737 *
738 * * On all other platforms, strings are encoded
739 * to bytes using PyUnicode_FSConverter, then we
740 * extract the char * from the bytes object and
741 * return that.
742 *
743 * path_converter also optionally accepts signed
744 * integers (representing open file descriptors) instead
745 * of path strings.
746 *
747 * Input fields:
748 * path.nullable
749 * If nonzero, the path is permitted to be None.
750 * path.allow_fd
751 * If nonzero, the path is permitted to be a file handle
752 * (a signed int) instead of a string.
753 * path.function_name
754 * If non-NULL, path_converter will use that as the name
755 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700756 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700757 * path.argument_name
758 * If non-NULL, path_converter will use that as the name
759 * of the parameter in error messages.
760 * (If path.argument_name is NULL it uses "path".)
761 *
762 * Output fields:
763 * path.wide
764 * Points to the path if it was expressed as Unicode
765 * and was not encoded. (Only used on Windows.)
766 * path.narrow
767 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700768 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000769 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700770 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700771 * path.fd
772 * Contains a file descriptor if path.accept_fd was true
773 * and the caller provided a signed integer instead of any
774 * sort of string.
775 *
776 * WARNING: if your "path" parameter is optional, and is
777 * unspecified, path_converter will never get called.
778 * So if you set allow_fd, you *MUST* initialize path.fd = -1
779 * yourself!
780 * path.length
781 * The length of the path in characters, if specified as
782 * a string.
783 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800784 * The original object passed in (if get a PathLike object,
785 * the result of PyOS_FSPath() is treated as the original object).
786 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700787 * path.cleanup
788 * For internal use only. May point to a temporary object.
789 * (Pay no attention to the man behind the curtain.)
790 *
791 * At most one of path.wide or path.narrow will be non-NULL.
792 * If path was None and path.nullable was set,
793 * or if path was an integer and path.allow_fd was set,
794 * both path.wide and path.narrow will be NULL
795 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200796 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700797 * path_converter takes care to not write to the path_t
798 * unless it's successful. However it must reset the
799 * "cleanup" field each time it's called.
800 *
801 * Use as follows:
802 * path_t path;
803 * memset(&path, 0, sizeof(path));
804 * PyArg_ParseTuple(args, "O&", path_converter, &path);
805 * // ... use values from path ...
806 * path_cleanup(&path);
807 *
808 * (Note that if PyArg_Parse fails you don't need to call
809 * path_cleanup(). However it is safe to do so.)
810 */
811typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100812 const char *function_name;
813 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700814 int nullable;
815 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300816 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700817#ifdef MS_WINDOWS
818 BOOL narrow;
819#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300820 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700821#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700822 int fd;
823 Py_ssize_t length;
824 PyObject *object;
825 PyObject *cleanup;
826} path_t;
827
Steve Dowercc16be82016-09-08 10:35:16 -0700828#ifdef MS_WINDOWS
829#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
830 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
831#else
Larry Hastings2f936352014-08-05 14:04:04 +1000832#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
833 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700834#endif
Larry Hastings31826802013-10-19 00:09:25 -0700835
Larry Hastings9cf065c2012-06-22 16:30:09 -0700836static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800837path_cleanup(path_t *path)
838{
839 Py_CLEAR(path->object);
840 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700841}
842
843static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300844path_converter(PyObject *o, void *p)
845{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700846 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800847 PyObject *bytes = NULL;
848 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700849 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300850 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700851#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800852 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700853 const wchar_t *wide;
854#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700855
856#define FORMAT_EXCEPTION(exc, fmt) \
857 PyErr_Format(exc, "%s%s" fmt, \
858 path->function_name ? path->function_name : "", \
859 path->function_name ? ": " : "", \
860 path->argument_name ? path->argument_name : "path")
861
862 /* Py_CLEANUP_SUPPORTED support */
863 if (o == NULL) {
864 path_cleanup(path);
865 return 1;
866 }
867
Brett Cannon3f9183b2016-08-26 14:44:48 -0700868 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800869 path->object = path->cleanup = NULL;
870 /* path->object owns a reference to the original object */
871 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700872
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300873 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700874 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700875#ifdef MS_WINDOWS
876 path->narrow = FALSE;
877#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700878 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700879#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800881 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 }
883
Brett Cannon3f9183b2016-08-26 14:44:48 -0700884 /* Only call this here so that we don't treat the return value of
885 os.fspath() as an fd or buffer. */
886 is_index = path->allow_fd && PyIndex_Check(o);
887 is_buffer = PyObject_CheckBuffer(o);
888 is_bytes = PyBytes_Check(o);
889 is_unicode = PyUnicode_Check(o);
890
891 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
892 /* Inline PyOS_FSPath() for better error messages. */
893 _Py_IDENTIFIER(__fspath__);
894 PyObject *func = NULL;
895
896 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
897 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800898 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700899 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800900 /* still owns a reference to the original object */
901 Py_DECREF(o);
902 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700903 Py_DECREF(func);
904 if (NULL == o) {
905 goto error_exit;
906 }
907 else if (PyUnicode_Check(o)) {
908 is_unicode = 1;
909 }
910 else if (PyBytes_Check(o)) {
911 is_bytes = 1;
912 }
913 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800914 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700915 }
916 }
917
918 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700919#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +0200920 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100921 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800922 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700923 }
Victor Stinner59799a82013-11-13 14:17:30 +0100924 if (length > 32767) {
925 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +0800926 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700927 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300928 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300929 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +0800930 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300931 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700932
933 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +0800934 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800936 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300938 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800939 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300940 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941#endif
942 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700943 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300944 bytes = o;
945 Py_INCREF(bytes);
946 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700947 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300948 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
949 "%s%s%s should be %s, not %.200s",
950 path->function_name ? path->function_name : "",
951 path->function_name ? ": " : "",
952 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700953 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
954 "integer or None" :
955 path->allow_fd ? "string, bytes, os.PathLike or integer" :
956 path->nullable ? "string, bytes, os.PathLike or None" :
957 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300958 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800959 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300960 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300961 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800963 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 }
965 }
Steve Dowercc16be82016-09-08 10:35:16 -0700966 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300967 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800968 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300969 }
970 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700971#ifdef MS_WINDOWS
972 path->narrow = FALSE;
973#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300974 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700975#endif
Xiang Zhang04316c42017-01-08 23:26:57 +0800976 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300977 }
978 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800979 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300980 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
981 path->function_name ? path->function_name : "",
982 path->function_name ? ": " : "",
983 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700984 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
985 "integer or None" :
986 path->allow_fd ? "string, bytes, os.PathLike or integer" :
987 path->nullable ? "string, bytes, os.PathLike or None" :
988 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300989 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +0800990 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991 }
992
Larry Hastings9cf065c2012-06-22 16:30:09 -0700993 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700994 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200995 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300996 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +0800997 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700998 }
999
Steve Dowercc16be82016-09-08 10:35:16 -07001000#ifdef MS_WINDOWS
1001 wo = PyUnicode_DecodeFSDefaultAndSize(
1002 narrow,
1003 length
1004 );
1005 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001006 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001007 }
1008
Xiang Zhang04316c42017-01-08 23:26:57 +08001009 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001010 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001011 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001012 }
1013 if (length > 32767) {
1014 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001015 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001016 }
1017 if (wcslen(wide) != length) {
1018 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001019 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001020 }
1021 path->wide = wide;
1022 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001023 path->cleanup = wo;
1024 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001025#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001026 path->wide = NULL;
1027 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001028 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001029 /* Still a reference owned by path->object, don't have to
1030 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001031 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001032 }
1033 else {
1034 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001035 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001036#endif
1037 path->fd = -1;
1038
1039 success_exit:
1040 path->length = length;
1041 path->object = o;
1042 return Py_CLEANUP_SUPPORTED;
1043
1044 error_exit:
1045 Py_XDECREF(o);
1046 Py_XDECREF(bytes);
1047#ifdef MS_WINDOWS
1048 Py_XDECREF(wo);
1049#endif
1050 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001051}
1052
1053static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001054argument_unavailable_error(const char *function_name, const char *argument_name)
1055{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001056 PyErr_Format(PyExc_NotImplementedError,
1057 "%s%s%s unavailable on this platform",
1058 (function_name != NULL) ? function_name : "",
1059 (function_name != NULL) ? ": ": "",
1060 argument_name);
1061}
1062
1063static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001064dir_fd_unavailable(PyObject *o, void *p)
1065{
1066 int dir_fd;
1067 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001068 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001069 if (dir_fd != DEFAULT_DIR_FD) {
1070 argument_unavailable_error(NULL, "dir_fd");
1071 return 0;
1072 }
1073 *(int *)p = dir_fd;
1074 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001075}
1076
1077static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001078fd_specified(const char *function_name, int fd)
1079{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001080 if (fd == -1)
1081 return 0;
1082
1083 argument_unavailable_error(function_name, "fd");
1084 return 1;
1085}
1086
1087static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001088follow_symlinks_specified(const char *function_name, int follow_symlinks)
1089{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 if (follow_symlinks)
1091 return 0;
1092
1093 argument_unavailable_error(function_name, "follow_symlinks");
1094 return 1;
1095}
1096
1097static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001098path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1099{
Steve Dowercc16be82016-09-08 10:35:16 -07001100 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1101#ifndef MS_WINDOWS
1102 && !path->narrow
1103#endif
1104 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001105 PyErr_Format(PyExc_ValueError,
1106 "%s: can't specify dir_fd without matching path",
1107 function_name);
1108 return 1;
1109 }
1110 return 0;
1111}
1112
1113static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001114dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1115{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001116 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1117 PyErr_Format(PyExc_ValueError,
1118 "%s: can't specify both dir_fd and fd",
1119 function_name);
1120 return 1;
1121 }
1122 return 0;
1123}
1124
1125static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001126fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1127 int follow_symlinks)
1128{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 if ((fd > 0) && (!follow_symlinks)) {
1130 PyErr_Format(PyExc_ValueError,
1131 "%s: cannot use fd and follow_symlinks together",
1132 function_name);
1133 return 1;
1134 }
1135 return 0;
1136}
1137
1138static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001139dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1140 int follow_symlinks)
1141{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001142 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1143 PyErr_Format(PyExc_ValueError,
1144 "%s: cannot use dir_fd and follow_symlinks together",
1145 function_name);
1146 return 1;
1147 }
1148 return 0;
1149}
1150
Larry Hastings2f936352014-08-05 14:04:04 +10001151#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001152 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001153#else
Larry Hastings2f936352014-08-05 14:04:04 +10001154 typedef off_t Py_off_t;
1155#endif
1156
1157static int
1158Py_off_t_converter(PyObject *arg, void *addr)
1159{
1160#ifdef HAVE_LARGEFILE_SUPPORT
1161 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1162#else
1163 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001164#endif
1165 if (PyErr_Occurred())
1166 return 0;
1167 return 1;
1168}
Larry Hastings2f936352014-08-05 14:04:04 +10001169
1170static PyObject *
1171PyLong_FromPy_off_t(Py_off_t offset)
1172{
1173#ifdef HAVE_LARGEFILE_SUPPORT
1174 return PyLong_FromLongLong(offset);
1175#else
1176 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001177#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001178}
1179
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001180#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001181
1182static int
Brian Curtind25aef52011-06-13 15:16:04 -05001183win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001184{
Martin Panter70214ad2016-08-04 02:38:59 +00001185 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1186 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001187 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001188
1189 if (0 == DeviceIoControl(
1190 reparse_point_handle,
1191 FSCTL_GET_REPARSE_POINT,
1192 NULL, 0, /* in buffer */
1193 target_buffer, sizeof(target_buffer),
1194 &n_bytes_returned,
1195 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001196 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001197
1198 if (reparse_tag)
1199 *reparse_tag = rdb->ReparseTag;
1200
Brian Curtind25aef52011-06-13 15:16:04 -05001201 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001202}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001203
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001204#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001205
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001207#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001208/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001209** environ directly, we must obtain it with _NSGetEnviron(). See also
1210** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001211*/
1212#include <crt_externs.h>
1213static char **environ;
1214#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001216#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001217
Barry Warsaw53699e91996-12-10 23:23:01 +00001218static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001219convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001220{
Victor Stinner8c62be82010-05-06 00:08:46 +00001221 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001222#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001223 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001224#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001226#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001227
Victor Stinner8c62be82010-05-06 00:08:46 +00001228 d = PyDict_New();
1229 if (d == NULL)
1230 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001231#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001232 if (environ == NULL)
1233 environ = *_NSGetEnviron();
1234#endif
1235#ifdef MS_WINDOWS
1236 /* _wenviron must be initialized in this way if the program is started
1237 through main() instead of wmain(). */
1238 _wgetenv(L"");
1239 if (_wenviron == NULL)
1240 return d;
1241 /* This part ignores errors */
1242 for (e = _wenviron; *e != NULL; e++) {
1243 PyObject *k;
1244 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001245 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001246 if (p == NULL)
1247 continue;
1248 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1249 if (k == NULL) {
1250 PyErr_Clear();
1251 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001252 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1254 if (v == NULL) {
1255 PyErr_Clear();
1256 Py_DECREF(k);
1257 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001258 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001259 if (PyDict_GetItem(d, k) == NULL) {
1260 if (PyDict_SetItem(d, k, v) != 0)
1261 PyErr_Clear();
1262 }
1263 Py_DECREF(k);
1264 Py_DECREF(v);
1265 }
1266#else
1267 if (environ == NULL)
1268 return d;
1269 /* This part ignores errors */
1270 for (e = environ; *e != NULL; e++) {
1271 PyObject *k;
1272 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001273 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001274 if (p == NULL)
1275 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001276 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001277 if (k == NULL) {
1278 PyErr_Clear();
1279 continue;
1280 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001281 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 if (v == NULL) {
1283 PyErr_Clear();
1284 Py_DECREF(k);
1285 continue;
1286 }
1287 if (PyDict_GetItem(d, k) == NULL) {
1288 if (PyDict_SetItem(d, k, v) != 0)
1289 PyErr_Clear();
1290 }
1291 Py_DECREF(k);
1292 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001293 }
1294#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001296}
1297
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298/* Set a POSIX-specific error from errno, and return NULL */
1299
Barry Warsawd58d7641998-07-23 16:14:40 +00001300static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001301posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001302{
Victor Stinner8c62be82010-05-06 00:08:46 +00001303 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001304}
Mark Hammondef8b6542001-05-13 08:04:26 +00001305
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001306#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001307static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001308win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001309{
Victor Stinner8c62be82010-05-06 00:08:46 +00001310 /* XXX We should pass the function name along in the future.
1311 (winreg.c also wants to pass the function name.)
1312 This would however require an additional param to the
1313 Windows error object, which is non-trivial.
1314 */
1315 errno = GetLastError();
1316 if (filename)
1317 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1318 else
1319 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001320}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001321
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001322static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001323win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001324{
1325 /* XXX - see win32_error for comments on 'function' */
1326 errno = GetLastError();
1327 if (filename)
1328 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001329 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001330 errno,
1331 filename);
1332 else
1333 return PyErr_SetFromWindowsErr(errno);
1334}
1335
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001336#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337
Larry Hastings9cf065c2012-06-22 16:30:09 -07001338static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001339path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001340{
1341#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001342 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1343 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001344#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001345 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001346#endif
1347}
1348
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001349static PyObject *
1350path_object_error2(PyObject *path, PyObject *path2)
1351{
1352#ifdef MS_WINDOWS
1353 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1354 PyExc_OSError, 0, path, path2);
1355#else
1356 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1357#endif
1358}
1359
1360static PyObject *
1361path_error(path_t *path)
1362{
1363 return path_object_error(path->object);
1364}
Larry Hastings31826802013-10-19 00:09:25 -07001365
Larry Hastingsb0827312014-02-09 22:05:19 -08001366static PyObject *
1367path_error2(path_t *path, path_t *path2)
1368{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001369 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001370}
1371
1372
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001373/* POSIX generic methods */
1374
Larry Hastings2f936352014-08-05 14:04:04 +10001375static int
1376fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001377{
Victor Stinner8c62be82010-05-06 00:08:46 +00001378 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001379 int *pointer = (int *)p;
1380 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001382 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001383 *pointer = fd;
1384 return 1;
1385}
1386
1387static PyObject *
1388posix_fildes_fd(int fd, int (*func)(int))
1389{
1390 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001391 int async_err = 0;
1392
1393 do {
1394 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001395 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001396 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001397 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001398 Py_END_ALLOW_THREADS
1399 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1400 if (res != 0)
1401 return (!async_err) ? posix_error() : NULL;
1402 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001403}
Guido van Rossum21142a01999-01-08 21:05:37 +00001404
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001406#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001407/* This is a reimplementation of the C library's chdir function,
1408 but one that produces Win32 errors instead of DOS error codes.
1409 chdir is essentially a wrapper around SetCurrentDirectory; however,
1410 it also needs to set "magic" environment variables indicating
1411 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001412static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001413win32_wchdir(LPCWSTR path)
1414{
Victor Stinnered537822015-12-13 21:40:26 +01001415 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001416 int result;
1417 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001418
Victor Stinner8c62be82010-05-06 00:08:46 +00001419 if(!SetCurrentDirectoryW(path))
1420 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001421 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001422 if (!result)
1423 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001424 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001425 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 if (!new_path) {
1427 SetLastError(ERROR_OUTOFMEMORY);
1428 return FALSE;
1429 }
1430 result = GetCurrentDirectoryW(result, new_path);
1431 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001432 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001433 return FALSE;
1434 }
1435 }
1436 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1437 wcsncmp(new_path, L"//", 2) == 0)
1438 /* UNC path, nothing to do. */
1439 return TRUE;
1440 env[1] = new_path[0];
1441 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001442 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001443 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001445}
1446#endif
1447
Martin v. Löwis14694662006-02-03 12:54:16 +00001448#ifdef MS_WINDOWS
1449/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1450 - time stamps are restricted to second resolution
1451 - file modification times suffer from forth-and-back conversions between
1452 UTC and local time
1453 Therefore, we implement our own stat, based on the Win32 API directly.
1454*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001455#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001456#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001457
Victor Stinner6036e442015-03-08 01:58:04 +01001458static void
Steve Dowercc16be82016-09-08 10:35:16 -07001459find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1460 BY_HANDLE_FILE_INFORMATION *info,
1461 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001462{
1463 memset(info, 0, sizeof(*info));
1464 info->dwFileAttributes = pFileData->dwFileAttributes;
1465 info->ftCreationTime = pFileData->ftCreationTime;
1466 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1467 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1468 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1469 info->nFileSizeLow = pFileData->nFileSizeLow;
1470/* info->nNumberOfLinks = 1; */
1471 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1472 *reparse_tag = pFileData->dwReserved0;
1473 else
1474 *reparse_tag = 0;
1475}
1476
Guido van Rossumd8faa362007-04-27 19:54:29 +00001477static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001478attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001479{
Victor Stinner8c62be82010-05-06 00:08:46 +00001480 HANDLE hFindFile;
1481 WIN32_FIND_DATAW FileData;
1482 hFindFile = FindFirstFileW(pszFile, &FileData);
1483 if (hFindFile == INVALID_HANDLE_VALUE)
1484 return FALSE;
1485 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001486 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001487 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001488}
1489
Brian Curtind25aef52011-06-13 15:16:04 -05001490static BOOL
1491get_target_path(HANDLE hdl, wchar_t **target_path)
1492{
1493 int buf_size, result_length;
1494 wchar_t *buf;
1495
1496 /* We have a good handle to the target, use it to determine
1497 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001498 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1499 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001500 if(!buf_size)
1501 return FALSE;
1502
Victor Stinnerc36674a2016-03-16 14:30:16 +01001503 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001504 if (!buf) {
1505 SetLastError(ERROR_OUTOFMEMORY);
1506 return FALSE;
1507 }
1508
Steve Dower2ea51c92015-03-20 21:49:12 -07001509 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001510 buf, buf_size, VOLUME_NAME_DOS);
1511
1512 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001513 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001514 return FALSE;
1515 }
1516
1517 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001518 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001519 return FALSE;
1520 }
1521
1522 buf[result_length] = 0;
1523
1524 *target_path = buf;
1525 return TRUE;
1526}
1527
1528static int
Steve Dowercc16be82016-09-08 10:35:16 -07001529win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001530 BOOL traverse)
1531{
Victor Stinner26de69d2011-06-17 15:15:38 +02001532 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001533 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001534 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001535 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001536 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001537 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538
Steve Dowercc16be82016-09-08 10:35:16 -07001539 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001540 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001541 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001542 0, /* share mode */
1543 NULL, /* security attributes */
1544 OPEN_EXISTING,
1545 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001546 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1547 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001548 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001549 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1550 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001551 NULL);
1552
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001553 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001554 /* Either the target doesn't exist, or we don't have access to
1555 get a handle to it. If the former, we need to return an error.
1556 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001557 DWORD lastError = GetLastError();
1558 if (lastError != ERROR_ACCESS_DENIED &&
1559 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001560 return -1;
1561 /* Could not get attributes on open file. Fall back to
1562 reading the directory. */
1563 if (!attributes_from_dir(path, &info, &reparse_tag))
1564 /* Very strange. This should not fail now */
1565 return -1;
1566 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1567 if (traverse) {
1568 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001569 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001570 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001572 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001573 } else {
1574 if (!GetFileInformationByHandle(hFile, &info)) {
1575 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001576 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001577 }
1578 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001579 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1580 return -1;
1581
1582 /* Close the outer open file handle now that we're about to
1583 reopen it with different flags. */
1584 if (!CloseHandle(hFile))
1585 return -1;
1586
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001587 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001588 /* In order to call GetFinalPathNameByHandle we need to open
1589 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001590 hFile2 = CreateFileW(
1591 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1592 NULL, OPEN_EXISTING,
1593 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1594 NULL);
1595 if (hFile2 == INVALID_HANDLE_VALUE)
1596 return -1;
1597
1598 if (!get_target_path(hFile2, &target_path))
1599 return -1;
1600
Steve Dowercc16be82016-09-08 10:35:16 -07001601 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001602 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001603 return code;
1604 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001605 } else
1606 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001608 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609
1610 /* Set S_IEXEC if it is an .exe, .bat, ... */
1611 dot = wcsrchr(path, '.');
1612 if (dot) {
1613 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1614 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1615 result->st_mode |= 0111;
1616 }
1617 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618}
1619
1620static int
Steve Dowercc16be82016-09-08 10:35:16 -07001621win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 /* Protocol violation: we explicitly clear errno, instead of
1624 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001625 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 errno = 0;
1627 return code;
1628}
Brian Curtind25aef52011-06-13 15:16:04 -05001629/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001630
1631 In Posix, stat automatically traverses symlinks and returns the stat
1632 structure for the target. In Windows, the equivalent GetFileAttributes by
1633 default does not traverse symlinks and instead returns attributes for
1634 the symlink.
1635
1636 Therefore, win32_lstat will get the attributes traditionally, and
1637 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001638 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001639
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001640static int
Steve Dowercc16be82016-09-08 10:35:16 -07001641win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001642{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001644}
1645
Victor Stinner8c62be82010-05-06 00:08:46 +00001646static int
Steve Dowercc16be82016-09-08 10:35:16 -07001647win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001648{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001649 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001650}
1651
Martin v. Löwis14694662006-02-03 12:54:16 +00001652#endif /* MS_WINDOWS */
1653
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001654PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001655"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001656This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001657 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001658or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1659\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001660Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1661or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001662\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001663See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001664
1665static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001666 {"st_mode", "protection bits"},
1667 {"st_ino", "inode"},
1668 {"st_dev", "device"},
1669 {"st_nlink", "number of hard links"},
1670 {"st_uid", "user ID of owner"},
1671 {"st_gid", "group ID of owner"},
1672 {"st_size", "total size, in bytes"},
1673 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1674 {NULL, "integer time of last access"},
1675 {NULL, "integer time of last modification"},
1676 {NULL, "integer time of last change"},
1677 {"st_atime", "time of last access"},
1678 {"st_mtime", "time of last modification"},
1679 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001680 {"st_atime_ns", "time of last access in nanoseconds"},
1681 {"st_mtime_ns", "time of last modification in nanoseconds"},
1682 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001683#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001685#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001686#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001688#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001689#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001690 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001691#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001692#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001693 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001694#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001695#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001696 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001697#endif
1698#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001700#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001701#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1702 {"st_file_attributes", "Windows file attribute bits"},
1703#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001704 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001705};
1706
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001707#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001708#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001709#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001710#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001711#endif
1712
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001713#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001714#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1715#else
1716#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1717#endif
1718
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001719#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001720#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1721#else
1722#define ST_RDEV_IDX ST_BLOCKS_IDX
1723#endif
1724
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001725#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1726#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1727#else
1728#define ST_FLAGS_IDX ST_RDEV_IDX
1729#endif
1730
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001731#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001732#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001733#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001734#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001735#endif
1736
1737#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1738#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1739#else
1740#define ST_BIRTHTIME_IDX ST_GEN_IDX
1741#endif
1742
Zachary Ware63f277b2014-06-19 09:46:37 -05001743#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1744#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1745#else
1746#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1747#endif
1748
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001749static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001750 "stat_result", /* name */
1751 stat_result__doc__, /* doc */
1752 stat_result_fields,
1753 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754};
1755
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001756PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001757"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1758This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001759 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001760or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001761\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001762See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001763
1764static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001765 {"f_bsize", },
1766 {"f_frsize", },
1767 {"f_blocks", },
1768 {"f_bfree", },
1769 {"f_bavail", },
1770 {"f_files", },
1771 {"f_ffree", },
1772 {"f_favail", },
1773 {"f_flag", },
1774 {"f_namemax",},
1775 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001776};
1777
1778static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 "statvfs_result", /* name */
1780 statvfs_result__doc__, /* doc */
1781 statvfs_result_fields,
1782 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783};
1784
Ross Lagerwall7807c352011-03-17 20:20:30 +02001785#if defined(HAVE_WAITID) && !defined(__APPLE__)
1786PyDoc_STRVAR(waitid_result__doc__,
1787"waitid_result: Result from waitid.\n\n\
1788This object may be accessed either as a tuple of\n\
1789 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1790or via the attributes si_pid, si_uid, and so on.\n\
1791\n\
1792See os.waitid for more information.");
1793
1794static PyStructSequence_Field waitid_result_fields[] = {
1795 {"si_pid", },
1796 {"si_uid", },
1797 {"si_signo", },
1798 {"si_status", },
1799 {"si_code", },
1800 {0}
1801};
1802
1803static PyStructSequence_Desc waitid_result_desc = {
1804 "waitid_result", /* name */
1805 waitid_result__doc__, /* doc */
1806 waitid_result_fields,
1807 5
1808};
1809static PyTypeObject WaitidResultType;
1810#endif
1811
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001812static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001813static PyTypeObject StatResultType;
1814static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001815#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001816static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001817#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001818static newfunc structseq_new;
1819
1820static PyObject *
1821statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1822{
Victor Stinner8c62be82010-05-06 00:08:46 +00001823 PyStructSequence *result;
1824 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001825
Victor Stinner8c62be82010-05-06 00:08:46 +00001826 result = (PyStructSequence*)structseq_new(type, args, kwds);
1827 if (!result)
1828 return NULL;
1829 /* If we have been initialized from a tuple,
1830 st_?time might be set to None. Initialize it
1831 from the int slots. */
1832 for (i = 7; i <= 9; i++) {
1833 if (result->ob_item[i+3] == Py_None) {
1834 Py_DECREF(Py_None);
1835 Py_INCREF(result->ob_item[i]);
1836 result->ob_item[i+3] = result->ob_item[i];
1837 }
1838 }
1839 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001840}
1841
1842
1843
1844/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001845static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001846
1847PyDoc_STRVAR(stat_float_times__doc__,
1848"stat_float_times([newval]) -> oldval\n\n\
1849Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001850\n\
1851If value is True, future calls to stat() return floats; if it is False,\n\
1852future calls return ints.\n\
1853If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001854
Larry Hastings2f936352014-08-05 14:04:04 +10001855/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001856static PyObject*
1857stat_float_times(PyObject* self, PyObject *args)
1858{
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 int newval = -1;
1860 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1861 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001862 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1863 "stat_float_times() is deprecated",
1864 1))
1865 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001866 if (newval == -1)
1867 /* Return old value */
1868 return PyBool_FromLong(_stat_float_times);
1869 _stat_float_times = newval;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001870 Py_RETURN_NONE;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001871}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001872
Larry Hastings6fe20b32012-04-19 15:07:49 -07001873static PyObject *billion = NULL;
1874
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001875static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001876fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001877{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001878 PyObject *s = _PyLong_FromTime_t(sec);
1879 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1880 PyObject *s_in_ns = NULL;
1881 PyObject *ns_total = NULL;
1882 PyObject *float_s = NULL;
1883
1884 if (!(s && ns_fractional))
1885 goto exit;
1886
1887 s_in_ns = PyNumber_Multiply(s, billion);
1888 if (!s_in_ns)
1889 goto exit;
1890
1891 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1892 if (!ns_total)
1893 goto exit;
1894
Victor Stinner4195b5c2012-02-08 23:03:19 +01001895 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001896 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1897 if (!float_s)
1898 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001899 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001900 else {
1901 float_s = s;
1902 Py_INCREF(float_s);
1903 }
1904
1905 PyStructSequence_SET_ITEM(v, index, s);
1906 PyStructSequence_SET_ITEM(v, index+3, float_s);
1907 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1908 s = NULL;
1909 float_s = NULL;
1910 ns_total = NULL;
1911exit:
1912 Py_XDECREF(s);
1913 Py_XDECREF(ns_fractional);
1914 Py_XDECREF(s_in_ns);
1915 Py_XDECREF(ns_total);
1916 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001917}
1918
Tim Peters5aa91602002-01-30 05:46:57 +00001919/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001920 (used by posix_stat() and posix_fstat()) */
1921static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001922_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001923{
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 unsigned long ansec, mnsec, cnsec;
1925 PyObject *v = PyStructSequence_New(&StatResultType);
1926 if (v == NULL)
1927 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001928
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01001930#if defined(HAVE_LARGEFILE_SUPPORT) || defined(MS_WINDOWS)
1931 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 PyStructSequence_SET_ITEM(v, 1,
Victor Stinner0f6d7332017-03-09 17:34:28 +01001933 PyLong_FromUnsignedLongLong(st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001934#else
Victor Stinner0f6d7332017-03-09 17:34:28 +01001935 Py_BUILD_ASSERT(sizeof(unsigned long) >= sizeof(st->st_ino));
1936 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLong(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)
Xiang Zhang4459e002017-01-22 13:04:17 +08002386 Path to be examined; can be string, bytes, path-like object or
2387 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002388
2389 *
2390
Larry Hastings2f936352014-08-05 14:04:04 +10002391 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002392 If not None, it should be a file descriptor open to a directory,
2393 and path should be a relative string; path will then be relative to
2394 that directory.
2395
2396 follow_symlinks: bool = True
2397 If False, and the last element of the path is a symbolic link,
2398 stat will examine the symbolic link itself instead of the file
2399 the link points to.
2400
2401Perform a stat system call on the given path.
2402
2403dir_fd and follow_symlinks may not be implemented
2404 on your platform. If they are unavailable, using them will raise a
2405 NotImplementedError.
2406
2407It's an error to use dir_fd or follow_symlinks when specifying path as
2408 an open file descriptor.
2409
Larry Hastings61272b72014-01-07 12:41:53 -08002410[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002411
Larry Hastings31826802013-10-19 00:09:25 -07002412static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002413os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002414/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002415{
2416 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2417}
2418
Larry Hastings2f936352014-08-05 14:04:04 +10002419
2420/*[clinic input]
2421os.lstat
2422
2423 path : path_t
2424
2425 *
2426
2427 dir_fd : dir_fd(requires='fstatat') = None
2428
2429Perform a stat system call on the given path, without following symbolic links.
2430
2431Like stat(), but do not follow symbolic links.
2432Equivalent to stat(path, follow_symlinks=False).
2433[clinic start generated code]*/
2434
Larry Hastings2f936352014-08-05 14:04:04 +10002435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002436os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2437/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002438{
2439 int follow_symlinks = 0;
2440 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2441}
Larry Hastings31826802013-10-19 00:09:25 -07002442
Larry Hastings2f936352014-08-05 14:04:04 +10002443
Larry Hastings61272b72014-01-07 12:41:53 -08002444/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002445os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002446
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002447 path: path_t
2448 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002449
2450 mode: int
2451 Operating-system mode bitfield. Can be F_OK to test existence,
2452 or the inclusive-OR of R_OK, W_OK, and X_OK.
2453
2454 *
2455
Larry Hastings2f936352014-08-05 14:04:04 +10002456 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002457 If not None, it should be a file descriptor open to a directory,
2458 and path should be relative; path will then be relative to that
2459 directory.
2460
2461 effective_ids: bool = False
2462 If True, access will use the effective uid/gid instead of
2463 the real uid/gid.
2464
2465 follow_symlinks: bool = True
2466 If False, and the last element of the path is a symbolic link,
2467 access will examine the symbolic link itself instead of the file
2468 the link points to.
2469
2470Use the real uid/gid to test for access to a path.
2471
2472{parameters}
2473dir_fd, effective_ids, and follow_symlinks may not be implemented
2474 on your platform. If they are unavailable, using them will raise a
2475 NotImplementedError.
2476
2477Note that most operations will use the effective uid/gid, therefore this
2478 routine can be used in a suid/sgid environment to test if the invoking user
2479 has the specified access to the path.
2480
Larry Hastings61272b72014-01-07 12:41:53 -08002481[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002482
Larry Hastings2f936352014-08-05 14:04:04 +10002483static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002484os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002485 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002486/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002487{
Larry Hastings2f936352014-08-05 14:04:04 +10002488 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002489
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002490#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002491 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002492#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002493 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002494#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002495
Larry Hastings9cf065c2012-06-22 16:30:09 -07002496#ifndef HAVE_FACCESSAT
2497 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002498 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002499
2500 if (effective_ids) {
2501 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002502 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002503 }
2504#endif
2505
2506#ifdef MS_WINDOWS
2507 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002508 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002509 Py_END_ALLOW_THREADS
2510
2511 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002512 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002513 * * we didn't get a -1, and
2514 * * write access wasn't requested,
2515 * * or the file isn't read-only,
2516 * * or it's a directory.
2517 * (Directories cannot be read-only on Windows.)
2518 */
Larry Hastings2f936352014-08-05 14:04:04 +10002519 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002520 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002522 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002523#else
2524
2525 Py_BEGIN_ALLOW_THREADS
2526#ifdef HAVE_FACCESSAT
2527 if ((dir_fd != DEFAULT_DIR_FD) ||
2528 effective_ids ||
2529 !follow_symlinks) {
2530 int flags = 0;
2531 if (!follow_symlinks)
2532 flags |= AT_SYMLINK_NOFOLLOW;
2533 if (effective_ids)
2534 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002535 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002536 }
2537 else
2538#endif
Larry Hastings31826802013-10-19 00:09:25 -07002539 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002540 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002541 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542#endif
2543
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002545}
2546
Guido van Rossumd371ff11999-01-25 16:12:23 +00002547#ifndef F_OK
2548#define F_OK 0
2549#endif
2550#ifndef R_OK
2551#define R_OK 4
2552#endif
2553#ifndef W_OK
2554#define W_OK 2
2555#endif
2556#ifndef X_OK
2557#define X_OK 1
2558#endif
2559
Larry Hastings31826802013-10-19 00:09:25 -07002560
Guido van Rossumd371ff11999-01-25 16:12:23 +00002561#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002562/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002563os.ttyname -> DecodeFSDefault
2564
2565 fd: int
2566 Integer file descriptor handle.
2567
2568 /
2569
2570Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002571[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002572
Larry Hastings31826802013-10-19 00:09:25 -07002573static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002574os_ttyname_impl(PyObject *module, int fd)
2575/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002576{
2577 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002578
Larry Hastings31826802013-10-19 00:09:25 -07002579 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002580 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002581 posix_error();
2582 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002583}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002584#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002585
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002586#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002587/*[clinic input]
2588os.ctermid
2589
2590Return the name of the controlling terminal for this process.
2591[clinic start generated code]*/
2592
Larry Hastings2f936352014-08-05 14:04:04 +10002593static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002594os_ctermid_impl(PyObject *module)
2595/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002596{
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 char *ret;
2598 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002599
Greg Wardb48bc172000-03-01 21:51:56 +00002600#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002601 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002602#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002604#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002605 if (ret == NULL)
2606 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002607 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002608}
Larry Hastings2f936352014-08-05 14:04:04 +10002609#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002610
Larry Hastings2f936352014-08-05 14:04:04 +10002611
2612/*[clinic input]
2613os.chdir
2614
2615 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2616
2617Change the current working directory to the specified path.
2618
2619path may always be specified as a string.
2620On some platforms, path may also be specified as an open file descriptor.
2621 If this functionality is unavailable, using it raises an exception.
2622[clinic start generated code]*/
2623
Larry Hastings2f936352014-08-05 14:04:04 +10002624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002625os_chdir_impl(PyObject *module, path_t *path)
2626/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002627{
2628 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002629
2630 Py_BEGIN_ALLOW_THREADS
2631#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002632 /* on unix, success = 0, on windows, success = !0 */
2633 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634#else
2635#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002636 if (path->fd != -1)
2637 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002638 else
2639#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002640 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641#endif
2642 Py_END_ALLOW_THREADS
2643
2644 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002645 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646 }
2647
Larry Hastings2f936352014-08-05 14:04:04 +10002648 Py_RETURN_NONE;
2649}
2650
2651
2652#ifdef HAVE_FCHDIR
2653/*[clinic input]
2654os.fchdir
2655
2656 fd: fildes
2657
2658Change to the directory of the given file descriptor.
2659
2660fd must be opened on a directory, not a file.
2661Equivalent to os.chdir(fd).
2662
2663[clinic start generated code]*/
2664
Fred Drake4d1e64b2002-04-15 19:40:07 +00002665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002666os_fchdir_impl(PyObject *module, int fd)
2667/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002668{
Larry Hastings2f936352014-08-05 14:04:04 +10002669 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002670}
2671#endif /* HAVE_FCHDIR */
2672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002673
Larry Hastings2f936352014-08-05 14:04:04 +10002674/*[clinic input]
2675os.chmod
2676
2677 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2678 Path to be modified. May always be specified as a str or bytes.
2679 On some platforms, path may also be specified as an open file descriptor.
2680 If this functionality is unavailable, using it raises an exception.
2681
2682 mode: int
2683 Operating-system mode bitfield.
2684
2685 *
2686
2687 dir_fd : dir_fd(requires='fchmodat') = None
2688 If not None, it should be a file descriptor open to a directory,
2689 and path should be relative; path will then be relative to that
2690 directory.
2691
2692 follow_symlinks: bool = True
2693 If False, and the last element of the path is a symbolic link,
2694 chmod will modify the symbolic link itself instead of the file
2695 the link points to.
2696
2697Change the access permissions of a file.
2698
2699It is an error to use dir_fd or follow_symlinks when specifying path as
2700 an open file descriptor.
2701dir_fd and follow_symlinks may not be implemented on your platform.
2702 If they are unavailable, using them will raise a NotImplementedError.
2703
2704[clinic start generated code]*/
2705
Larry Hastings2f936352014-08-05 14:04:04 +10002706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002707os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002708 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002709/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002710{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002713#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002714 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002715#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002716
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717#ifdef HAVE_FCHMODAT
2718 int fchmodat_nofollow_unsupported = 0;
2719#endif
2720
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2722 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002723 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724#endif
2725
2726#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002727 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002728 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002729 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002730 result = 0;
2731 else {
2732 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002733 attr &= ~FILE_ATTRIBUTE_READONLY;
2734 else
2735 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002736 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002737 }
2738 Py_END_ALLOW_THREADS
2739
2740 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002741 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002742 }
2743#else /* MS_WINDOWS */
2744 Py_BEGIN_ALLOW_THREADS
2745#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002746 if (path->fd != -1)
2747 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002748 else
2749#endif
2750#ifdef HAVE_LCHMOD
2751 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002752 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753 else
2754#endif
2755#ifdef HAVE_FCHMODAT
2756 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2757 /*
2758 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2759 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002760 * and then says it isn't implemented yet.
2761 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002762 *
2763 * Once it is supported, os.chmod will automatically
2764 * support dir_fd and follow_symlinks=False. (Hopefully.)
2765 * Until then, we need to be careful what exception we raise.
2766 */
Larry Hastings2f936352014-08-05 14:04:04 +10002767 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002768 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2769 /*
2770 * But wait! We can't throw the exception without allowing threads,
2771 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2772 */
2773 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002774 result &&
2775 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2776 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 }
2778 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002779#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002780 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 Py_END_ALLOW_THREADS
2782
2783 if (result) {
2784#ifdef HAVE_FCHMODAT
2785 if (fchmodat_nofollow_unsupported) {
2786 if (dir_fd != DEFAULT_DIR_FD)
2787 dir_fd_and_follow_symlinks_invalid("chmod",
2788 dir_fd, follow_symlinks);
2789 else
2790 follow_symlinks_specified("chmod", follow_symlinks);
2791 }
2792 else
2793#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002794 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795 }
2796#endif
2797
Larry Hastings2f936352014-08-05 14:04:04 +10002798 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002799}
2800
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801
Christian Heimes4e30a842007-11-30 22:12:06 +00002802#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002803/*[clinic input]
2804os.fchmod
2805
2806 fd: int
2807 mode: int
2808
2809Change the access permissions of the file given by file descriptor fd.
2810
2811Equivalent to os.chmod(fd, mode).
2812[clinic start generated code]*/
2813
Larry Hastings2f936352014-08-05 14:04:04 +10002814static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002815os_fchmod_impl(PyObject *module, int fd, int mode)
2816/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002817{
2818 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002819 int async_err = 0;
2820
2821 do {
2822 Py_BEGIN_ALLOW_THREADS
2823 res = fchmod(fd, mode);
2824 Py_END_ALLOW_THREADS
2825 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2826 if (res != 0)
2827 return (!async_err) ? posix_error() : NULL;
2828
Victor Stinner8c62be82010-05-06 00:08:46 +00002829 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002830}
2831#endif /* HAVE_FCHMOD */
2832
Larry Hastings2f936352014-08-05 14:04:04 +10002833
Christian Heimes4e30a842007-11-30 22:12:06 +00002834#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002835/*[clinic input]
2836os.lchmod
2837
2838 path: path_t
2839 mode: int
2840
2841Change the access permissions of a file, without following symbolic links.
2842
2843If path is a symlink, this affects the link itself rather than the target.
2844Equivalent to chmod(path, mode, follow_symlinks=False)."
2845[clinic start generated code]*/
2846
Larry Hastings2f936352014-08-05 14:04:04 +10002847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002848os_lchmod_impl(PyObject *module, path_t *path, int mode)
2849/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002850{
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002852 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002853 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002854 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002855 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002856 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002857 return NULL;
2858 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002860}
2861#endif /* HAVE_LCHMOD */
2862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002863
Thomas Wouterscf297e42007-02-23 15:07:44 +00002864#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002865/*[clinic input]
2866os.chflags
2867
2868 path: path_t
2869 flags: unsigned_long(bitwise=True)
2870 follow_symlinks: bool=True
2871
2872Set file flags.
2873
2874If follow_symlinks is False, and the last element of the path is a symbolic
2875 link, chflags will change flags on the symbolic link itself instead of the
2876 file the link points to.
2877follow_symlinks may not be implemented on your platform. If it is
2878unavailable, using it will raise a NotImplementedError.
2879
2880[clinic start generated code]*/
2881
Larry Hastings2f936352014-08-05 14:04:04 +10002882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002883os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002884 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002885/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002886{
2887 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002888
2889#ifndef HAVE_LCHFLAGS
2890 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002891 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892#endif
2893
Victor Stinner8c62be82010-05-06 00:08:46 +00002894 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895#ifdef HAVE_LCHFLAGS
2896 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002897 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002898 else
2899#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002900 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002901 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002902
Larry Hastings2f936352014-08-05 14:04:04 +10002903 if (result)
2904 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002905
Larry Hastings2f936352014-08-05 14:04:04 +10002906 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002907}
2908#endif /* HAVE_CHFLAGS */
2909
Larry Hastings2f936352014-08-05 14:04:04 +10002910
Thomas Wouterscf297e42007-02-23 15:07:44 +00002911#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002912/*[clinic input]
2913os.lchflags
2914
2915 path: path_t
2916 flags: unsigned_long(bitwise=True)
2917
2918Set file flags.
2919
2920This function will not follow symbolic links.
2921Equivalent to chflags(path, flags, follow_symlinks=False).
2922[clinic start generated code]*/
2923
Larry Hastings2f936352014-08-05 14:04:04 +10002924static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002925os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2926/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002927{
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002929 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002930 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002931 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002932 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002933 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002934 }
Victor Stinner292c8352012-10-30 02:17:38 +01002935 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002936}
2937#endif /* HAVE_LCHFLAGS */
2938
Larry Hastings2f936352014-08-05 14:04:04 +10002939
Martin v. Löwis244edc82001-10-04 22:44:26 +00002940#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002941/*[clinic input]
2942os.chroot
2943 path: path_t
2944
2945Change root directory to path.
2946
2947[clinic start generated code]*/
2948
Larry Hastings2f936352014-08-05 14:04:04 +10002949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002950os_chroot_impl(PyObject *module, path_t *path)
2951/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002952{
2953 int res;
2954 Py_BEGIN_ALLOW_THREADS
2955 res = chroot(path->narrow);
2956 Py_END_ALLOW_THREADS
2957 if (res < 0)
2958 return path_error(path);
2959 Py_RETURN_NONE;
2960}
2961#endif /* HAVE_CHROOT */
2962
Martin v. Löwis244edc82001-10-04 22:44:26 +00002963
Guido van Rossum21142a01999-01-08 21:05:37 +00002964#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002965/*[clinic input]
2966os.fsync
2967
2968 fd: fildes
2969
2970Force write of fd to disk.
2971[clinic start generated code]*/
2972
Larry Hastings2f936352014-08-05 14:04:04 +10002973static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002974os_fsync_impl(PyObject *module, int fd)
2975/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002976{
2977 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002978}
2979#endif /* HAVE_FSYNC */
2980
Larry Hastings2f936352014-08-05 14:04:04 +10002981
Ross Lagerwall7807c352011-03-17 20:20:30 +02002982#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002983/*[clinic input]
2984os.sync
2985
2986Force write of everything to disk.
2987[clinic start generated code]*/
2988
Larry Hastings2f936352014-08-05 14:04:04 +10002989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002990os_sync_impl(PyObject *module)
2991/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002992{
2993 Py_BEGIN_ALLOW_THREADS
2994 sync();
2995 Py_END_ALLOW_THREADS
2996 Py_RETURN_NONE;
2997}
Larry Hastings2f936352014-08-05 14:04:04 +10002998#endif /* HAVE_SYNC */
2999
Ross Lagerwall7807c352011-03-17 20:20:30 +02003000
Guido van Rossum21142a01999-01-08 21:05:37 +00003001#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003002#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003003extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3004#endif
3005
Larry Hastings2f936352014-08-05 14:04:04 +10003006/*[clinic input]
3007os.fdatasync
3008
3009 fd: fildes
3010
3011Force write of fd to disk without forcing update of metadata.
3012[clinic start generated code]*/
3013
Larry Hastings2f936352014-08-05 14:04:04 +10003014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003015os_fdatasync_impl(PyObject *module, int fd)
3016/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003017{
3018 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003019}
3020#endif /* HAVE_FDATASYNC */
3021
3022
Fredrik Lundh10723342000-07-10 16:38:09 +00003023#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003024/*[clinic input]
3025os.chown
3026
3027 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3028 Path to be examined; can be string, bytes, or open-file-descriptor int.
3029
3030 uid: uid_t
3031
3032 gid: gid_t
3033
3034 *
3035
3036 dir_fd : dir_fd(requires='fchownat') = None
3037 If not None, it should be a file descriptor open to a directory,
3038 and path should be relative; path will then be relative to that
3039 directory.
3040
3041 follow_symlinks: bool = True
3042 If False, and the last element of the path is a symbolic link,
3043 stat will examine the symbolic link itself instead of the file
3044 the link points to.
3045
3046Change the owner and group id of path to the numeric uid and gid.\
3047
3048path may always be specified as a string.
3049On some platforms, path may also be specified as an open file descriptor.
3050 If this functionality is unavailable, using it raises an exception.
3051If dir_fd is not None, it should be a file descriptor open to a directory,
3052 and path should be relative; path will then be relative to that directory.
3053If follow_symlinks is False, and the last element of the path is a symbolic
3054 link, chown will modify the symbolic link itself instead of the file the
3055 link points to.
3056It is an error to use dir_fd or follow_symlinks when specifying path as
3057 an open file descriptor.
3058dir_fd and follow_symlinks may not be implemented on your platform.
3059 If they are unavailable, using them will raise a NotImplementedError.
3060
3061[clinic start generated code]*/
3062
Larry Hastings2f936352014-08-05 14:04:04 +10003063static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003064os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003065 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003066/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003067{
3068 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069
3070#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3071 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003072 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003073#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003074 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3075 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3076 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003077
3078#ifdef __APPLE__
3079 /*
3080 * This is for Mac OS X 10.3, which doesn't have lchown.
3081 * (But we still have an lchown symbol because of weak-linking.)
3082 * It doesn't have fchownat either. So there's no possibility
3083 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003084 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003085 if ((!follow_symlinks) && (lchown == NULL)) {
3086 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003087 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088 }
3089#endif
3090
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003093 if (path->fd != -1)
3094 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095 else
3096#endif
3097#ifdef HAVE_LCHOWN
3098 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003099 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003100 else
3101#endif
3102#ifdef HAVE_FCHOWNAT
3103 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003104 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3106 else
3107#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003108 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110
Larry Hastings2f936352014-08-05 14:04:04 +10003111 if (result)
3112 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003113
Larry Hastings2f936352014-08-05 14:04:04 +10003114 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003115}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003116#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003117
Larry Hastings2f936352014-08-05 14:04:04 +10003118
Christian Heimes4e30a842007-11-30 22:12:06 +00003119#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003120/*[clinic input]
3121os.fchown
3122
3123 fd: int
3124 uid: uid_t
3125 gid: gid_t
3126
3127Change the owner and group id of the file specified by file descriptor.
3128
3129Equivalent to os.chown(fd, uid, gid).
3130
3131[clinic start generated code]*/
3132
Larry Hastings2f936352014-08-05 14:04:04 +10003133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003134os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3135/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003136{
Victor Stinner8c62be82010-05-06 00:08:46 +00003137 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003138 int async_err = 0;
3139
3140 do {
3141 Py_BEGIN_ALLOW_THREADS
3142 res = fchown(fd, uid, gid);
3143 Py_END_ALLOW_THREADS
3144 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3145 if (res != 0)
3146 return (!async_err) ? posix_error() : NULL;
3147
Victor Stinner8c62be82010-05-06 00:08:46 +00003148 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003149}
3150#endif /* HAVE_FCHOWN */
3151
Larry Hastings2f936352014-08-05 14:04:04 +10003152
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003153#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003154/*[clinic input]
3155os.lchown
3156
3157 path : path_t
3158 uid: uid_t
3159 gid: gid_t
3160
3161Change the owner and group id of path to the numeric uid and gid.
3162
3163This function will not follow symbolic links.
3164Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3165[clinic start generated code]*/
3166
Larry Hastings2f936352014-08-05 14:04:04 +10003167static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003168os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3169/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003170{
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003172 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003173 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003175 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003176 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003177 }
Larry Hastings2f936352014-08-05 14:04:04 +10003178 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003179}
3180#endif /* HAVE_LCHOWN */
3181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003182
Barry Warsaw53699e91996-12-10 23:23:01 +00003183static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003184posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003185{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003186 char *buf, *tmpbuf;
3187 char *cwd;
3188 const size_t chunk = 1024;
3189 size_t buflen = 0;
3190 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003191
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003192#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003194 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 wchar_t *wbuf2 = wbuf;
3196 PyObject *resobj;
3197 DWORD len;
3198 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003199 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003200 /* If the buffer is large enough, len does not include the
3201 terminating \0. If the buffer is too small, len includes
3202 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003203 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003204 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 if (wbuf2)
3206 len = GetCurrentDirectoryW(len, wbuf2);
3207 }
3208 Py_END_ALLOW_THREADS
3209 if (!wbuf2) {
3210 PyErr_NoMemory();
3211 return NULL;
3212 }
3213 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003214 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003215 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003216 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003217 }
3218 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003219 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003220 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 return resobj;
3222 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003223
3224 if (win32_warn_bytes_api())
3225 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003226#endif
3227
Victor Stinner4403d7d2015-04-25 00:16:10 +02003228 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003229 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003230 do {
3231 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003232#ifdef MS_WINDOWS
3233 if (buflen > INT_MAX) {
3234 PyErr_NoMemory();
3235 break;
3236 }
3237#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003238 tmpbuf = PyMem_RawRealloc(buf, buflen);
3239 if (tmpbuf == NULL)
3240 break;
3241
3242 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003243#ifdef MS_WINDOWS
3244 cwd = getcwd(buf, (int)buflen);
3245#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003246 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003247#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003248 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003249 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003250
3251 if (cwd == NULL) {
3252 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003254 }
3255
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003257 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3258 else
3259 obj = PyUnicode_DecodeFSDefault(buf);
3260 PyMem_RawFree(buf);
3261
3262 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003263}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003264
Larry Hastings2f936352014-08-05 14:04:04 +10003265
3266/*[clinic input]
3267os.getcwd
3268
3269Return a unicode string representing the current working directory.
3270[clinic start generated code]*/
3271
Larry Hastings2f936352014-08-05 14:04:04 +10003272static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003273os_getcwd_impl(PyObject *module)
3274/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003275{
3276 return posix_getcwd(0);
3277}
3278
Larry Hastings2f936352014-08-05 14:04:04 +10003279
3280/*[clinic input]
3281os.getcwdb
3282
3283Return a bytes string representing the current working directory.
3284[clinic start generated code]*/
3285
Larry Hastings2f936352014-08-05 14:04:04 +10003286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003287os_getcwdb_impl(PyObject *module)
3288/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003289{
3290 return posix_getcwd(1);
3291}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003292
Larry Hastings2f936352014-08-05 14:04:04 +10003293
Larry Hastings9cf065c2012-06-22 16:30:09 -07003294#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3295#define HAVE_LINK 1
3296#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003297
Guido van Rossumb6775db1994-08-01 11:34:53 +00003298#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003299/*[clinic input]
3300
3301os.link
3302
3303 src : path_t
3304 dst : path_t
3305 *
3306 src_dir_fd : dir_fd = None
3307 dst_dir_fd : dir_fd = None
3308 follow_symlinks: bool = True
3309
3310Create a hard link to a file.
3311
3312If either src_dir_fd or dst_dir_fd is not None, it should be a file
3313 descriptor open to a directory, and the respective path string (src or dst)
3314 should be relative; the path will then be relative to that directory.
3315If follow_symlinks is False, and the last element of src is a symbolic
3316 link, link will create a link to the symbolic link itself instead of the
3317 file the link points to.
3318src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3319 platform. If they are unavailable, using them will raise a
3320 NotImplementedError.
3321[clinic start generated code]*/
3322
Larry Hastings2f936352014-08-05 14:04:04 +10003323static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003324os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003325 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003326/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003327{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003328#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003329 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330#else
3331 int result;
3332#endif
3333
Larry Hastings9cf065c2012-06-22 16:30:09 -07003334#ifndef HAVE_LINKAT
3335 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3336 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003337 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338 }
3339#endif
3340
Steve Dowercc16be82016-09-08 10:35:16 -07003341#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003342 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003343 PyErr_SetString(PyExc_NotImplementedError,
3344 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003345 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003346 }
Steve Dowercc16be82016-09-08 10:35:16 -07003347#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003348
Brian Curtin1b9df392010-11-24 20:24:31 +00003349#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003350 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003351 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003353
Larry Hastings2f936352014-08-05 14:04:04 +10003354 if (!result)
3355 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356#else
3357 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003358#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003359 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3360 (dst_dir_fd != DEFAULT_DIR_FD) ||
3361 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003362 result = linkat(src_dir_fd, src->narrow,
3363 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3365 else
Steve Dowercc16be82016-09-08 10:35:16 -07003366#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003367 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003369
Larry Hastings2f936352014-08-05 14:04:04 +10003370 if (result)
3371 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003372#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373
Larry Hastings2f936352014-08-05 14:04:04 +10003374 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003375}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003376#endif
3377
Brian Curtin1b9df392010-11-24 20:24:31 +00003378
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003379#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003380static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003381_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003382{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383 PyObject *v;
3384 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3385 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003386 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003387 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003388 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003389 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003390
Steve Dowercc16be82016-09-08 10:35:16 -07003391 WIN32_FIND_DATAW wFileData;
3392 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003393
Steve Dowercc16be82016-09-08 10:35:16 -07003394 if (!path->wide) { /* Default arg: "." */
3395 po_wchars = L".";
3396 len = 1;
3397 } else {
3398 po_wchars = path->wide;
3399 len = wcslen(path->wide);
3400 }
3401 /* The +5 is so we can append "\\*.*\0" */
3402 wnamebuf = PyMem_New(wchar_t, len + 5);
3403 if (!wnamebuf) {
3404 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003405 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 }
Steve Dowercc16be82016-09-08 10:35:16 -07003407 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003409 wchar_t wch = wnamebuf[len-1];
3410 if (wch != SEP && wch != ALTSEP && wch != L':')
3411 wnamebuf[len++] = SEP;
3412 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003413 }
Steve Dowercc16be82016-09-08 10:35:16 -07003414 if ((list = PyList_New(0)) == NULL) {
3415 goto exit;
3416 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003417 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003418 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003419 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 if (hFindFile == INVALID_HANDLE_VALUE) {
3421 int error = GetLastError();
3422 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 goto exit;
3424 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003425 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 }
3428 do {
3429 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003430 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3431 wcscmp(wFileData.cFileName, L"..") != 0) {
3432 v = PyUnicode_FromWideChar(wFileData.cFileName,
3433 wcslen(wFileData.cFileName));
3434 if (path->narrow && v) {
3435 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3436 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003437 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 Py_DECREF(list);
3439 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 break;
3441 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003443 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 Py_DECREF(list);
3445 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 break;
3447 }
3448 Py_DECREF(v);
3449 }
3450 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003451 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 Py_END_ALLOW_THREADS
3453 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3454 it got to the end of the directory. */
3455 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003457 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 }
3460 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003461
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462exit:
3463 if (hFindFile != INVALID_HANDLE_VALUE) {
3464 if (FindClose(hFindFile) == FALSE) {
3465 if (list != NULL) {
3466 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003467 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003468 }
3469 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003471 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003472
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003474} /* end of _listdir_windows_no_opendir */
3475
3476#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3477
3478static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003479_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003480{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003481 PyObject *v;
3482 DIR *dirp = NULL;
3483 struct dirent *ep;
3484 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003485#ifdef HAVE_FDOPENDIR
3486 int fd = -1;
3487#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003488
Victor Stinner8c62be82010-05-06 00:08:46 +00003489 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003491 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003493 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003494 if (fd == -1)
3495 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496
Larry Hastingsfdaea062012-06-25 04:42:23 -07003497 return_str = 1;
3498
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 Py_BEGIN_ALLOW_THREADS
3500 dirp = fdopendir(fd);
3501 Py_END_ALLOW_THREADS
3502 }
3503 else
3504#endif
3505 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003506 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003507 if (path->narrow) {
3508 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003509 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003510 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003511 }
3512 else {
3513 name = ".";
3514 return_str = 1;
3515 }
3516
Larry Hastings9cf065c2012-06-22 16:30:09 -07003517 Py_BEGIN_ALLOW_THREADS
3518 dirp = opendir(name);
3519 Py_END_ALLOW_THREADS
3520 }
3521
3522 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003523 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003524#ifdef HAVE_FDOPENDIR
3525 if (fd != -1) {
3526 Py_BEGIN_ALLOW_THREADS
3527 close(fd);
3528 Py_END_ALLOW_THREADS
3529 }
3530#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 goto exit;
3532 }
3533 if ((list = PyList_New(0)) == NULL) {
3534 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 }
3536 for (;;) {
3537 errno = 0;
3538 Py_BEGIN_ALLOW_THREADS
3539 ep = readdir(dirp);
3540 Py_END_ALLOW_THREADS
3541 if (ep == NULL) {
3542 if (errno == 0) {
3543 break;
3544 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003546 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 }
3549 }
3550 if (ep->d_name[0] == '.' &&
3551 (NAMLEN(ep) == 1 ||
3552 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3553 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003554 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003555 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3556 else
3557 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003559 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 break;
3561 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 break;
3566 }
3567 Py_DECREF(v);
3568 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003569
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570exit:
3571 if (dirp != NULL) {
3572 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003573#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 if (fd > -1)
3575 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003576#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 closedir(dirp);
3578 Py_END_ALLOW_THREADS
3579 }
3580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003582} /* end of _posix_listdir */
3583#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003584
Larry Hastings2f936352014-08-05 14:04:04 +10003585
3586/*[clinic input]
3587os.listdir
3588
3589 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3590
3591Return a list containing the names of the files in the directory.
3592
3593path can be specified as either str or bytes. If path is bytes,
3594 the filenames returned will also be bytes; in all other circumstances
3595 the filenames returned will be str.
3596If path is None, uses the path='.'.
3597On some platforms, path may also be specified as an open file descriptor;\
3598 the file descriptor must refer to a directory.
3599 If this functionality is unavailable, using it raises NotImplementedError.
3600
3601The list is in arbitrary order. It does not include the special
3602entries '.' and '..' even if they are present in the directory.
3603
3604
3605[clinic start generated code]*/
3606
Larry Hastings2f936352014-08-05 14:04:04 +10003607static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003608os_listdir_impl(PyObject *module, path_t *path)
3609/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003610{
3611#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3612 return _listdir_windows_no_opendir(path, NULL);
3613#else
3614 return _posix_listdir(path, NULL);
3615#endif
3616}
3617
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003618#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003619/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003620/*[clinic input]
3621os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003622
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003623 path: path_t
3624 /
3625
3626[clinic start generated code]*/
3627
3628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003629os__getfullpathname_impl(PyObject *module, path_t *path)
3630/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003631{
Steve Dowercc16be82016-09-08 10:35:16 -07003632 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3633 wchar_t *wtemp;
3634 DWORD result;
3635 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003636
Steve Dowercc16be82016-09-08 10:35:16 -07003637 result = GetFullPathNameW(path->wide,
3638 Py_ARRAY_LENGTH(woutbuf),
3639 woutbuf, &wtemp);
3640 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3641 woutbufp = PyMem_New(wchar_t, result);
3642 if (!woutbufp)
3643 return PyErr_NoMemory();
3644 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 }
Steve Dowercc16be82016-09-08 10:35:16 -07003646 if (result) {
3647 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3648 if (path->narrow)
3649 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3650 } else
3651 v = win32_error_object("GetFullPathNameW", path->object);
3652 if (woutbufp != woutbuf)
3653 PyMem_Free(woutbufp);
3654 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003655}
Brian Curtind40e6f72010-07-08 21:39:08 +00003656
Brian Curtind25aef52011-06-13 15:16:04 -05003657
Larry Hastings2f936352014-08-05 14:04:04 +10003658/*[clinic input]
3659os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003660
Larry Hastings2f936352014-08-05 14:04:04 +10003661 path: unicode
3662 /
3663
3664A helper function for samepath on windows.
3665[clinic start generated code]*/
3666
Larry Hastings2f936352014-08-05 14:04:04 +10003667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003668os__getfinalpathname_impl(PyObject *module, PyObject *path)
3669/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003670{
3671 HANDLE hFile;
3672 int buf_size;
3673 wchar_t *target_path;
3674 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003675 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003676 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003677
Larry Hastings2f936352014-08-05 14:04:04 +10003678 path_wchar = PyUnicode_AsUnicode(path);
3679 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003680 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003681
Brian Curtind40e6f72010-07-08 21:39:08 +00003682 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003683 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003684 0, /* desired access */
3685 0, /* share mode */
3686 NULL, /* security attributes */
3687 OPEN_EXISTING,
3688 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3689 FILE_FLAG_BACKUP_SEMANTICS,
3690 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003691
Victor Stinnereb5657a2011-09-30 01:44:27 +02003692 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003693 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003694
3695 /* We have a good handle to the target, use it to determine the
3696 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003697 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003698
3699 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003700 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003701
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003702 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003703 if(!target_path)
3704 return PyErr_NoMemory();
3705
Steve Dower2ea51c92015-03-20 21:49:12 -07003706 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3707 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003708 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003709 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003710
3711 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003712 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003713
3714 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003715 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003716 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003717 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003718}
Brian Curtin62857742010-09-06 17:07:27 +00003719
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003720/*[clinic input]
3721os._isdir
3722
3723 path: path_t
3724 /
3725
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003726Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003727[clinic start generated code]*/
3728
Brian Curtin9c669cc2011-06-08 18:17:18 -05003729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003730os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003731/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003732{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003733 DWORD attributes;
3734
Steve Dowerb22a6772016-07-17 20:49:38 -07003735 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003736 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003737 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003738
Brian Curtin9c669cc2011-06-08 18:17:18 -05003739 if (attributes == INVALID_FILE_ATTRIBUTES)
3740 Py_RETURN_FALSE;
3741
Brian Curtin9c669cc2011-06-08 18:17:18 -05003742 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3743 Py_RETURN_TRUE;
3744 else
3745 Py_RETURN_FALSE;
3746}
Tim Golden6b528062013-08-01 12:44:00 +01003747
Tim Golden6b528062013-08-01 12:44:00 +01003748
Larry Hastings2f936352014-08-05 14:04:04 +10003749/*[clinic input]
3750os._getvolumepathname
3751
3752 path: unicode
3753
3754A helper function for ismount on Win32.
3755[clinic start generated code]*/
3756
Larry Hastings2f936352014-08-05 14:04:04 +10003757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003758os__getvolumepathname_impl(PyObject *module, PyObject *path)
3759/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003760{
3761 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003762 const wchar_t *path_wchar;
3763 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003764 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003765 BOOL ret;
3766
Larry Hastings2f936352014-08-05 14:04:04 +10003767 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3768 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003769 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003770 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003771
3772 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003773 buflen = Py_MAX(buflen, MAX_PATH);
3774
3775 if (buflen > DWORD_MAX) {
3776 PyErr_SetString(PyExc_OverflowError, "path too long");
3777 return NULL;
3778 }
3779
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003780 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003781 if (mountpath == NULL)
3782 return PyErr_NoMemory();
3783
3784 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003785 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003786 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003787 Py_END_ALLOW_THREADS
3788
3789 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003790 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003791 goto exit;
3792 }
3793 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3794
3795exit:
3796 PyMem_Free(mountpath);
3797 return result;
3798}
Tim Golden6b528062013-08-01 12:44:00 +01003799
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003800#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003801
Larry Hastings2f936352014-08-05 14:04:04 +10003802
3803/*[clinic input]
3804os.mkdir
3805
3806 path : path_t
3807
3808 mode: int = 0o777
3809
3810 *
3811
3812 dir_fd : dir_fd(requires='mkdirat') = None
3813
3814# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3815
3816Create a directory.
3817
3818If dir_fd is not None, it should be a file descriptor open to a directory,
3819 and path should be relative; path will then be relative to that directory.
3820dir_fd may not be implemented on your platform.
3821 If it is unavailable, using it will raise a NotImplementedError.
3822
3823The mode argument is ignored on Windows.
3824[clinic start generated code]*/
3825
Larry Hastings2f936352014-08-05 14:04:04 +10003826static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003827os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3828/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003829{
3830 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003831
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003832#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003833 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003834 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003835 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003836
Larry Hastings2f936352014-08-05 14:04:04 +10003837 if (!result)
3838 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003839#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003841#if HAVE_MKDIRAT
3842 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003843 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003844 else
3845#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003846#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003847 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003848#else
Larry Hastings2f936352014-08-05 14:04:04 +10003849 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003850#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003851 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003852 if (result < 0)
3853 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003854#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003855 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003856}
3857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003858
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003859/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3860#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003861#include <sys/resource.h>
3862#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003863
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003864
3865#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003866/*[clinic input]
3867os.nice
3868
3869 increment: int
3870 /
3871
3872Add increment to the priority of process and return the new priority.
3873[clinic start generated code]*/
3874
Larry Hastings2f936352014-08-05 14:04:04 +10003875static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003876os_nice_impl(PyObject *module, int increment)
3877/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003878{
3879 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003880
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 /* There are two flavours of 'nice': one that returns the new
3882 priority (as required by almost all standards out there) and the
3883 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3884 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003885
Victor Stinner8c62be82010-05-06 00:08:46 +00003886 If we are of the nice family that returns the new priority, we
3887 need to clear errno before the call, and check if errno is filled
3888 before calling posix_error() on a returnvalue of -1, because the
3889 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003890
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 errno = 0;
3892 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003893#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003894 if (value == 0)
3895 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003896#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 if (value == -1 && errno != 0)
3898 /* either nice() or getpriority() returned an error */
3899 return posix_error();
3900 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003901}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003902#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003903
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003904
3905#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003906/*[clinic input]
3907os.getpriority
3908
3909 which: int
3910 who: int
3911
3912Return program scheduling priority.
3913[clinic start generated code]*/
3914
Larry Hastings2f936352014-08-05 14:04:04 +10003915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003916os_getpriority_impl(PyObject *module, int which, int who)
3917/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003918{
3919 int retval;
3920
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003921 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003922 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003923 if (errno != 0)
3924 return posix_error();
3925 return PyLong_FromLong((long)retval);
3926}
3927#endif /* HAVE_GETPRIORITY */
3928
3929
3930#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003931/*[clinic input]
3932os.setpriority
3933
3934 which: int
3935 who: int
3936 priority: int
3937
3938Set program scheduling priority.
3939[clinic start generated code]*/
3940
Larry Hastings2f936352014-08-05 14:04:04 +10003941static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003942os_setpriority_impl(PyObject *module, int which, int who, int priority)
3943/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003944{
3945 int retval;
3946
3947 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003948 if (retval == -1)
3949 return posix_error();
3950 Py_RETURN_NONE;
3951}
3952#endif /* HAVE_SETPRIORITY */
3953
3954
Barry Warsaw53699e91996-12-10 23:23:01 +00003955static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003956internal_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 +00003957{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003958 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003959 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003960
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003962 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003963 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003964#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003965 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003966#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967
Larry Hastings9cf065c2012-06-22 16:30:09 -07003968 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3969 (dst_dir_fd != DEFAULT_DIR_FD);
3970#ifndef HAVE_RENAMEAT
3971 if (dir_fd_specified) {
3972 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003973 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 }
3975#endif
3976
Larry Hastings9cf065c2012-06-22 16:30:09 -07003977#ifdef MS_WINDOWS
3978 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003979 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003980 Py_END_ALLOW_THREADS
3981
Larry Hastings2f936352014-08-05 14:04:04 +10003982 if (!result)
3983 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003984
3985#else
Steve Dowercc16be82016-09-08 10:35:16 -07003986 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3987 PyErr_Format(PyExc_ValueError,
3988 "%s: src and dst must be the same type", function_name);
3989 return NULL;
3990 }
3991
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992 Py_BEGIN_ALLOW_THREADS
3993#ifdef HAVE_RENAMEAT
3994 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10003995 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996 else
3997#endif
Steve Dowercc16be82016-09-08 10:35:16 -07003998 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999 Py_END_ALLOW_THREADS
4000
Larry Hastings2f936352014-08-05 14:04:04 +10004001 if (result)
4002 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004003#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004004 Py_RETURN_NONE;
4005}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006
Larry Hastings2f936352014-08-05 14:04:04 +10004007
4008/*[clinic input]
4009os.rename
4010
4011 src : path_t
4012 dst : path_t
4013 *
4014 src_dir_fd : dir_fd = None
4015 dst_dir_fd : dir_fd = None
4016
4017Rename a file or directory.
4018
4019If either src_dir_fd or dst_dir_fd is not None, it should be a file
4020 descriptor open to a directory, and the respective path string (src or dst)
4021 should be relative; the path will then be relative to that directory.
4022src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4023 If they are unavailable, using them will raise a NotImplementedError.
4024[clinic start generated code]*/
4025
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004026static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004027os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004028 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004029/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004030{
Larry Hastings2f936352014-08-05 14:04:04 +10004031 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004032}
4033
Larry Hastings2f936352014-08-05 14:04:04 +10004034
4035/*[clinic input]
4036os.replace = os.rename
4037
4038Rename a file or directory, overwriting the destination.
4039
4040If either src_dir_fd or dst_dir_fd is not None, it should be a file
4041 descriptor open to a directory, and the respective path string (src or dst)
4042 should be relative; the path will then be relative to that directory.
4043src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4044 If they are unavailable, using them will raise a NotImplementedError."
4045[clinic start generated code]*/
4046
Larry Hastings2f936352014-08-05 14:04:04 +10004047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004048os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4049 int dst_dir_fd)
4050/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004051{
4052 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4053}
4054
4055
4056/*[clinic input]
4057os.rmdir
4058
4059 path: path_t
4060 *
4061 dir_fd: dir_fd(requires='unlinkat') = None
4062
4063Remove a directory.
4064
4065If dir_fd is not None, it should be a file descriptor open to a directory,
4066 and path should be relative; path will then be relative to that directory.
4067dir_fd may not be implemented on your platform.
4068 If it is unavailable, using it will raise a NotImplementedError.
4069[clinic start generated code]*/
4070
Larry Hastings2f936352014-08-05 14:04:04 +10004071static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004072os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4073/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004074{
4075 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004076
4077 Py_BEGIN_ALLOW_THREADS
4078#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004079 /* Windows, success=1, UNIX, success=0 */
4080 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004081#else
4082#ifdef HAVE_UNLINKAT
4083 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004084 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004085 else
4086#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004087 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004088#endif
4089 Py_END_ALLOW_THREADS
4090
Larry Hastings2f936352014-08-05 14:04:04 +10004091 if (result)
4092 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004093
Larry Hastings2f936352014-08-05 14:04:04 +10004094 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004095}
4096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004098#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004099#ifdef MS_WINDOWS
4100/*[clinic input]
4101os.system -> long
4102
4103 command: Py_UNICODE
4104
4105Execute the command in a subshell.
4106[clinic start generated code]*/
4107
Larry Hastings2f936352014-08-05 14:04:04 +10004108static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004109os_system_impl(PyObject *module, Py_UNICODE *command)
4110/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004111{
4112 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004113 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004114 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004115 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004116 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004117 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004118 return result;
4119}
4120#else /* MS_WINDOWS */
4121/*[clinic input]
4122os.system -> long
4123
4124 command: FSConverter
4125
4126Execute the command in a subshell.
4127[clinic start generated code]*/
4128
Larry Hastings2f936352014-08-05 14:04:04 +10004129static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004130os_system_impl(PyObject *module, PyObject *command)
4131/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004132{
4133 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004134 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004135 Py_BEGIN_ALLOW_THREADS
4136 result = system(bytes);
4137 Py_END_ALLOW_THREADS
4138 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004139}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004140#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004141#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004142
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004143
Larry Hastings2f936352014-08-05 14:04:04 +10004144/*[clinic input]
4145os.umask
4146
4147 mask: int
4148 /
4149
4150Set the current numeric umask and return the previous umask.
4151[clinic start generated code]*/
4152
Larry Hastings2f936352014-08-05 14:04:04 +10004153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004154os_umask_impl(PyObject *module, int mask)
4155/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004156{
4157 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004158 if (i < 0)
4159 return posix_error();
4160 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004161}
4162
Brian Curtind40e6f72010-07-08 21:39:08 +00004163#ifdef MS_WINDOWS
4164
4165/* override the default DeleteFileW behavior so that directory
4166symlinks can be removed with this function, the same as with
4167Unix symlinks */
4168BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4169{
4170 WIN32_FILE_ATTRIBUTE_DATA info;
4171 WIN32_FIND_DATAW find_data;
4172 HANDLE find_data_handle;
4173 int is_directory = 0;
4174 int is_link = 0;
4175
4176 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4177 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004178
Brian Curtind40e6f72010-07-08 21:39:08 +00004179 /* Get WIN32_FIND_DATA structure for the path to determine if
4180 it is a symlink */
4181 if(is_directory &&
4182 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4183 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4184
4185 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004186 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4187 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4188 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4189 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004190 FindClose(find_data_handle);
4191 }
4192 }
4193 }
4194
4195 if (is_directory && is_link)
4196 return RemoveDirectoryW(lpFileName);
4197
4198 return DeleteFileW(lpFileName);
4199}
4200#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004202
Larry Hastings2f936352014-08-05 14:04:04 +10004203/*[clinic input]
4204os.unlink
4205
4206 path: path_t
4207 *
4208 dir_fd: dir_fd(requires='unlinkat')=None
4209
4210Remove a file (same as remove()).
4211
4212If dir_fd is not None, it should be a file descriptor open to a directory,
4213 and path should be relative; path will then be relative to that directory.
4214dir_fd may not be implemented on your platform.
4215 If it is unavailable, using it will raise a NotImplementedError.
4216
4217[clinic start generated code]*/
4218
Larry Hastings2f936352014-08-05 14:04:04 +10004219static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004220os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4221/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004222{
4223 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004224
4225 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004226 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004227#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004228 /* Windows, success=1, UNIX, success=0 */
4229 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004230#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004231#ifdef HAVE_UNLINKAT
4232 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004233 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004234 else
4235#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004236 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004237#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004238 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004239 Py_END_ALLOW_THREADS
4240
Larry Hastings2f936352014-08-05 14:04:04 +10004241 if (result)
4242 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004243
Larry Hastings2f936352014-08-05 14:04:04 +10004244 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004245}
4246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004247
Larry Hastings2f936352014-08-05 14:04:04 +10004248/*[clinic input]
4249os.remove = os.unlink
4250
4251Remove a file (same as unlink()).
4252
4253If dir_fd is not None, it should be a file descriptor open to a directory,
4254 and path should be relative; path will then be relative to that directory.
4255dir_fd may not be implemented on your platform.
4256 If it is unavailable, using it will raise a NotImplementedError.
4257[clinic start generated code]*/
4258
Larry Hastings2f936352014-08-05 14:04:04 +10004259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004260os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4261/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004262{
4263 return os_unlink_impl(module, path, dir_fd);
4264}
4265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004266
Larry Hastings605a62d2012-06-24 04:33:36 -07004267static PyStructSequence_Field uname_result_fields[] = {
4268 {"sysname", "operating system name"},
4269 {"nodename", "name of machine on network (implementation-defined)"},
4270 {"release", "operating system release"},
4271 {"version", "operating system version"},
4272 {"machine", "hardware identifier"},
4273 {NULL}
4274};
4275
4276PyDoc_STRVAR(uname_result__doc__,
4277"uname_result: Result from os.uname().\n\n\
4278This object may be accessed either as a tuple of\n\
4279 (sysname, nodename, release, version, machine),\n\
4280or via the attributes sysname, nodename, release, version, and machine.\n\
4281\n\
4282See os.uname for more information.");
4283
4284static PyStructSequence_Desc uname_result_desc = {
4285 "uname_result", /* name */
4286 uname_result__doc__, /* doc */
4287 uname_result_fields,
4288 5
4289};
4290
4291static PyTypeObject UnameResultType;
4292
4293
4294#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004295/*[clinic input]
4296os.uname
4297
4298Return an object identifying the current operating system.
4299
4300The object behaves like a named tuple with the following fields:
4301 (sysname, nodename, release, version, machine)
4302
4303[clinic start generated code]*/
4304
Larry Hastings2f936352014-08-05 14:04:04 +10004305static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004306os_uname_impl(PyObject *module)
4307/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004308{
Victor Stinner8c62be82010-05-06 00:08:46 +00004309 struct utsname u;
4310 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004311 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004312
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 Py_BEGIN_ALLOW_THREADS
4314 res = uname(&u);
4315 Py_END_ALLOW_THREADS
4316 if (res < 0)
4317 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004318
4319 value = PyStructSequence_New(&UnameResultType);
4320 if (value == NULL)
4321 return NULL;
4322
4323#define SET(i, field) \
4324 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004325 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004326 if (!o) { \
4327 Py_DECREF(value); \
4328 return NULL; \
4329 } \
4330 PyStructSequence_SET_ITEM(value, i, o); \
4331 } \
4332
4333 SET(0, u.sysname);
4334 SET(1, u.nodename);
4335 SET(2, u.release);
4336 SET(3, u.version);
4337 SET(4, u.machine);
4338
4339#undef SET
4340
4341 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004342}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004343#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004344
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004345
Larry Hastings9cf065c2012-06-22 16:30:09 -07004346
4347typedef struct {
4348 int now;
4349 time_t atime_s;
4350 long atime_ns;
4351 time_t mtime_s;
4352 long mtime_ns;
4353} utime_t;
4354
4355/*
Victor Stinner484df002014-10-09 13:52:31 +02004356 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357 * they also intentionally leak the declaration of a pointer named "time"
4358 */
4359#define UTIME_TO_TIMESPEC \
4360 struct timespec ts[2]; \
4361 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004362 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004363 time = NULL; \
4364 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004365 ts[0].tv_sec = ut->atime_s; \
4366 ts[0].tv_nsec = ut->atime_ns; \
4367 ts[1].tv_sec = ut->mtime_s; \
4368 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004369 time = ts; \
4370 } \
4371
4372#define UTIME_TO_TIMEVAL \
4373 struct timeval tv[2]; \
4374 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004375 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376 time = NULL; \
4377 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004378 tv[0].tv_sec = ut->atime_s; \
4379 tv[0].tv_usec = ut->atime_ns / 1000; \
4380 tv[1].tv_sec = ut->mtime_s; \
4381 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 time = tv; \
4383 } \
4384
4385#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004386 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004387 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004388 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 time = NULL; \
4390 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004391 u.actime = ut->atime_s; \
4392 u.modtime = ut->mtime_s; \
4393 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394 }
4395
4396#define UTIME_TO_TIME_T \
4397 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004398 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004399 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004400 time = NULL; \
4401 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004402 timet[0] = ut->atime_s; \
4403 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004404 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004405 } \
4406
4407
Victor Stinner528a9ab2015-09-03 21:30:26 +02004408#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409
4410static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004411utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004412{
4413#ifdef HAVE_UTIMENSAT
4414 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4415 UTIME_TO_TIMESPEC;
4416 return utimensat(dir_fd, path, time, flags);
4417#elif defined(HAVE_FUTIMESAT)
4418 UTIME_TO_TIMEVAL;
4419 /*
4420 * follow_symlinks will never be false here;
4421 * we only allow !follow_symlinks and dir_fd together
4422 * if we have utimensat()
4423 */
4424 assert(follow_symlinks);
4425 return futimesat(dir_fd, path, time);
4426#endif
4427}
4428
Larry Hastings2f936352014-08-05 14:04:04 +10004429 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4430#else
4431 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432#endif
4433
Victor Stinner528a9ab2015-09-03 21:30:26 +02004434#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004435
4436static int
Victor Stinner484df002014-10-09 13:52:31 +02004437utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438{
4439#ifdef HAVE_FUTIMENS
4440 UTIME_TO_TIMESPEC;
4441 return futimens(fd, time);
4442#else
4443 UTIME_TO_TIMEVAL;
4444 return futimes(fd, time);
4445#endif
4446}
4447
Larry Hastings2f936352014-08-05 14:04:04 +10004448 #define PATH_UTIME_HAVE_FD 1
4449#else
4450 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451#endif
4452
Victor Stinner5ebae872015-09-22 01:29:33 +02004453#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4454# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4455#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456
Victor Stinner4552ced2015-09-21 22:37:15 +02004457#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004458
4459static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004460utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004461{
4462#ifdef HAVE_UTIMENSAT
4463 UTIME_TO_TIMESPEC;
4464 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4465#else
4466 UTIME_TO_TIMEVAL;
4467 return lutimes(path, time);
4468#endif
4469}
4470
4471#endif
4472
4473#ifndef MS_WINDOWS
4474
4475static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004476utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004477{
4478#ifdef HAVE_UTIMENSAT
4479 UTIME_TO_TIMESPEC;
4480 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4481#elif defined(HAVE_UTIMES)
4482 UTIME_TO_TIMEVAL;
4483 return utimes(path, time);
4484#elif defined(HAVE_UTIME_H)
4485 UTIME_TO_UTIMBUF;
4486 return utime(path, time);
4487#else
4488 UTIME_TO_TIME_T;
4489 return utime(path, time);
4490#endif
4491}
4492
4493#endif
4494
Larry Hastings76ad59b2012-05-03 00:30:07 -07004495static int
4496split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4497{
4498 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004499 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004500 divmod = PyNumber_Divmod(py_long, billion);
4501 if (!divmod)
4502 goto exit;
4503 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4504 if ((*s == -1) && PyErr_Occurred())
4505 goto exit;
4506 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004507 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004508 goto exit;
4509
4510 result = 1;
4511exit:
4512 Py_XDECREF(divmod);
4513 return result;
4514}
4515
Larry Hastings2f936352014-08-05 14:04:04 +10004516
4517/*[clinic input]
4518os.utime
4519
4520 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4521 times: object = NULL
4522 *
4523 ns: object = NULL
4524 dir_fd: dir_fd(requires='futimensat') = None
4525 follow_symlinks: bool=True
4526
Martin Panter0ff89092015-09-09 01:56:53 +00004527# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004528
4529Set the access and modified time of path.
4530
4531path may always be specified as a string.
4532On some platforms, path may also be specified as an open file descriptor.
4533 If this functionality is unavailable, using it raises an exception.
4534
4535If times is not None, it must be a tuple (atime, mtime);
4536 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004537If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004538 atime_ns and mtime_ns should be expressed as integer nanoseconds
4539 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004540If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004541Specifying tuples for both times and ns is an error.
4542
4543If dir_fd is not None, it should be a file descriptor open to a directory,
4544 and path should be relative; path will then be relative to that directory.
4545If follow_symlinks is False, and the last element of the path is a symbolic
4546 link, utime will modify the symbolic link itself instead of the file the
4547 link points to.
4548It is an error to use dir_fd or follow_symlinks when specifying path
4549 as an open file descriptor.
4550dir_fd and follow_symlinks may not be available on your platform.
4551 If they are unavailable, using them will raise a NotImplementedError.
4552
4553[clinic start generated code]*/
4554
Larry Hastings2f936352014-08-05 14:04:04 +10004555static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004556os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4557 int dir_fd, int follow_symlinks)
4558/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004559{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560#ifdef MS_WINDOWS
4561 HANDLE hFile;
4562 FILETIME atime, mtime;
4563#else
4564 int result;
4565#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004566
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004568 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004569
Christian Heimesb3c87242013-08-01 00:08:16 +02004570 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004571
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 if (times && (times != Py_None) && ns) {
4573 PyErr_SetString(PyExc_ValueError,
4574 "utime: you may specify either 'times'"
4575 " or 'ns' but not both");
4576 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004577 }
4578
4579 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004580 time_t a_sec, m_sec;
4581 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004582 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583 PyErr_SetString(PyExc_TypeError,
4584 "utime: 'times' must be either"
4585 " a tuple of two ints or None");
4586 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004587 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004589 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004590 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004591 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004592 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004593 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004594 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004595 utime.atime_s = a_sec;
4596 utime.atime_ns = a_nsec;
4597 utime.mtime_s = m_sec;
4598 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004599 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004601 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004602 PyErr_SetString(PyExc_TypeError,
4603 "utime: 'ns' must be a tuple of two ints");
4604 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004605 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004607 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004609 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610 &utime.mtime_s, &utime.mtime_ns)) {
4611 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004612 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613 }
4614 else {
4615 /* times and ns are both None/unspecified. use "now". */
4616 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004617 }
4618
Victor Stinner4552ced2015-09-21 22:37:15 +02004619#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620 if (follow_symlinks_specified("utime", follow_symlinks))
4621 goto exit;
4622#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004623
Larry Hastings2f936352014-08-05 14:04:04 +10004624 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4625 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4626 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004628
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629#if !defined(HAVE_UTIMENSAT)
4630 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004631 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632 "utime: cannot use dir_fd and follow_symlinks "
4633 "together on this platform");
4634 goto exit;
4635 }
4636#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004637
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004638#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004640 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4641 NULL, OPEN_EXISTING,
4642 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004643 Py_END_ALLOW_THREADS
4644 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004645 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004647 }
4648
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004650 GetSystemTimeAsFileTime(&mtime);
4651 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004652 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004653 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004654 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4655 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004656 }
4657 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4658 /* Avoid putting the file name into the error here,
4659 as that may confuse the user into believing that
4660 something is wrong with the file, when it also
4661 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004662 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004664 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004665#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004666 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004667
Victor Stinner4552ced2015-09-21 22:37:15 +02004668#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004670 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004672#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673
Victor Stinner528a9ab2015-09-03 21:30:26 +02004674#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004676 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004677 else
4678#endif
4679
Victor Stinner528a9ab2015-09-03 21:30:26 +02004680#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004681 if (path->fd != -1)
4682 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 else
4684#endif
4685
Larry Hastings2f936352014-08-05 14:04:04 +10004686 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687
4688 Py_END_ALLOW_THREADS
4689
4690 if (result < 0) {
4691 /* see previous comment about not putting filename in error here */
4692 return_value = posix_error();
4693 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004694 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004695
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004696#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004697
4698 Py_INCREF(Py_None);
4699 return_value = Py_None;
4700
4701exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702#ifdef MS_WINDOWS
4703 if (hFile != INVALID_HANDLE_VALUE)
4704 CloseHandle(hFile);
4705#endif
4706 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004707}
4708
Guido van Rossum3b066191991-06-04 19:40:25 +00004709/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004710
Larry Hastings2f936352014-08-05 14:04:04 +10004711
4712/*[clinic input]
4713os._exit
4714
4715 status: int
4716
4717Exit to the system with specified status, without normal exit processing.
4718[clinic start generated code]*/
4719
Larry Hastings2f936352014-08-05 14:04:04 +10004720static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004721os__exit_impl(PyObject *module, int status)
4722/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004723{
4724 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004725 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004726}
4727
Steve Dowercc16be82016-09-08 10:35:16 -07004728#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4729#define EXECV_CHAR wchar_t
4730#else
4731#define EXECV_CHAR char
4732#endif
4733
Martin v. Löwis114619e2002-10-07 06:44:21 +00004734#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4735static void
Steve Dowercc16be82016-09-08 10:35:16 -07004736free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004737{
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 Py_ssize_t i;
4739 for (i = 0; i < count; i++)
4740 PyMem_Free(array[i]);
4741 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004742}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004743
Berker Peksag81816462016-09-15 20:19:47 +03004744static int
4745fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004746{
Victor Stinner8c62be82010-05-06 00:08:46 +00004747 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004748 PyObject *ub;
4749 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004750#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004751 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004752 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004753 *out = PyUnicode_AsWideCharString(ub, &size);
4754 if (*out)
4755 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004756#else
Berker Peksag81816462016-09-15 20:19:47 +03004757 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004758 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004759 size = PyBytes_GET_SIZE(ub);
4760 *out = PyMem_Malloc(size + 1);
4761 if (*out) {
4762 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4763 result = 1;
4764 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004765 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004766#endif
Berker Peksag81816462016-09-15 20:19:47 +03004767 Py_DECREF(ub);
4768 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004769}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004770#endif
4771
Ross Lagerwall7807c352011-03-17 20:20:30 +02004772#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004773static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004774parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4775{
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 Py_ssize_t i, pos, envc;
4777 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004778 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004779 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004780
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 i = PyMapping_Size(env);
4782 if (i < 0)
4783 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004784 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 if (envlist == NULL) {
4786 PyErr_NoMemory();
4787 return NULL;
4788 }
4789 envc = 0;
4790 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004791 if (!keys)
4792 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004794 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 goto error;
4796 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4797 PyErr_Format(PyExc_TypeError,
4798 "env.keys() or env.values() is not a list");
4799 goto error;
4800 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004801
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 for (pos = 0; pos < i; pos++) {
4803 key = PyList_GetItem(keys, pos);
4804 val = PyList_GetItem(vals, pos);
4805 if (!key || !val)
4806 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004807
Berker Peksag81816462016-09-15 20:19:47 +03004808#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4809 if (!PyUnicode_FSDecoder(key, &key2))
4810 goto error;
4811 if (!PyUnicode_FSDecoder(val, &val2)) {
4812 Py_DECREF(key2);
4813 goto error;
4814 }
4815 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4816#else
4817 if (!PyUnicode_FSConverter(key, &key2))
4818 goto error;
4819 if (!PyUnicode_FSConverter(val, &val2)) {
4820 Py_DECREF(key2);
4821 goto error;
4822 }
4823 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4824 PyBytes_AS_STRING(val2));
4825#endif
4826 Py_DECREF(key2);
4827 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004828 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004830
4831 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4832 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004833 goto error;
4834 }
Berker Peksag81816462016-09-15 20:19:47 +03004835
Steve Dowercc16be82016-09-08 10:35:16 -07004836 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004837 }
4838 Py_DECREF(vals);
4839 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004840
Victor Stinner8c62be82010-05-06 00:08:46 +00004841 envlist[envc] = 0;
4842 *envc_ptr = envc;
4843 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004844
4845error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 Py_XDECREF(keys);
4847 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004848 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004850}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004851
Steve Dowercc16be82016-09-08 10:35:16 -07004852static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004853parse_arglist(PyObject* argv, Py_ssize_t *argc)
4854{
4855 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004856 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004857 if (argvlist == NULL) {
4858 PyErr_NoMemory();
4859 return NULL;
4860 }
4861 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004862 PyObject* item = PySequence_ITEM(argv, i);
4863 if (item == NULL)
4864 goto fail;
4865 if (!fsconvert_strdup(item, &argvlist[i])) {
4866 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004867 goto fail;
4868 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004869 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004870 }
4871 argvlist[*argc] = NULL;
4872 return argvlist;
4873fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004874 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004875 free_string_array(argvlist, *argc);
4876 return NULL;
4877}
Steve Dowercc16be82016-09-08 10:35:16 -07004878
Ross Lagerwall7807c352011-03-17 20:20:30 +02004879#endif
4880
Larry Hastings2f936352014-08-05 14:04:04 +10004881
Ross Lagerwall7807c352011-03-17 20:20:30 +02004882#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004883/*[clinic input]
4884os.execv
4885
Steve Dowercc16be82016-09-08 10:35:16 -07004886 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004887 Path of executable file.
4888 argv: object
4889 Tuple or list of strings.
4890 /
4891
4892Execute an executable path with arguments, replacing current process.
4893[clinic start generated code]*/
4894
Larry Hastings2f936352014-08-05 14:04:04 +10004895static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004896os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4897/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004898{
Steve Dowercc16be82016-09-08 10:35:16 -07004899 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004900 Py_ssize_t argc;
4901
4902 /* execv has two arguments: (path, argv), where
4903 argv is a list or tuple of strings. */
4904
Ross Lagerwall7807c352011-03-17 20:20:30 +02004905 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4906 PyErr_SetString(PyExc_TypeError,
4907 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004908 return NULL;
4909 }
4910 argc = PySequence_Size(argv);
4911 if (argc < 1) {
4912 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004913 return NULL;
4914 }
4915
4916 argvlist = parse_arglist(argv, &argc);
4917 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004918 return NULL;
4919 }
Steve Dowerbce26262016-11-19 19:17:26 -08004920 if (!argvlist[0][0]) {
4921 PyErr_SetString(PyExc_ValueError,
4922 "execv() arg 2 first element cannot be empty");
4923 free_string_array(argvlist, argc);
4924 return NULL;
4925 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004926
Steve Dowerbce26262016-11-19 19:17:26 -08004927 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004928#ifdef HAVE_WEXECV
4929 _wexecv(path->wide, argvlist);
4930#else
4931 execv(path->narrow, argvlist);
4932#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004933 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004934
4935 /* If we get here it's definitely an error */
4936
4937 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004938 return posix_error();
4939}
4940
Larry Hastings2f936352014-08-05 14:04:04 +10004941
4942/*[clinic input]
4943os.execve
4944
4945 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4946 Path of executable file.
4947 argv: object
4948 Tuple or list of strings.
4949 env: object
4950 Dictionary of strings mapping to strings.
4951
4952Execute an executable path with arguments, replacing current process.
4953[clinic start generated code]*/
4954
Larry Hastings2f936352014-08-05 14:04:04 +10004955static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004956os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4957/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004958{
Steve Dowercc16be82016-09-08 10:35:16 -07004959 EXECV_CHAR **argvlist = NULL;
4960 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004961 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004962
Victor Stinner8c62be82010-05-06 00:08:46 +00004963 /* execve has three arguments: (path, argv, env), where
4964 argv is a list or tuple of strings and env is a dictionary
4965 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004966
Ross Lagerwall7807c352011-03-17 20:20:30 +02004967 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004969 "execve: argv must be a tuple or list");
4970 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004971 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004972 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08004973 if (argc < 1) {
4974 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
4975 return NULL;
4976 }
4977
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 if (!PyMapping_Check(env)) {
4979 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980 "execve: environment must be a mapping object");
4981 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004983
Ross Lagerwall7807c352011-03-17 20:20:30 +02004984 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004986 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 }
Steve Dowerbce26262016-11-19 19:17:26 -08004988 if (!argvlist[0][0]) {
4989 PyErr_SetString(PyExc_ValueError,
4990 "execve: argv first element cannot be empty");
4991 goto fail;
4992 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004993
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 envlist = parse_envlist(env, &envc);
4995 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004996 goto fail;
4997
Steve Dowerbce26262016-11-19 19:17:26 -08004998 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004999#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005000 if (path->fd > -1)
5001 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005002 else
5003#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005004#ifdef HAVE_WEXECV
5005 _wexecve(path->wide, argvlist, envlist);
5006#else
Larry Hastings2f936352014-08-05 14:04:04 +10005007 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005008#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005009 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005010
5011 /* If we get here it's definitely an error */
5012
Larry Hastings2f936352014-08-05 14:04:04 +10005013 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014
Steve Dowercc16be82016-09-08 10:35:16 -07005015 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005017 if (argvlist)
5018 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019 return NULL;
5020}
Steve Dowercc16be82016-09-08 10:35:16 -07005021
Larry Hastings9cf065c2012-06-22 16:30:09 -07005022#endif /* HAVE_EXECV */
5023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005024
Steve Dowercc16be82016-09-08 10:35:16 -07005025#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005026/*[clinic input]
5027os.spawnv
5028
5029 mode: int
5030 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005031 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005032 Path of executable file.
5033 argv: object
5034 Tuple or list of strings.
5035 /
5036
5037Execute the program specified by path in a new process.
5038[clinic start generated code]*/
5039
Larry Hastings2f936352014-08-05 14:04:04 +10005040static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005041os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5042/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005043{
Steve Dowercc16be82016-09-08 10:35:16 -07005044 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005045 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005047 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005048 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005049
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 /* spawnv has three arguments: (mode, path, argv), where
5051 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005052
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 if (PyList_Check(argv)) {
5054 argc = PyList_Size(argv);
5055 getitem = PyList_GetItem;
5056 }
5057 else if (PyTuple_Check(argv)) {
5058 argc = PyTuple_Size(argv);
5059 getitem = PyTuple_GetItem;
5060 }
5061 else {
5062 PyErr_SetString(PyExc_TypeError,
5063 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 return NULL;
5065 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005066 if (argc == 0) {
5067 PyErr_SetString(PyExc_ValueError,
5068 "spawnv() arg 2 cannot be empty");
5069 return NULL;
5070 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005071
Steve Dowercc16be82016-09-08 10:35:16 -07005072 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005073 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 return PyErr_NoMemory();
5075 }
5076 for (i = 0; i < argc; i++) {
5077 if (!fsconvert_strdup((*getitem)(argv, i),
5078 &argvlist[i])) {
5079 free_string_array(argvlist, i);
5080 PyErr_SetString(
5081 PyExc_TypeError,
5082 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 return NULL;
5084 }
Steve Dower93ff8722016-11-19 19:03:54 -08005085 if (i == 0 && !argvlist[0][0]) {
5086 free_string_array(argvlist, i);
5087 PyErr_SetString(
5088 PyExc_ValueError,
5089 "spawnv() arg 2 first element cannot be empty");
5090 return NULL;
5091 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 }
5093 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005094
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 if (mode == _OLD_P_OVERLAY)
5096 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005097
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005099 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005100#ifdef HAVE_WSPAWNV
5101 spawnval = _wspawnv(mode, path->wide, argvlist);
5102#else
5103 spawnval = _spawnv(mode, path->narrow, argvlist);
5104#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005105 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005107
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005109
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 if (spawnval == -1)
5111 return posix_error();
5112 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005113 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005114}
5115
5116
Larry Hastings2f936352014-08-05 14:04:04 +10005117/*[clinic input]
5118os.spawnve
5119
5120 mode: int
5121 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005122 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005123 Path of executable file.
5124 argv: object
5125 Tuple or list of strings.
5126 env: object
5127 Dictionary of strings mapping to strings.
5128 /
5129
5130Execute the program specified by path in a new process.
5131[clinic start generated code]*/
5132
Larry Hastings2f936352014-08-05 14:04:04 +10005133static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005134os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005135 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005136/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005137{
Steve Dowercc16be82016-09-08 10:35:16 -07005138 EXECV_CHAR **argvlist;
5139 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005141 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005142 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5144 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005145
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 /* spawnve has four arguments: (mode, path, argv, env), where
5147 argv is a list or tuple of strings and env is a dictionary
5148 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005149
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 if (PyList_Check(argv)) {
5151 argc = PyList_Size(argv);
5152 getitem = PyList_GetItem;
5153 }
5154 else if (PyTuple_Check(argv)) {
5155 argc = PyTuple_Size(argv);
5156 getitem = PyTuple_GetItem;
5157 }
5158 else {
5159 PyErr_SetString(PyExc_TypeError,
5160 "spawnve() arg 2 must be a tuple or list");
5161 goto fail_0;
5162 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005163 if (argc == 0) {
5164 PyErr_SetString(PyExc_ValueError,
5165 "spawnve() arg 2 cannot be empty");
5166 goto fail_0;
5167 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 if (!PyMapping_Check(env)) {
5169 PyErr_SetString(PyExc_TypeError,
5170 "spawnve() arg 3 must be a mapping object");
5171 goto fail_0;
5172 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005173
Steve Dowercc16be82016-09-08 10:35:16 -07005174 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 if (argvlist == NULL) {
5176 PyErr_NoMemory();
5177 goto fail_0;
5178 }
5179 for (i = 0; i < argc; i++) {
5180 if (!fsconvert_strdup((*getitem)(argv, i),
5181 &argvlist[i]))
5182 {
5183 lastarg = i;
5184 goto fail_1;
5185 }
Steve Dowerbce26262016-11-19 19:17:26 -08005186 if (i == 0 && !argvlist[0][0]) {
5187 lastarg = i;
5188 PyErr_SetString(
5189 PyExc_ValueError,
5190 "spawnv() arg 2 first element cannot be empty");
5191 goto fail_1;
5192 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 }
5194 lastarg = argc;
5195 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005196
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 envlist = parse_envlist(env, &envc);
5198 if (envlist == NULL)
5199 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005200
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 if (mode == _OLD_P_OVERLAY)
5202 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005203
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005205 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005206#ifdef HAVE_WSPAWNV
5207 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5208#else
5209 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5210#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005211 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005213
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 if (spawnval == -1)
5215 (void) posix_error();
5216 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005217 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005218
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 while (--envc >= 0)
5220 PyMem_DEL(envlist[envc]);
5221 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005222 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005223 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005224 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005226}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005227
Guido van Rossuma1065681999-01-25 23:20:23 +00005228#endif /* HAVE_SPAWNV */
5229
5230
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005231#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005232/*[clinic input]
5233os.fork1
5234
5235Fork a child process with a single multiplexed (i.e., not bound) thread.
5236
5237Return 0 to child process and PID of child to parent process.
5238[clinic start generated code]*/
5239
Larry Hastings2f936352014-08-05 14:04:04 +10005240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005241os_fork1_impl(PyObject *module)
5242/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005243{
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 pid_t pid;
5245 int result = 0;
5246 _PyImport_AcquireLock();
5247 pid = fork1();
5248 if (pid == 0) {
5249 /* child: this clobbers and resets the import lock. */
5250 PyOS_AfterFork();
5251 } else {
5252 /* parent: release the import lock. */
5253 result = _PyImport_ReleaseLock();
5254 }
5255 if (pid == -1)
5256 return posix_error();
5257 if (result < 0) {
5258 /* Don't clobber the OSError if the fork failed. */
5259 PyErr_SetString(PyExc_RuntimeError,
5260 "not holding the import lock");
5261 return NULL;
5262 }
5263 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005264}
Larry Hastings2f936352014-08-05 14:04:04 +10005265#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005266
5267
Guido van Rossumad0ee831995-03-01 10:34:45 +00005268#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005269/*[clinic input]
5270os.fork
5271
5272Fork a child process.
5273
5274Return 0 to child process and PID of child to parent process.
5275[clinic start generated code]*/
5276
Larry Hastings2f936352014-08-05 14:04:04 +10005277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005278os_fork_impl(PyObject *module)
5279/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005280{
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 pid_t pid;
5282 int result = 0;
5283 _PyImport_AcquireLock();
5284 pid = fork();
5285 if (pid == 0) {
5286 /* child: this clobbers and resets the import lock. */
5287 PyOS_AfterFork();
5288 } else {
5289 /* parent: release the import lock. */
5290 result = _PyImport_ReleaseLock();
5291 }
5292 if (pid == -1)
5293 return posix_error();
5294 if (result < 0) {
5295 /* Don't clobber the OSError if the fork failed. */
5296 PyErr_SetString(PyExc_RuntimeError,
5297 "not holding the import lock");
5298 return NULL;
5299 }
5300 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005301}
Larry Hastings2f936352014-08-05 14:04:04 +10005302#endif /* HAVE_FORK */
5303
Guido van Rossum85e3b011991-06-03 12:42:10 +00005304
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005305#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005306#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005307/*[clinic input]
5308os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005309
Larry Hastings2f936352014-08-05 14:04:04 +10005310 policy: int
5311
5312Get the maximum scheduling priority for policy.
5313[clinic start generated code]*/
5314
Larry Hastings2f936352014-08-05 14:04:04 +10005315static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005316os_sched_get_priority_max_impl(PyObject *module, int policy)
5317/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005318{
5319 int max;
5320
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005321 max = sched_get_priority_max(policy);
5322 if (max < 0)
5323 return posix_error();
5324 return PyLong_FromLong(max);
5325}
5326
Larry Hastings2f936352014-08-05 14:04:04 +10005327
5328/*[clinic input]
5329os.sched_get_priority_min
5330
5331 policy: int
5332
5333Get the minimum scheduling priority for policy.
5334[clinic start generated code]*/
5335
Larry Hastings2f936352014-08-05 14:04:04 +10005336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005337os_sched_get_priority_min_impl(PyObject *module, int policy)
5338/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005339{
5340 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005341 if (min < 0)
5342 return posix_error();
5343 return PyLong_FromLong(min);
5344}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005345#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5346
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005347
Larry Hastings2f936352014-08-05 14:04:04 +10005348#ifdef HAVE_SCHED_SETSCHEDULER
5349/*[clinic input]
5350os.sched_getscheduler
5351 pid: pid_t
5352 /
5353
5354Get the scheduling policy for the process identifiedy by pid.
5355
5356Passing 0 for pid returns the scheduling policy for the calling process.
5357[clinic start generated code]*/
5358
Larry Hastings2f936352014-08-05 14:04:04 +10005359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005360os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5361/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005362{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005363 int policy;
5364
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005365 policy = sched_getscheduler(pid);
5366 if (policy < 0)
5367 return posix_error();
5368 return PyLong_FromLong(policy);
5369}
Larry Hastings2f936352014-08-05 14:04:04 +10005370#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005371
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005372
5373#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005374/*[clinic input]
5375class os.sched_param "PyObject *" "&SchedParamType"
5376
5377@classmethod
5378os.sched_param.__new__
5379
5380 sched_priority: object
5381 A scheduling parameter.
5382
5383Current has only one field: sched_priority");
5384[clinic start generated code]*/
5385
Larry Hastings2f936352014-08-05 14:04:04 +10005386static PyObject *
5387os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005388/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005389{
5390 PyObject *res;
5391
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005392 res = PyStructSequence_New(type);
5393 if (!res)
5394 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005395 Py_INCREF(sched_priority);
5396 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005397 return res;
5398}
5399
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005400
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005401PyDoc_VAR(os_sched_param__doc__);
5402
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005403static PyStructSequence_Field sched_param_fields[] = {
5404 {"sched_priority", "the scheduling priority"},
5405 {0}
5406};
5407
5408static PyStructSequence_Desc sched_param_desc = {
5409 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005410 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005411 sched_param_fields,
5412 1
5413};
5414
5415static int
5416convert_sched_param(PyObject *param, struct sched_param *res)
5417{
5418 long priority;
5419
5420 if (Py_TYPE(param) != &SchedParamType) {
5421 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5422 return 0;
5423 }
5424 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5425 if (priority == -1 && PyErr_Occurred())
5426 return 0;
5427 if (priority > INT_MAX || priority < INT_MIN) {
5428 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5429 return 0;
5430 }
5431 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5432 return 1;
5433}
Larry Hastings2f936352014-08-05 14:04:04 +10005434#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005435
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005436
5437#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005438/*[clinic input]
5439os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005440
Larry Hastings2f936352014-08-05 14:04:04 +10005441 pid: pid_t
5442 policy: int
5443 param: sched_param
5444 /
5445
5446Set the scheduling policy for the process identified by pid.
5447
5448If pid is 0, the calling process is changed.
5449param is an instance of sched_param.
5450[clinic start generated code]*/
5451
Larry Hastings2f936352014-08-05 14:04:04 +10005452static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005453os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005454 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005455/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005456{
Jesus Cea9c822272011-09-10 01:40:52 +02005457 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005458 ** sched_setscheduler() returns 0 in Linux, but the previous
5459 ** scheduling policy under Solaris/Illumos, and others.
5460 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005461 */
Larry Hastings2f936352014-08-05 14:04:04 +10005462 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005463 return posix_error();
5464 Py_RETURN_NONE;
5465}
Larry Hastings2f936352014-08-05 14:04:04 +10005466#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005467
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005468
5469#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005470/*[clinic input]
5471os.sched_getparam
5472 pid: pid_t
5473 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005474
Larry Hastings2f936352014-08-05 14:04:04 +10005475Returns scheduling parameters for the process identified by pid.
5476
5477If pid is 0, returns parameters for the calling process.
5478Return value is an instance of sched_param.
5479[clinic start generated code]*/
5480
Larry Hastings2f936352014-08-05 14:04:04 +10005481static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005482os_sched_getparam_impl(PyObject *module, pid_t pid)
5483/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005484{
5485 struct sched_param param;
5486 PyObject *result;
5487 PyObject *priority;
5488
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005489 if (sched_getparam(pid, &param))
5490 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005491 result = PyStructSequence_New(&SchedParamType);
5492 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005493 return NULL;
5494 priority = PyLong_FromLong(param.sched_priority);
5495 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005496 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005497 return NULL;
5498 }
Larry Hastings2f936352014-08-05 14:04:04 +10005499 PyStructSequence_SET_ITEM(result, 0, priority);
5500 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005501}
5502
Larry Hastings2f936352014-08-05 14:04:04 +10005503
5504/*[clinic input]
5505os.sched_setparam
5506 pid: pid_t
5507 param: sched_param
5508 /
5509
5510Set scheduling parameters for the process identified by pid.
5511
5512If pid is 0, sets parameters for the calling process.
5513param should be an instance of sched_param.
5514[clinic start generated code]*/
5515
Larry Hastings2f936352014-08-05 14:04:04 +10005516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005517os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005518 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005519/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005520{
5521 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005522 return posix_error();
5523 Py_RETURN_NONE;
5524}
Larry Hastings2f936352014-08-05 14:04:04 +10005525#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005526
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005527
5528#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005529/*[clinic input]
5530os.sched_rr_get_interval -> double
5531 pid: pid_t
5532 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005533
Larry Hastings2f936352014-08-05 14:04:04 +10005534Return the round-robin quantum for the process identified by pid, in seconds.
5535
5536Value returned is a float.
5537[clinic start generated code]*/
5538
Larry Hastings2f936352014-08-05 14:04:04 +10005539static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005540os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5541/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005542{
5543 struct timespec interval;
5544 if (sched_rr_get_interval(pid, &interval)) {
5545 posix_error();
5546 return -1.0;
5547 }
5548 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5549}
5550#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005551
Larry Hastings2f936352014-08-05 14:04:04 +10005552
5553/*[clinic input]
5554os.sched_yield
5555
5556Voluntarily relinquish the CPU.
5557[clinic start generated code]*/
5558
Larry Hastings2f936352014-08-05 14:04:04 +10005559static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005560os_sched_yield_impl(PyObject *module)
5561/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005562{
5563 if (sched_yield())
5564 return posix_error();
5565 Py_RETURN_NONE;
5566}
5567
Benjamin Peterson2740af82011-08-02 17:41:34 -05005568#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005569/* The minimum number of CPUs allocated in a cpu_set_t */
5570static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571
Larry Hastings2f936352014-08-05 14:04:04 +10005572/*[clinic input]
5573os.sched_setaffinity
5574 pid: pid_t
5575 mask : object
5576 /
5577
5578Set the CPU affinity of the process identified by pid to mask.
5579
5580mask should be an iterable of integers identifying CPUs.
5581[clinic start generated code]*/
5582
Larry Hastings2f936352014-08-05 14:04:04 +10005583static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005584os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5585/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005586{
Antoine Pitrou84869872012-08-04 16:16:35 +02005587 int ncpus;
5588 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005589 cpu_set_t *cpu_set = NULL;
5590 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005591
Larry Hastings2f936352014-08-05 14:04:04 +10005592 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005593 if (iterator == NULL)
5594 return NULL;
5595
5596 ncpus = NCPUS_START;
5597 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005598 cpu_set = CPU_ALLOC(ncpus);
5599 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005600 PyErr_NoMemory();
5601 goto error;
5602 }
Larry Hastings2f936352014-08-05 14:04:04 +10005603 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005604
5605 while ((item = PyIter_Next(iterator))) {
5606 long cpu;
5607 if (!PyLong_Check(item)) {
5608 PyErr_Format(PyExc_TypeError,
5609 "expected an iterator of ints, "
5610 "but iterator yielded %R",
5611 Py_TYPE(item));
5612 Py_DECREF(item);
5613 goto error;
5614 }
5615 cpu = PyLong_AsLong(item);
5616 Py_DECREF(item);
5617 if (cpu < 0) {
5618 if (!PyErr_Occurred())
5619 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5620 goto error;
5621 }
5622 if (cpu > INT_MAX - 1) {
5623 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5624 goto error;
5625 }
5626 if (cpu >= ncpus) {
5627 /* Grow CPU mask to fit the CPU number */
5628 int newncpus = ncpus;
5629 cpu_set_t *newmask;
5630 size_t newsetsize;
5631 while (newncpus <= cpu) {
5632 if (newncpus > INT_MAX / 2)
5633 newncpus = cpu + 1;
5634 else
5635 newncpus = newncpus * 2;
5636 }
5637 newmask = CPU_ALLOC(newncpus);
5638 if (newmask == NULL) {
5639 PyErr_NoMemory();
5640 goto error;
5641 }
5642 newsetsize = CPU_ALLOC_SIZE(newncpus);
5643 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005644 memcpy(newmask, cpu_set, setsize);
5645 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005646 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005647 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005648 ncpus = newncpus;
5649 }
Larry Hastings2f936352014-08-05 14:04:04 +10005650 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005651 }
5652 Py_CLEAR(iterator);
5653
Larry Hastings2f936352014-08-05 14:04:04 +10005654 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005655 posix_error();
5656 goto error;
5657 }
Larry Hastings2f936352014-08-05 14:04:04 +10005658 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005659 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005660
5661error:
Larry Hastings2f936352014-08-05 14:04:04 +10005662 if (cpu_set)
5663 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005664 Py_XDECREF(iterator);
5665 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005666}
5667
Larry Hastings2f936352014-08-05 14:04:04 +10005668
5669/*[clinic input]
5670os.sched_getaffinity
5671 pid: pid_t
5672 /
5673
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005674Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005675
5676The affinity is returned as a set of CPU identifiers.
5677[clinic start generated code]*/
5678
Larry Hastings2f936352014-08-05 14:04:04 +10005679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005680os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005681/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005682{
Antoine Pitrou84869872012-08-04 16:16:35 +02005683 int cpu, ncpus, count;
5684 size_t setsize;
5685 cpu_set_t *mask = NULL;
5686 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005687
Antoine Pitrou84869872012-08-04 16:16:35 +02005688 ncpus = NCPUS_START;
5689 while (1) {
5690 setsize = CPU_ALLOC_SIZE(ncpus);
5691 mask = CPU_ALLOC(ncpus);
5692 if (mask == NULL)
5693 return PyErr_NoMemory();
5694 if (sched_getaffinity(pid, setsize, mask) == 0)
5695 break;
5696 CPU_FREE(mask);
5697 if (errno != EINVAL)
5698 return posix_error();
5699 if (ncpus > INT_MAX / 2) {
5700 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5701 "a large enough CPU set");
5702 return NULL;
5703 }
5704 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005705 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005706
5707 res = PySet_New(NULL);
5708 if (res == NULL)
5709 goto error;
5710 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5711 if (CPU_ISSET_S(cpu, setsize, mask)) {
5712 PyObject *cpu_num = PyLong_FromLong(cpu);
5713 --count;
5714 if (cpu_num == NULL)
5715 goto error;
5716 if (PySet_Add(res, cpu_num)) {
5717 Py_DECREF(cpu_num);
5718 goto error;
5719 }
5720 Py_DECREF(cpu_num);
5721 }
5722 }
5723 CPU_FREE(mask);
5724 return res;
5725
5726error:
5727 if (mask)
5728 CPU_FREE(mask);
5729 Py_XDECREF(res);
5730 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005731}
5732
Benjamin Peterson2740af82011-08-02 17:41:34 -05005733#endif /* HAVE_SCHED_SETAFFINITY */
5734
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005735#endif /* HAVE_SCHED_H */
5736
Larry Hastings2f936352014-08-05 14:04:04 +10005737
Neal Norwitzb59798b2003-03-21 01:43:31 +00005738/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005739/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5740#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005741#define DEV_PTY_FILE "/dev/ptc"
5742#define HAVE_DEV_PTMX
5743#else
5744#define DEV_PTY_FILE "/dev/ptmx"
5745#endif
5746
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005747#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005748#ifdef HAVE_PTY_H
5749#include <pty.h>
5750#else
5751#ifdef HAVE_LIBUTIL_H
5752#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005753#else
5754#ifdef HAVE_UTIL_H
5755#include <util.h>
5756#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005757#endif /* HAVE_LIBUTIL_H */
5758#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005759#ifdef HAVE_STROPTS_H
5760#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005761#endif
5762#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005763
Larry Hastings2f936352014-08-05 14:04:04 +10005764
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005765#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005766/*[clinic input]
5767os.openpty
5768
5769Open a pseudo-terminal.
5770
5771Return a tuple of (master_fd, slave_fd) containing open file descriptors
5772for both the master and slave ends.
5773[clinic start generated code]*/
5774
Larry Hastings2f936352014-08-05 14:04:04 +10005775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005776os_openpty_impl(PyObject *module)
5777/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005778{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005779 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005780#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005781 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005782#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005783#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005784 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005785#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005787#endif
5788#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005789
Thomas Wouters70c21a12000-07-14 14:28:33 +00005790#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005792 goto posix_error;
5793
5794 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5795 goto error;
5796 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5797 goto error;
5798
Neal Norwitzb59798b2003-03-21 01:43:31 +00005799#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5801 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005802 goto posix_error;
5803 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5804 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005805
Victor Stinnerdaf45552013-08-28 00:53:59 +02005806 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005807 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005808 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005809
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005810#else
Victor Stinner000de532013-11-25 23:19:58 +01005811 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005812 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005813 goto posix_error;
5814
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005816
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 /* change permission of slave */
5818 if (grantpt(master_fd) < 0) {
5819 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005820 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005822
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 /* unlock slave */
5824 if (unlockpt(master_fd) < 0) {
5825 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005826 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005827 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005828
Victor Stinner8c62be82010-05-06 00:08:46 +00005829 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005830
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 slave_name = ptsname(master_fd); /* get name of slave */
5832 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005833 goto posix_error;
5834
5835 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005836 if (slave_fd == -1)
5837 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005838
5839 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5840 goto posix_error;
5841
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005842#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005843 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5844 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005845#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005846 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005847#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005848#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005849#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005850
Victor Stinner8c62be82010-05-06 00:08:46 +00005851 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005852
Victor Stinnerdaf45552013-08-28 00:53:59 +02005853posix_error:
5854 posix_error();
5855error:
5856 if (master_fd != -1)
5857 close(master_fd);
5858 if (slave_fd != -1)
5859 close(slave_fd);
5860 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005861}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005862#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005863
Larry Hastings2f936352014-08-05 14:04:04 +10005864
Fred Drake8cef4cf2000-06-28 16:40:38 +00005865#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005866/*[clinic input]
5867os.forkpty
5868
5869Fork a new process with a new pseudo-terminal as controlling tty.
5870
5871Returns a tuple of (pid, master_fd).
5872Like fork(), return pid of 0 to the child process,
5873and pid of child to the parent process.
5874To both, return fd of newly opened pseudo-terminal.
5875[clinic start generated code]*/
5876
Larry Hastings2f936352014-08-05 14:04:04 +10005877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005878os_forkpty_impl(PyObject *module)
5879/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005880{
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 int master_fd = -1, result = 0;
5882 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005883
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 _PyImport_AcquireLock();
5885 pid = forkpty(&master_fd, NULL, NULL, NULL);
5886 if (pid == 0) {
5887 /* child: this clobbers and resets the import lock. */
5888 PyOS_AfterFork();
5889 } else {
5890 /* parent: release the import lock. */
5891 result = _PyImport_ReleaseLock();
5892 }
5893 if (pid == -1)
5894 return posix_error();
5895 if (result < 0) {
5896 /* Don't clobber the OSError if the fork failed. */
5897 PyErr_SetString(PyExc_RuntimeError,
5898 "not holding the import lock");
5899 return NULL;
5900 }
5901 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005902}
Larry Hastings2f936352014-08-05 14:04:04 +10005903#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005904
Ross Lagerwall7807c352011-03-17 20:20:30 +02005905
Guido van Rossumad0ee831995-03-01 10:34:45 +00005906#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005907/*[clinic input]
5908os.getegid
5909
5910Return the current process's effective group id.
5911[clinic start generated code]*/
5912
Larry Hastings2f936352014-08-05 14:04:04 +10005913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005914os_getegid_impl(PyObject *module)
5915/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005916{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005917 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005918}
Larry Hastings2f936352014-08-05 14:04:04 +10005919#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005921
Guido van Rossumad0ee831995-03-01 10:34:45 +00005922#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005923/*[clinic input]
5924os.geteuid
5925
5926Return the current process's effective user id.
5927[clinic start generated code]*/
5928
Larry Hastings2f936352014-08-05 14:04:04 +10005929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005930os_geteuid_impl(PyObject *module)
5931/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005932{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005933 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005934}
Larry Hastings2f936352014-08-05 14:04:04 +10005935#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005936
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005937
Guido van Rossumad0ee831995-03-01 10:34:45 +00005938#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005939/*[clinic input]
5940os.getgid
5941
5942Return the current process's group id.
5943[clinic start generated code]*/
5944
Larry Hastings2f936352014-08-05 14:04:04 +10005945static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005946os_getgid_impl(PyObject *module)
5947/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005948{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005949 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005950}
Larry Hastings2f936352014-08-05 14:04:04 +10005951#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005953
Berker Peksag39404992016-09-15 20:45:16 +03005954#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10005955/*[clinic input]
5956os.getpid
5957
5958Return the current process id.
5959[clinic start generated code]*/
5960
Larry Hastings2f936352014-08-05 14:04:04 +10005961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005962os_getpid_impl(PyObject *module)
5963/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005964{
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005966}
Berker Peksag39404992016-09-15 20:45:16 +03005967#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005968
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005969#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005970
5971/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005972PyDoc_STRVAR(posix_getgrouplist__doc__,
5973"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5974Returns a list of groups to which a user belongs.\n\n\
5975 user: username to lookup\n\
5976 group: base group id of the user");
5977
5978static PyObject *
5979posix_getgrouplist(PyObject *self, PyObject *args)
5980{
5981#ifdef NGROUPS_MAX
5982#define MAX_GROUPS NGROUPS_MAX
5983#else
5984 /* defined to be 16 on Solaris7, so this should be a small number */
5985#define MAX_GROUPS 64
5986#endif
5987
5988 const char *user;
5989 int i, ngroups;
5990 PyObject *list;
5991#ifdef __APPLE__
5992 int *groups, basegid;
5993#else
5994 gid_t *groups, basegid;
5995#endif
5996 ngroups = MAX_GROUPS;
5997
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005998#ifdef __APPLE__
5999 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006000 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006001#else
6002 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6003 _Py_Gid_Converter, &basegid))
6004 return NULL;
6005#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006006
6007#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006008 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006009#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006010 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006011#endif
6012 if (groups == NULL)
6013 return PyErr_NoMemory();
6014
6015 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6016 PyMem_Del(groups);
6017 return posix_error();
6018 }
6019
6020 list = PyList_New(ngroups);
6021 if (list == NULL) {
6022 PyMem_Del(groups);
6023 return NULL;
6024 }
6025
6026 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006027#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006028 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006029#else
6030 PyObject *o = _PyLong_FromGid(groups[i]);
6031#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006032 if (o == NULL) {
6033 Py_DECREF(list);
6034 PyMem_Del(groups);
6035 return NULL;
6036 }
6037 PyList_SET_ITEM(list, i, o);
6038 }
6039
6040 PyMem_Del(groups);
6041
6042 return list;
6043}
Larry Hastings2f936352014-08-05 14:04:04 +10006044#endif /* HAVE_GETGROUPLIST */
6045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006046
Fred Drakec9680921999-12-13 16:37:25 +00006047#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006048/*[clinic input]
6049os.getgroups
6050
6051Return list of supplemental group IDs for the process.
6052[clinic start generated code]*/
6053
Larry Hastings2f936352014-08-05 14:04:04 +10006054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006055os_getgroups_impl(PyObject *module)
6056/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006057{
6058 PyObject *result = NULL;
6059
Fred Drakec9680921999-12-13 16:37:25 +00006060#ifdef NGROUPS_MAX
6061#define MAX_GROUPS NGROUPS_MAX
6062#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006063 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006064#define MAX_GROUPS 64
6065#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006067
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006068 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006069 * This is a helper variable to store the intermediate result when
6070 * that happens.
6071 *
6072 * To keep the code readable the OSX behaviour is unconditional,
6073 * according to the POSIX spec this should be safe on all unix-y
6074 * systems.
6075 */
6076 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006078
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006079#ifdef __APPLE__
6080 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6081 * there are more groups than can fit in grouplist. Therefore, on OS X
6082 * always first call getgroups with length 0 to get the actual number
6083 * of groups.
6084 */
6085 n = getgroups(0, NULL);
6086 if (n < 0) {
6087 return posix_error();
6088 } else if (n <= MAX_GROUPS) {
6089 /* groups will fit in existing array */
6090 alt_grouplist = grouplist;
6091 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006092 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006093 if (alt_grouplist == NULL) {
6094 errno = EINVAL;
6095 return posix_error();
6096 }
6097 }
6098
6099 n = getgroups(n, alt_grouplist);
6100 if (n == -1) {
6101 if (alt_grouplist != grouplist) {
6102 PyMem_Free(alt_grouplist);
6103 }
6104 return posix_error();
6105 }
6106#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006107 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006108 if (n < 0) {
6109 if (errno == EINVAL) {
6110 n = getgroups(0, NULL);
6111 if (n == -1) {
6112 return posix_error();
6113 }
6114 if (n == 0) {
6115 /* Avoid malloc(0) */
6116 alt_grouplist = grouplist;
6117 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006118 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006119 if (alt_grouplist == NULL) {
6120 errno = EINVAL;
6121 return posix_error();
6122 }
6123 n = getgroups(n, alt_grouplist);
6124 if (n == -1) {
6125 PyMem_Free(alt_grouplist);
6126 return posix_error();
6127 }
6128 }
6129 } else {
6130 return posix_error();
6131 }
6132 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006133#endif
6134
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006135 result = PyList_New(n);
6136 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006137 int i;
6138 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006139 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006141 Py_DECREF(result);
6142 result = NULL;
6143 break;
Fred Drakec9680921999-12-13 16:37:25 +00006144 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006146 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006147 }
6148
6149 if (alt_grouplist != grouplist) {
6150 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006152
Fred Drakec9680921999-12-13 16:37:25 +00006153 return result;
6154}
Larry Hastings2f936352014-08-05 14:04:04 +10006155#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006156
Antoine Pitroub7572f02009-12-02 20:46:48 +00006157#ifdef HAVE_INITGROUPS
6158PyDoc_STRVAR(posix_initgroups__doc__,
6159"initgroups(username, gid) -> None\n\n\
6160Call the system initgroups() to initialize the group access list with all of\n\
6161the groups of which the specified username is a member, plus the specified\n\
6162group id.");
6163
Larry Hastings2f936352014-08-05 14:04:04 +10006164/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006165static PyObject *
6166posix_initgroups(PyObject *self, PyObject *args)
6167{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006168 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006169 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006170 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006171#ifdef __APPLE__
6172 int gid;
6173#else
6174 gid_t gid;
6175#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006176
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006177#ifdef __APPLE__
6178 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6179 PyUnicode_FSConverter, &oname,
6180 &gid))
6181#else
6182 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6183 PyUnicode_FSConverter, &oname,
6184 _Py_Gid_Converter, &gid))
6185#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006187 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006188
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006189 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006190 Py_DECREF(oname);
6191 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006192 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006193
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006194 Py_RETURN_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();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006257 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006258}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006259#endif /* HAVE_SETPGRP */
6260
Guido van Rossumad0ee831995-03-01 10:34:45 +00006261#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006262
6263#ifdef MS_WINDOWS
6264#include <tlhelp32.h>
6265
6266static PyObject*
6267win32_getppid()
6268{
6269 HANDLE snapshot;
6270 pid_t mypid;
6271 PyObject* result = NULL;
6272 BOOL have_record;
6273 PROCESSENTRY32 pe;
6274
6275 mypid = getpid(); /* This function never fails */
6276
6277 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6278 if (snapshot == INVALID_HANDLE_VALUE)
6279 return PyErr_SetFromWindowsErr(GetLastError());
6280
6281 pe.dwSize = sizeof(pe);
6282 have_record = Process32First(snapshot, &pe);
6283 while (have_record) {
6284 if (mypid == (pid_t)pe.th32ProcessID) {
6285 /* We could cache the ulong value in a static variable. */
6286 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6287 break;
6288 }
6289
6290 have_record = Process32Next(snapshot, &pe);
6291 }
6292
6293 /* If our loop exits and our pid was not found (result will be NULL)
6294 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6295 * error anyway, so let's raise it. */
6296 if (!result)
6297 result = PyErr_SetFromWindowsErr(GetLastError());
6298
6299 CloseHandle(snapshot);
6300
6301 return result;
6302}
6303#endif /*MS_WINDOWS*/
6304
Larry Hastings2f936352014-08-05 14:04:04 +10006305
6306/*[clinic input]
6307os.getppid
6308
6309Return the parent's process id.
6310
6311If the parent process has already exited, Windows machines will still
6312return its id; others systems will return the id of the 'init' process (1).
6313[clinic start generated code]*/
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006316os_getppid_impl(PyObject *module)
6317/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006318{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006319#ifdef MS_WINDOWS
6320 return win32_getppid();
6321#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006323#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006324}
6325#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006327
Fred Drake12c6e2d1999-12-14 21:25:03 +00006328#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006329/*[clinic input]
6330os.getlogin
6331
6332Return the actual login name.
6333[clinic start generated code]*/
6334
Larry Hastings2f936352014-08-05 14:04:04 +10006335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006336os_getlogin_impl(PyObject *module)
6337/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006338{
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006340#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006341 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006342 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006343
6344 if (GetUserNameW(user_name, &num_chars)) {
6345 /* num_chars is the number of unicode chars plus null terminator */
6346 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006347 }
6348 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006349 result = PyErr_SetFromWindowsErr(GetLastError());
6350#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 char *name;
6352 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006353
Victor Stinner8c62be82010-05-06 00:08:46 +00006354 errno = 0;
6355 name = getlogin();
6356 if (name == NULL) {
6357 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006358 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006359 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006360 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 }
6362 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006363 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006365#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006366 return result;
6367}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006368#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006369
Larry Hastings2f936352014-08-05 14:04:04 +10006370
Guido van Rossumad0ee831995-03-01 10:34:45 +00006371#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006372/*[clinic input]
6373os.getuid
6374
6375Return the current process's user id.
6376[clinic start generated code]*/
6377
Larry Hastings2f936352014-08-05 14:04:04 +10006378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006379os_getuid_impl(PyObject *module)
6380/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006381{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006382 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006383}
Larry Hastings2f936352014-08-05 14:04:04 +10006384#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006385
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006386
Brian Curtineb24d742010-04-12 17:16:38 +00006387#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006388#define HAVE_KILL
6389#endif /* MS_WINDOWS */
6390
6391#ifdef HAVE_KILL
6392/*[clinic input]
6393os.kill
6394
6395 pid: pid_t
6396 signal: Py_ssize_t
6397 /
6398
6399Kill a process with a signal.
6400[clinic start generated code]*/
6401
Larry Hastings2f936352014-08-05 14:04:04 +10006402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006403os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6404/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006405#ifndef MS_WINDOWS
6406{
6407 if (kill(pid, (int)signal) == -1)
6408 return posix_error();
6409 Py_RETURN_NONE;
6410}
6411#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006412{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006413 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006414 DWORD sig = (DWORD)signal;
6415 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006417
Victor Stinner8c62be82010-05-06 00:08:46 +00006418 /* Console processes which share a common console can be sent CTRL+C or
6419 CTRL+BREAK events, provided they handle said events. */
6420 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006421 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 err = GetLastError();
6423 PyErr_SetFromWindowsErr(err);
6424 }
6425 else
6426 Py_RETURN_NONE;
6427 }
Brian Curtineb24d742010-04-12 17:16:38 +00006428
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6430 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006431 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 if (handle == NULL) {
6433 err = GetLastError();
6434 return PyErr_SetFromWindowsErr(err);
6435 }
Brian Curtineb24d742010-04-12 17:16:38 +00006436
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 if (TerminateProcess(handle, sig) == 0) {
6438 err = GetLastError();
6439 result = PyErr_SetFromWindowsErr(err);
6440 } else {
6441 Py_INCREF(Py_None);
6442 result = Py_None;
6443 }
Brian Curtineb24d742010-04-12 17:16:38 +00006444
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 CloseHandle(handle);
6446 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006447}
Larry Hastings2f936352014-08-05 14:04:04 +10006448#endif /* !MS_WINDOWS */
6449#endif /* HAVE_KILL */
6450
6451
6452#ifdef HAVE_KILLPG
6453/*[clinic input]
6454os.killpg
6455
6456 pgid: pid_t
6457 signal: int
6458 /
6459
6460Kill a process group with a signal.
6461[clinic start generated code]*/
6462
Larry Hastings2f936352014-08-05 14:04:04 +10006463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006464os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6465/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006466{
6467 /* XXX some man pages make the `pgid` parameter an int, others
6468 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6469 take the same type. Moreover, pid_t is always at least as wide as
6470 int (else compilation of this module fails), which is safe. */
6471 if (killpg(pgid, signal) == -1)
6472 return posix_error();
6473 Py_RETURN_NONE;
6474}
6475#endif /* HAVE_KILLPG */
6476
Brian Curtineb24d742010-04-12 17:16:38 +00006477
Guido van Rossumc0125471996-06-28 18:55:32 +00006478#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006479#ifdef HAVE_SYS_LOCK_H
6480#include <sys/lock.h>
6481#endif
6482
Larry Hastings2f936352014-08-05 14:04:04 +10006483/*[clinic input]
6484os.plock
6485 op: int
6486 /
6487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006488Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006489[clinic start generated code]*/
6490
Larry Hastings2f936352014-08-05 14:04:04 +10006491static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006492os_plock_impl(PyObject *module, int op)
6493/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006494{
Victor Stinner8c62be82010-05-06 00:08:46 +00006495 if (plock(op) == -1)
6496 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006497 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006498}
Larry Hastings2f936352014-08-05 14:04:04 +10006499#endif /* HAVE_PLOCK */
6500
Guido van Rossumc0125471996-06-28 18:55:32 +00006501
Guido van Rossumb6775db1994-08-01 11:34:53 +00006502#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006503/*[clinic input]
6504os.setuid
6505
6506 uid: uid_t
6507 /
6508
6509Set the current process's user id.
6510[clinic start generated code]*/
6511
Larry Hastings2f936352014-08-05 14:04:04 +10006512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006513os_setuid_impl(PyObject *module, uid_t uid)
6514/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006515{
Victor Stinner8c62be82010-05-06 00:08:46 +00006516 if (setuid(uid) < 0)
6517 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006518 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006519}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006520#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006521
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006522
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006523#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006524/*[clinic input]
6525os.seteuid
6526
6527 euid: uid_t
6528 /
6529
6530Set the current process's effective user id.
6531[clinic start generated code]*/
6532
Larry Hastings2f936352014-08-05 14:04:04 +10006533static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006534os_seteuid_impl(PyObject *module, uid_t euid)
6535/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006536{
6537 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006539 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006540}
6541#endif /* HAVE_SETEUID */
6542
Larry Hastings2f936352014-08-05 14:04:04 +10006543
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006544#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006545/*[clinic input]
6546os.setegid
6547
6548 egid: gid_t
6549 /
6550
6551Set the current process's effective group id.
6552[clinic start generated code]*/
6553
Larry Hastings2f936352014-08-05 14:04:04 +10006554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006555os_setegid_impl(PyObject *module, gid_t egid)
6556/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006557{
6558 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006560 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006561}
6562#endif /* HAVE_SETEGID */
6563
Larry Hastings2f936352014-08-05 14:04:04 +10006564
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006565#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006566/*[clinic input]
6567os.setreuid
6568
6569 ruid: uid_t
6570 euid: uid_t
6571 /
6572
6573Set the current process's real and effective user ids.
6574[clinic start generated code]*/
6575
Larry Hastings2f936352014-08-05 14:04:04 +10006576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006577os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6578/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006579{
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 if (setreuid(ruid, euid) < 0) {
6581 return posix_error();
6582 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006583 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006585}
6586#endif /* HAVE_SETREUID */
6587
Larry Hastings2f936352014-08-05 14:04:04 +10006588
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006589#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006590/*[clinic input]
6591os.setregid
6592
6593 rgid: gid_t
6594 egid: gid_t
6595 /
6596
6597Set the current process's real and effective group ids.
6598[clinic start generated code]*/
6599
Larry Hastings2f936352014-08-05 14:04:04 +10006600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006601os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6602/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006603{
6604 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006606 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006607}
6608#endif /* HAVE_SETREGID */
6609
Larry Hastings2f936352014-08-05 14:04:04 +10006610
Guido van Rossumb6775db1994-08-01 11:34:53 +00006611#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006612/*[clinic input]
6613os.setgid
6614 gid: gid_t
6615 /
6616
6617Set the current process's group id.
6618[clinic start generated code]*/
6619
Larry Hastings2f936352014-08-05 14:04:04 +10006620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006621os_setgid_impl(PyObject *module, gid_t gid)
6622/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006623{
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 if (setgid(gid) < 0)
6625 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006626 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006627}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006628#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006629
Larry Hastings2f936352014-08-05 14:04:04 +10006630
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006631#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006632/*[clinic input]
6633os.setgroups
6634
6635 groups: object
6636 /
6637
6638Set the groups of the current process to list.
6639[clinic start generated code]*/
6640
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006641static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006642os_setgroups(PyObject *module, PyObject *groups)
6643/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006644{
Victor Stinner8c62be82010-05-06 00:08:46 +00006645 int i, len;
6646 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006647
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 if (!PySequence_Check(groups)) {
6649 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6650 return NULL;
6651 }
6652 len = PySequence_Size(groups);
6653 if (len > MAX_GROUPS) {
6654 PyErr_SetString(PyExc_ValueError, "too many groups");
6655 return NULL;
6656 }
6657 for(i = 0; i < len; i++) {
6658 PyObject *elem;
6659 elem = PySequence_GetItem(groups, i);
6660 if (!elem)
6661 return NULL;
6662 if (!PyLong_Check(elem)) {
6663 PyErr_SetString(PyExc_TypeError,
6664 "groups must be integers");
6665 Py_DECREF(elem);
6666 return NULL;
6667 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006668 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 Py_DECREF(elem);
6670 return NULL;
6671 }
6672 }
6673 Py_DECREF(elem);
6674 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006675
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 if (setgroups(len, grouplist) < 0)
6677 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006678 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006679}
6680#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006681
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006682#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6683static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006684wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006685{
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 PyObject *result;
6687 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006688 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006689
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 if (pid == -1)
6691 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006692
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 if (struct_rusage == NULL) {
6694 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6695 if (m == NULL)
6696 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006697 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 Py_DECREF(m);
6699 if (struct_rusage == NULL)
6700 return NULL;
6701 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006702
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6704 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6705 if (!result)
6706 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006707
6708#ifndef doubletime
6709#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6710#endif
6711
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006713 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006715 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006716#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6718 SET_INT(result, 2, ru->ru_maxrss);
6719 SET_INT(result, 3, ru->ru_ixrss);
6720 SET_INT(result, 4, ru->ru_idrss);
6721 SET_INT(result, 5, ru->ru_isrss);
6722 SET_INT(result, 6, ru->ru_minflt);
6723 SET_INT(result, 7, ru->ru_majflt);
6724 SET_INT(result, 8, ru->ru_nswap);
6725 SET_INT(result, 9, ru->ru_inblock);
6726 SET_INT(result, 10, ru->ru_oublock);
6727 SET_INT(result, 11, ru->ru_msgsnd);
6728 SET_INT(result, 12, ru->ru_msgrcv);
6729 SET_INT(result, 13, ru->ru_nsignals);
6730 SET_INT(result, 14, ru->ru_nvcsw);
6731 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006732#undef SET_INT
6733
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 if (PyErr_Occurred()) {
6735 Py_DECREF(result);
6736 return NULL;
6737 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006738
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006740}
6741#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6742
Larry Hastings2f936352014-08-05 14:04:04 +10006743
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006744#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006745/*[clinic input]
6746os.wait3
6747
6748 options: int
6749Wait for completion of a child process.
6750
6751Returns a tuple of information about the child process:
6752 (pid, status, rusage)
6753[clinic start generated code]*/
6754
Larry Hastings2f936352014-08-05 14:04:04 +10006755static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006756os_wait3_impl(PyObject *module, int options)
6757/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006758{
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006761 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 WAIT_TYPE status;
6763 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006764
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006765 do {
6766 Py_BEGIN_ALLOW_THREADS
6767 pid = wait3(&status, options, &ru);
6768 Py_END_ALLOW_THREADS
6769 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6770 if (pid < 0)
6771 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006772
Victor Stinner4195b5c2012-02-08 23:03:19 +01006773 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006774}
6775#endif /* HAVE_WAIT3 */
6776
Larry Hastings2f936352014-08-05 14:04:04 +10006777
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006778#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006779/*[clinic input]
6780
6781os.wait4
6782
6783 pid: pid_t
6784 options: int
6785
6786Wait for completion of a specific child process.
6787
6788Returns a tuple of information about the child process:
6789 (pid, status, rusage)
6790[clinic start generated code]*/
6791
Larry Hastings2f936352014-08-05 14:04:04 +10006792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006793os_wait4_impl(PyObject *module, pid_t pid, int options)
6794/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006795{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006796 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006798 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 WAIT_TYPE status;
6800 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006801
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006802 do {
6803 Py_BEGIN_ALLOW_THREADS
6804 res = wait4(pid, &status, options, &ru);
6805 Py_END_ALLOW_THREADS
6806 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6807 if (res < 0)
6808 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006809
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006810 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006811}
6812#endif /* HAVE_WAIT4 */
6813
Larry Hastings2f936352014-08-05 14:04:04 +10006814
Ross Lagerwall7807c352011-03-17 20:20:30 +02006815#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006816/*[clinic input]
6817os.waitid
6818
6819 idtype: idtype_t
6820 Must be one of be P_PID, P_PGID or P_ALL.
6821 id: id_t
6822 The id to wait on.
6823 options: int
6824 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6825 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6826 /
6827
6828Returns the result of waiting for a process or processes.
6829
6830Returns either waitid_result or None if WNOHANG is specified and there are
6831no children in a waitable state.
6832[clinic start generated code]*/
6833
Larry Hastings2f936352014-08-05 14:04:04 +10006834static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006835os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6836/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006837{
6838 PyObject *result;
6839 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006840 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006841 siginfo_t si;
6842 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006843
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006844 do {
6845 Py_BEGIN_ALLOW_THREADS
6846 res = waitid(idtype, id, &si, options);
6847 Py_END_ALLOW_THREADS
6848 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6849 if (res < 0)
6850 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006851
6852 if (si.si_pid == 0)
6853 Py_RETURN_NONE;
6854
6855 result = PyStructSequence_New(&WaitidResultType);
6856 if (!result)
6857 return NULL;
6858
6859 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006860 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006861 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6862 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6863 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6864 if (PyErr_Occurred()) {
6865 Py_DECREF(result);
6866 return NULL;
6867 }
6868
6869 return result;
6870}
Larry Hastings2f936352014-08-05 14:04:04 +10006871#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006872
Larry Hastings2f936352014-08-05 14:04:04 +10006873
6874#if defined(HAVE_WAITPID)
6875/*[clinic input]
6876os.waitpid
6877 pid: pid_t
6878 options: int
6879 /
6880
6881Wait for completion of a given child process.
6882
6883Returns a tuple of information regarding the child process:
6884 (pid, status)
6885
6886The options argument is ignored on Windows.
6887[clinic start generated code]*/
6888
Larry Hastings2f936352014-08-05 14:04:04 +10006889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006890os_waitpid_impl(PyObject *module, pid_t pid, int options)
6891/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006892{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006893 pid_t res;
6894 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 WAIT_TYPE status;
6896 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006897
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006898 do {
6899 Py_BEGIN_ALLOW_THREADS
6900 res = waitpid(pid, &status, options);
6901 Py_END_ALLOW_THREADS
6902 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6903 if (res < 0)
6904 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006905
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006906 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006907}
Tim Petersab034fa2002-02-01 11:27:43 +00006908#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006909/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006910/*[clinic input]
6911os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006912 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006913 options: int
6914 /
6915
6916Wait for completion of a given process.
6917
6918Returns a tuple of information regarding the process:
6919 (pid, status << 8)
6920
6921The options argument is ignored on Windows.
6922[clinic start generated code]*/
6923
Larry Hastings2f936352014-08-05 14:04:04 +10006924static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006925os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006926/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006927{
6928 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006929 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006930 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006931
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006932 do {
6933 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006934 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006936 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006937 Py_END_ALLOW_THREADS
6938 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006939 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006940 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006943 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006944}
Larry Hastings2f936352014-08-05 14:04:04 +10006945#endif
6946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006947
Guido van Rossumad0ee831995-03-01 10:34:45 +00006948#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006949/*[clinic input]
6950os.wait
6951
6952Wait for completion of a child process.
6953
6954Returns a tuple of information about the child process:
6955 (pid, status)
6956[clinic start generated code]*/
6957
Larry Hastings2f936352014-08-05 14:04:04 +10006958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006959os_wait_impl(PyObject *module)
6960/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006961{
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006963 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 WAIT_TYPE status;
6965 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006966
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006967 do {
6968 Py_BEGIN_ALLOW_THREADS
6969 pid = wait(&status);
6970 Py_END_ALLOW_THREADS
6971 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6972 if (pid < 0)
6973 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006974
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006976}
Larry Hastings2f936352014-08-05 14:04:04 +10006977#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006979
Larry Hastings9cf065c2012-06-22 16:30:09 -07006980#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6981PyDoc_STRVAR(readlink__doc__,
6982"readlink(path, *, dir_fd=None) -> path\n\n\
6983Return a string representing the path to which the symbolic link points.\n\
6984\n\
6985If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6986 and path should be relative; path will then be relative to that directory.\n\
6987dir_fd may not be implemented on your platform.\n\
6988 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006989#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006990
Guido van Rossumb6775db1994-08-01 11:34:53 +00006991#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006992
Larry Hastings2f936352014-08-05 14:04:04 +10006993/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006994static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006995posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006996{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006997 path_t path;
6998 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02006999 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007000 ssize_t length;
7001 PyObject *return_value = NULL;
7002 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007003
Larry Hastings9cf065c2012-06-22 16:30:09 -07007004 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007005 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007006 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7007 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007008 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007010
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007012#ifdef HAVE_READLINKAT
7013 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007014 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007015 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007016#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007017 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007018 Py_END_ALLOW_THREADS
7019
7020 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007021 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007022 goto exit;
7023 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007024 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007025
7026 if (PyUnicode_Check(path.object))
7027 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7028 else
7029 return_value = PyBytes_FromStringAndSize(buffer, length);
7030exit:
7031 path_cleanup(&path);
7032 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007033}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007034
Guido van Rossumb6775db1994-08-01 11:34:53 +00007035#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007036
Larry Hastings2f936352014-08-05 14:04:04 +10007037#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7038
7039static PyObject *
7040win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7041{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007042 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007043 DWORD n_bytes_returned;
7044 DWORD io_result;
7045 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007046 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007047 HANDLE reparse_point_handle;
7048
Martin Panter70214ad2016-08-04 02:38:59 +00007049 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7050 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007051 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007052
7053 static char *keywords[] = {"path", "dir_fd", NULL};
7054
7055 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7056 &po,
7057 dir_fd_unavailable, &dir_fd
7058 ))
7059 return NULL;
7060
7061 path = PyUnicode_AsUnicode(po);
7062 if (path == NULL)
7063 return NULL;
7064
7065 /* First get a handle to the reparse point */
7066 Py_BEGIN_ALLOW_THREADS
7067 reparse_point_handle = CreateFileW(
7068 path,
7069 0,
7070 0,
7071 0,
7072 OPEN_EXISTING,
7073 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7074 0);
7075 Py_END_ALLOW_THREADS
7076
7077 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7078 return win32_error_object("readlink", po);
7079
7080 Py_BEGIN_ALLOW_THREADS
7081 /* New call DeviceIoControl to read the reparse point */
7082 io_result = DeviceIoControl(
7083 reparse_point_handle,
7084 FSCTL_GET_REPARSE_POINT,
7085 0, 0, /* in buffer */
7086 target_buffer, sizeof(target_buffer),
7087 &n_bytes_returned,
7088 0 /* we're not using OVERLAPPED_IO */
7089 );
7090 CloseHandle(reparse_point_handle);
7091 Py_END_ALLOW_THREADS
7092
7093 if (io_result==0)
7094 return win32_error_object("readlink", po);
7095
7096 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7097 {
7098 PyErr_SetString(PyExc_ValueError,
7099 "not a symbolic link");
7100 return NULL;
7101 }
7102 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7103 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7104
7105 result = PyUnicode_FromWideChar(print_name,
7106 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7107 return result;
7108}
7109
7110#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7111
7112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007113
Larry Hastings9cf065c2012-06-22 16:30:09 -07007114#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115
7116#if defined(MS_WINDOWS)
7117
7118/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007119static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007120
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007122check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007123{
7124 HINSTANCE hKernel32;
7125 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007126 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007127 return 1;
7128 hKernel32 = GetModuleHandleW(L"KERNEL32");
7129 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7130 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007131 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007132}
7133
Victor Stinner31b3b922013-06-05 01:49:17 +02007134/* Remove the last portion of the path */
7135static void
7136_dirnameW(WCHAR *path)
7137{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007138 WCHAR *ptr;
7139
7140 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007141 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007142 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007143 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007144 }
7145 *ptr = 0;
7146}
7147
Victor Stinner31b3b922013-06-05 01:49:17 +02007148/* Is this path absolute? */
7149static int
7150_is_absW(const WCHAR *path)
7151{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007152 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7153
7154}
7155
Victor Stinner31b3b922013-06-05 01:49:17 +02007156/* join root and rest with a backslash */
7157static void
7158_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7159{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007160 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007161
Victor Stinner31b3b922013-06-05 01:49:17 +02007162 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007163 wcscpy(dest_path, rest);
7164 return;
7165 }
7166
7167 root_len = wcslen(root);
7168
7169 wcscpy(dest_path, root);
7170 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007171 dest_path[root_len] = L'\\';
7172 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007173 }
7174 wcscpy(dest_path+root_len, rest);
7175}
7176
Victor Stinner31b3b922013-06-05 01:49:17 +02007177/* Return True if the path at src relative to dest is a directory */
7178static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007179_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007180{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007181 WIN32_FILE_ATTRIBUTE_DATA src_info;
7182 WCHAR dest_parent[MAX_PATH];
7183 WCHAR src_resolved[MAX_PATH] = L"";
7184
7185 /* dest_parent = os.path.dirname(dest) */
7186 wcscpy(dest_parent, dest);
7187 _dirnameW(dest_parent);
7188 /* src_resolved = os.path.join(dest_parent, src) */
7189 _joinW(src_resolved, dest_parent, src);
7190 return (
7191 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7192 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7193 );
7194}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007195#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007196
Larry Hastings2f936352014-08-05 14:04:04 +10007197
7198/*[clinic input]
7199os.symlink
7200 src: path_t
7201 dst: path_t
7202 target_is_directory: bool = False
7203 *
7204 dir_fd: dir_fd(requires='symlinkat')=None
7205
7206# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7207
7208Create a symbolic link pointing to src named dst.
7209
7210target_is_directory is required on Windows if the target is to be
7211 interpreted as a directory. (On Windows, symlink requires
7212 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7213 target_is_directory is ignored on non-Windows platforms.
7214
7215If dir_fd is not None, it should be a file descriptor open to a directory,
7216 and path should be relative; path will then be relative to that directory.
7217dir_fd may not be implemented on your platform.
7218 If it is unavailable, using it will raise a NotImplementedError.
7219
7220[clinic start generated code]*/
7221
Larry Hastings2f936352014-08-05 14:04:04 +10007222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007223os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007224 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007225/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007226{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007227#ifdef MS_WINDOWS
7228 DWORD result;
7229#else
7230 int result;
7231#endif
7232
Larry Hastings9cf065c2012-06-22 16:30:09 -07007233#ifdef MS_WINDOWS
7234 if (!check_CreateSymbolicLink()) {
7235 PyErr_SetString(PyExc_NotImplementedError,
7236 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007237 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007238 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007239 if (!win32_can_symlink) {
7240 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007241 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007242 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007243#endif
7244
Larry Hastings2f936352014-08-05 14:04:04 +10007245 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007246 PyErr_SetString(PyExc_ValueError,
7247 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007248 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007249 }
7250
7251#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007252
Larry Hastings9cf065c2012-06-22 16:30:09 -07007253 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007254 /* if src is a directory, ensure target_is_directory==1 */
7255 target_is_directory |= _check_dirW(src->wide, dst->wide);
7256 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7257 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007258 Py_END_ALLOW_THREADS
7259
Larry Hastings2f936352014-08-05 14:04:04 +10007260 if (!result)
7261 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262
7263#else
7264
7265 Py_BEGIN_ALLOW_THREADS
7266#if HAVE_SYMLINKAT
7267 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007268 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007269 else
7270#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007271 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007272 Py_END_ALLOW_THREADS
7273
Larry Hastings2f936352014-08-05 14:04:04 +10007274 if (result)
7275 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007276#endif
7277
Larry Hastings2f936352014-08-05 14:04:04 +10007278 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007279}
7280#endif /* HAVE_SYMLINK */
7281
Larry Hastings9cf065c2012-06-22 16:30:09 -07007282
Brian Curtind40e6f72010-07-08 21:39:08 +00007283
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007284
Larry Hastings605a62d2012-06-24 04:33:36 -07007285static PyStructSequence_Field times_result_fields[] = {
7286 {"user", "user time"},
7287 {"system", "system time"},
7288 {"children_user", "user time of children"},
7289 {"children_system", "system time of children"},
7290 {"elapsed", "elapsed time since an arbitrary point in the past"},
7291 {NULL}
7292};
7293
7294PyDoc_STRVAR(times_result__doc__,
7295"times_result: Result from os.times().\n\n\
7296This object may be accessed either as a tuple of\n\
7297 (user, system, children_user, children_system, elapsed),\n\
7298or via the attributes user, system, children_user, children_system,\n\
7299and elapsed.\n\
7300\n\
7301See os.times for more information.");
7302
7303static PyStructSequence_Desc times_result_desc = {
7304 "times_result", /* name */
7305 times_result__doc__, /* doc */
7306 times_result_fields,
7307 5
7308};
7309
7310static PyTypeObject TimesResultType;
7311
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007312#ifdef MS_WINDOWS
7313#define HAVE_TIMES /* mandatory, for the method table */
7314#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007315
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007316#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007317
7318static PyObject *
7319build_times_result(double user, double system,
7320 double children_user, double children_system,
7321 double elapsed)
7322{
7323 PyObject *value = PyStructSequence_New(&TimesResultType);
7324 if (value == NULL)
7325 return NULL;
7326
7327#define SET(i, field) \
7328 { \
7329 PyObject *o = PyFloat_FromDouble(field); \
7330 if (!o) { \
7331 Py_DECREF(value); \
7332 return NULL; \
7333 } \
7334 PyStructSequence_SET_ITEM(value, i, o); \
7335 } \
7336
7337 SET(0, user);
7338 SET(1, system);
7339 SET(2, children_user);
7340 SET(3, children_system);
7341 SET(4, elapsed);
7342
7343#undef SET
7344
7345 return value;
7346}
7347
Larry Hastings605a62d2012-06-24 04:33:36 -07007348
Larry Hastings2f936352014-08-05 14:04:04 +10007349#ifndef MS_WINDOWS
7350#define NEED_TICKS_PER_SECOND
7351static long ticks_per_second = -1;
7352#endif /* MS_WINDOWS */
7353
7354/*[clinic input]
7355os.times
7356
7357Return a collection containing process timing information.
7358
7359The object returned behaves like a named tuple with these fields:
7360 (utime, stime, cutime, cstime, elapsed_time)
7361All fields are floating point numbers.
7362[clinic start generated code]*/
7363
Larry Hastings2f936352014-08-05 14:04:04 +10007364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007365os_times_impl(PyObject *module)
7366/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007367#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007368{
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 FILETIME create, exit, kernel, user;
7370 HANDLE hProc;
7371 hProc = GetCurrentProcess();
7372 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7373 /* The fields of a FILETIME structure are the hi and lo part
7374 of a 64-bit value expressed in 100 nanosecond units.
7375 1e7 is one second in such units; 1e-7 the inverse.
7376 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7377 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007378 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 (double)(user.dwHighDateTime*429.4967296 +
7380 user.dwLowDateTime*1e-7),
7381 (double)(kernel.dwHighDateTime*429.4967296 +
7382 kernel.dwLowDateTime*1e-7),
7383 (double)0,
7384 (double)0,
7385 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007386}
Larry Hastings2f936352014-08-05 14:04:04 +10007387#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007388{
Larry Hastings2f936352014-08-05 14:04:04 +10007389
7390
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007391 struct tms t;
7392 clock_t c;
7393 errno = 0;
7394 c = times(&t);
7395 if (c == (clock_t) -1)
7396 return posix_error();
7397 return build_times_result(
7398 (double)t.tms_utime / ticks_per_second,
7399 (double)t.tms_stime / ticks_per_second,
7400 (double)t.tms_cutime / ticks_per_second,
7401 (double)t.tms_cstime / ticks_per_second,
7402 (double)c / ticks_per_second);
7403}
Larry Hastings2f936352014-08-05 14:04:04 +10007404#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007405#endif /* HAVE_TIMES */
7406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007407
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007408#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007409/*[clinic input]
7410os.getsid
7411
7412 pid: pid_t
7413 /
7414
7415Call the system call getsid(pid) and return the result.
7416[clinic start generated code]*/
7417
Larry Hastings2f936352014-08-05 14:04:04 +10007418static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007419os_getsid_impl(PyObject *module, pid_t pid)
7420/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007421{
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007423 sid = getsid(pid);
7424 if (sid < 0)
7425 return posix_error();
7426 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007427}
7428#endif /* HAVE_GETSID */
7429
7430
Guido van Rossumb6775db1994-08-01 11:34:53 +00007431#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007432/*[clinic input]
7433os.setsid
7434
7435Call the system call setsid().
7436[clinic start generated code]*/
7437
Larry Hastings2f936352014-08-05 14:04:04 +10007438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007439os_setsid_impl(PyObject *module)
7440/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007441{
Victor Stinner8c62be82010-05-06 00:08:46 +00007442 if (setsid() < 0)
7443 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007444 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007445}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007446#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007447
Larry Hastings2f936352014-08-05 14:04:04 +10007448
Guido van Rossumb6775db1994-08-01 11:34:53 +00007449#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007450/*[clinic input]
7451os.setpgid
7452
7453 pid: pid_t
7454 pgrp: pid_t
7455 /
7456
7457Call the system call setpgid(pid, pgrp).
7458[clinic start generated code]*/
7459
Larry Hastings2f936352014-08-05 14:04:04 +10007460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007461os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7462/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007463{
Victor Stinner8c62be82010-05-06 00:08:46 +00007464 if (setpgid(pid, pgrp) < 0)
7465 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007466 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007467}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007468#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007469
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007470
Guido van Rossumb6775db1994-08-01 11:34:53 +00007471#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007472/*[clinic input]
7473os.tcgetpgrp
7474
7475 fd: int
7476 /
7477
7478Return the process group associated with the terminal specified by fd.
7479[clinic start generated code]*/
7480
Larry Hastings2f936352014-08-05 14:04:04 +10007481static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007482os_tcgetpgrp_impl(PyObject *module, int fd)
7483/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007484{
7485 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007486 if (pgid < 0)
7487 return posix_error();
7488 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007489}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007490#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007491
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007492
Guido van Rossumb6775db1994-08-01 11:34:53 +00007493#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007494/*[clinic input]
7495os.tcsetpgrp
7496
7497 fd: int
7498 pgid: pid_t
7499 /
7500
7501Set the process group associated with the terminal specified by fd.
7502[clinic start generated code]*/
7503
Larry Hastings2f936352014-08-05 14:04:04 +10007504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007505os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7506/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007507{
Victor Stinner8c62be82010-05-06 00:08:46 +00007508 if (tcsetpgrp(fd, pgid) < 0)
7509 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007510 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007511}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007512#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007513
Guido van Rossum687dd131993-05-17 08:34:16 +00007514/* Functions acting on file descriptors */
7515
Victor Stinnerdaf45552013-08-28 00:53:59 +02007516#ifdef O_CLOEXEC
7517extern int _Py_open_cloexec_works;
7518#endif
7519
Larry Hastings2f936352014-08-05 14:04:04 +10007520
7521/*[clinic input]
7522os.open -> int
7523 path: path_t
7524 flags: int
7525 mode: int = 0o777
7526 *
7527 dir_fd: dir_fd(requires='openat') = None
7528
7529# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7530
7531Open a file for low level IO. Returns a file descriptor (integer).
7532
7533If dir_fd is not None, it should be a file descriptor open to a directory,
7534 and path should be relative; path will then be relative to that directory.
7535dir_fd may not be implemented on your platform.
7536 If it is unavailable, using it will raise a NotImplementedError.
7537[clinic start generated code]*/
7538
Larry Hastings2f936352014-08-05 14:04:04 +10007539static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007540os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7541/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007542{
7543 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007544 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007545
Victor Stinnerdaf45552013-08-28 00:53:59 +02007546#ifdef O_CLOEXEC
7547 int *atomic_flag_works = &_Py_open_cloexec_works;
7548#elif !defined(MS_WINDOWS)
7549 int *atomic_flag_works = NULL;
7550#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007551
Victor Stinnerdaf45552013-08-28 00:53:59 +02007552#ifdef MS_WINDOWS
7553 flags |= O_NOINHERIT;
7554#elif defined(O_CLOEXEC)
7555 flags |= O_CLOEXEC;
7556#endif
7557
Steve Dower8fc89802015-04-12 00:26:27 -04007558 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007559 do {
7560 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007561#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007562 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007563#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007564#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007565 if (dir_fd != DEFAULT_DIR_FD)
7566 fd = openat(dir_fd, path->narrow, flags, mode);
7567 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007568#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007569 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007570#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007571 Py_END_ALLOW_THREADS
7572 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007573 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007574
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007575 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007576 if (!async_err)
7577 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007578 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007579 }
7580
Victor Stinnerdaf45552013-08-28 00:53:59 +02007581#ifndef MS_WINDOWS
7582 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7583 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007584 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007585 }
7586#endif
7587
Larry Hastings2f936352014-08-05 14:04:04 +10007588 return fd;
7589}
7590
7591
7592/*[clinic input]
7593os.close
7594
7595 fd: int
7596
7597Close a file descriptor.
7598[clinic start generated code]*/
7599
Barry Warsaw53699e91996-12-10 23:23:01 +00007600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007601os_close_impl(PyObject *module, int fd)
7602/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007603{
Larry Hastings2f936352014-08-05 14:04:04 +10007604 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007605 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7606 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7607 * for more details.
7608 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007610 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007612 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 Py_END_ALLOW_THREADS
7614 if (res < 0)
7615 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007616 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007617}
7618
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007619
Larry Hastings2f936352014-08-05 14:04:04 +10007620/*[clinic input]
7621os.closerange
7622
7623 fd_low: int
7624 fd_high: int
7625 /
7626
7627Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7628[clinic start generated code]*/
7629
Larry Hastings2f936352014-08-05 14:04:04 +10007630static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007631os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7632/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007633{
7634 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007635 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007636 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007637 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007638 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007639 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007640 Py_END_ALLOW_THREADS
7641 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007642}
7643
7644
Larry Hastings2f936352014-08-05 14:04:04 +10007645/*[clinic input]
7646os.dup -> int
7647
7648 fd: int
7649 /
7650
7651Return a duplicate of a file descriptor.
7652[clinic start generated code]*/
7653
Larry Hastings2f936352014-08-05 14:04:04 +10007654static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007655os_dup_impl(PyObject *module, int fd)
7656/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007657{
7658 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007659}
7660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007661
Larry Hastings2f936352014-08-05 14:04:04 +10007662/*[clinic input]
7663os.dup2
7664 fd: int
7665 fd2: int
7666 inheritable: bool=True
7667
7668Duplicate file descriptor.
7669[clinic start generated code]*/
7670
Larry Hastings2f936352014-08-05 14:04:04 +10007671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007672os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7673/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007674{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007675 int res;
7676#if defined(HAVE_DUP3) && \
7677 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7678 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7679 int dup3_works = -1;
7680#endif
7681
Steve Dower940f33a2016-09-08 11:21:54 -07007682 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007683 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007684
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007685 /* dup2() can fail with EINTR if the target FD is already open, because it
7686 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7687 * upon close(), and therefore below.
7688 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007689#ifdef MS_WINDOWS
7690 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007691 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007693 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007694 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 if (res < 0)
7696 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007697
7698 /* Character files like console cannot be make non-inheritable */
7699 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7700 close(fd2);
7701 return NULL;
7702 }
7703
7704#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7705 Py_BEGIN_ALLOW_THREADS
7706 if (!inheritable)
7707 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7708 else
7709 res = dup2(fd, fd2);
7710 Py_END_ALLOW_THREADS
7711 if (res < 0)
7712 return posix_error();
7713
7714#else
7715
7716#ifdef HAVE_DUP3
7717 if (!inheritable && dup3_works != 0) {
7718 Py_BEGIN_ALLOW_THREADS
7719 res = dup3(fd, fd2, O_CLOEXEC);
7720 Py_END_ALLOW_THREADS
7721 if (res < 0) {
7722 if (dup3_works == -1)
7723 dup3_works = (errno != ENOSYS);
7724 if (dup3_works)
7725 return posix_error();
7726 }
7727 }
7728
7729 if (inheritable || dup3_works == 0)
7730 {
7731#endif
7732 Py_BEGIN_ALLOW_THREADS
7733 res = dup2(fd, fd2);
7734 Py_END_ALLOW_THREADS
7735 if (res < 0)
7736 return posix_error();
7737
7738 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7739 close(fd2);
7740 return NULL;
7741 }
7742#ifdef HAVE_DUP3
7743 }
7744#endif
7745
7746#endif
7747
Larry Hastings2f936352014-08-05 14:04:04 +10007748 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007749}
7750
Larry Hastings2f936352014-08-05 14:04:04 +10007751
Ross Lagerwall7807c352011-03-17 20:20:30 +02007752#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007753/*[clinic input]
7754os.lockf
7755
7756 fd: int
7757 An open file descriptor.
7758 command: int
7759 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7760 length: Py_off_t
7761 The number of bytes to lock, starting at the current position.
7762 /
7763
7764Apply, test or remove a POSIX lock on an open file descriptor.
7765
7766[clinic start generated code]*/
7767
Larry Hastings2f936352014-08-05 14:04:04 +10007768static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007769os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7770/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007771{
7772 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007773
7774 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007775 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007776 Py_END_ALLOW_THREADS
7777
7778 if (res < 0)
7779 return posix_error();
7780
7781 Py_RETURN_NONE;
7782}
Larry Hastings2f936352014-08-05 14:04:04 +10007783#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007785
Larry Hastings2f936352014-08-05 14:04:04 +10007786/*[clinic input]
7787os.lseek -> Py_off_t
7788
7789 fd: int
7790 position: Py_off_t
7791 how: int
7792 /
7793
7794Set the position of a file descriptor. Return the new position.
7795
7796Return the new cursor position in number of bytes
7797relative to the beginning of the file.
7798[clinic start generated code]*/
7799
Larry Hastings2f936352014-08-05 14:04:04 +10007800static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007801os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7802/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007803{
7804 Py_off_t result;
7805
Guido van Rossum687dd131993-05-17 08:34:16 +00007806#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7808 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007809 case 0: how = SEEK_SET; break;
7810 case 1: how = SEEK_CUR; break;
7811 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007812 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007813#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007814
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007816 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007817
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007819 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007820#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007821 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007822#else
Larry Hastings2f936352014-08-05 14:04:04 +10007823 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007824#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007825 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007827 if (result < 0)
7828 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007829
Larry Hastings2f936352014-08-05 14:04:04 +10007830 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007831}
7832
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007833
Larry Hastings2f936352014-08-05 14:04:04 +10007834/*[clinic input]
7835os.read
7836 fd: int
7837 length: Py_ssize_t
7838 /
7839
7840Read from a file descriptor. Returns a bytes object.
7841[clinic start generated code]*/
7842
Larry Hastings2f936352014-08-05 14:04:04 +10007843static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007844os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7845/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007846{
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 Py_ssize_t n;
7848 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007849
7850 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 errno = EINVAL;
7852 return posix_error();
7853 }
Larry Hastings2f936352014-08-05 14:04:04 +10007854
7855#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007856 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007857 if (length > INT_MAX)
7858 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007859#endif
7860
7861 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 if (buffer == NULL)
7863 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007864
Victor Stinner66aab0c2015-03-19 22:53:20 +01007865 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7866 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007868 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 }
Larry Hastings2f936352014-08-05 14:04:04 +10007870
7871 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007873
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007875}
7876
Ross Lagerwall7807c352011-03-17 20:20:30 +02007877#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7878 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007879static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007880iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7881{
7882 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007883 Py_ssize_t blen, total = 0;
7884
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007885 *iov = PyMem_New(struct iovec, cnt);
7886 if (*iov == NULL) {
7887 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007888 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007889 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007890
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007891 *buf = PyMem_New(Py_buffer, cnt);
7892 if (*buf == NULL) {
7893 PyMem_Del(*iov);
7894 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007895 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007896 }
7897
7898 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007899 PyObject *item = PySequence_GetItem(seq, i);
7900 if (item == NULL)
7901 goto fail;
7902 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7903 Py_DECREF(item);
7904 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007905 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007906 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007907 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007908 blen = (*buf)[i].len;
7909 (*iov)[i].iov_len = blen;
7910 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007911 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007912 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007913
7914fail:
7915 PyMem_Del(*iov);
7916 for (j = 0; j < i; j++) {
7917 PyBuffer_Release(&(*buf)[j]);
7918 }
7919 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007920 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007921}
7922
7923static void
7924iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7925{
7926 int i;
7927 PyMem_Del(iov);
7928 for (i = 0; i < cnt; i++) {
7929 PyBuffer_Release(&buf[i]);
7930 }
7931 PyMem_Del(buf);
7932}
7933#endif
7934
Larry Hastings2f936352014-08-05 14:04:04 +10007935
Ross Lagerwall7807c352011-03-17 20:20:30 +02007936#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007937/*[clinic input]
7938os.readv -> Py_ssize_t
7939
7940 fd: int
7941 buffers: object
7942 /
7943
7944Read from a file descriptor fd into an iterable of buffers.
7945
7946The buffers should be mutable buffers accepting bytes.
7947readv will transfer data into each buffer until it is full
7948and then move on to the next buffer in the sequence to hold
7949the rest of the data.
7950
7951readv returns the total number of bytes read,
7952which may be less than the total capacity of all the buffers.
7953[clinic start generated code]*/
7954
Larry Hastings2f936352014-08-05 14:04:04 +10007955static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007956os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7957/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007958{
7959 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007960 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007961 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007962 struct iovec *iov;
7963 Py_buffer *buf;
7964
Larry Hastings2f936352014-08-05 14:04:04 +10007965 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007966 PyErr_SetString(PyExc_TypeError,
7967 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007968 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007969 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007970
Larry Hastings2f936352014-08-05 14:04:04 +10007971 cnt = PySequence_Size(buffers);
7972
7973 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7974 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007975
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007976 do {
7977 Py_BEGIN_ALLOW_THREADS
7978 n = readv(fd, iov, cnt);
7979 Py_END_ALLOW_THREADS
7980 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007981
7982 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007983 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007984 if (!async_err)
7985 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007986 return -1;
7987 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007988
Larry Hastings2f936352014-08-05 14:04:04 +10007989 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007990}
Larry Hastings2f936352014-08-05 14:04:04 +10007991#endif /* HAVE_READV */
7992
Ross Lagerwall7807c352011-03-17 20:20:30 +02007993
7994#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007995/*[clinic input]
7996# TODO length should be size_t! but Python doesn't support parsing size_t yet.
7997os.pread
7998
7999 fd: int
8000 length: int
8001 offset: Py_off_t
8002 /
8003
8004Read a number of bytes from a file descriptor starting at a particular offset.
8005
8006Read length bytes from file descriptor fd, starting at offset bytes from
8007the beginning of the file. The file offset remains unchanged.
8008[clinic start generated code]*/
8009
Larry Hastings2f936352014-08-05 14:04:04 +10008010static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008011os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8012/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008013{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008014 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008015 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008016 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008017
Larry Hastings2f936352014-08-05 14:04:04 +10008018 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008019 errno = EINVAL;
8020 return posix_error();
8021 }
Larry Hastings2f936352014-08-05 14:04:04 +10008022 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023 if (buffer == NULL)
8024 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008025
8026 do {
8027 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008028 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008029 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008030 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008031 Py_END_ALLOW_THREADS
8032 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8033
Ross Lagerwall7807c352011-03-17 20:20:30 +02008034 if (n < 0) {
8035 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008036 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008037 }
Larry Hastings2f936352014-08-05 14:04:04 +10008038 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008039 _PyBytes_Resize(&buffer, n);
8040 return buffer;
8041}
Larry Hastings2f936352014-08-05 14:04:04 +10008042#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008043
Larry Hastings2f936352014-08-05 14:04:04 +10008044
8045/*[clinic input]
8046os.write -> Py_ssize_t
8047
8048 fd: int
8049 data: Py_buffer
8050 /
8051
8052Write a bytes object to a file descriptor.
8053[clinic start generated code]*/
8054
Larry Hastings2f936352014-08-05 14:04:04 +10008055static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008056os_write_impl(PyObject *module, int fd, Py_buffer *data)
8057/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008058{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008059 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008060}
8061
8062#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008064"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008065sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008067Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068
Larry Hastings2f936352014-08-05 14:04:04 +10008069/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070static PyObject *
8071posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8072{
8073 int in, out;
8074 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008075 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008076 off_t offset;
8077
8078#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8079#ifndef __APPLE__
8080 Py_ssize_t len;
8081#endif
8082 PyObject *headers = NULL, *trailers = NULL;
8083 Py_buffer *hbuf, *tbuf;
8084 off_t sbytes;
8085 struct sf_hdtr sf;
8086 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008087 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008088 static char *keywords[] = {"out", "in",
8089 "offset", "count",
8090 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008092 sf.headers = NULL;
8093 sf.trailers = NULL;
8094
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095#ifdef __APPLE__
8096 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008097 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008098#else
8099 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008100 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008101#endif
8102 &headers, &trailers, &flags))
8103 return NULL;
8104 if (headers != NULL) {
8105 if (!PySequence_Check(headers)) {
8106 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008107 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008108 return NULL;
8109 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008110 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008111 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008112 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008113 (i = iov_setup(&(sf.headers), &hbuf,
8114 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008115 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008116#ifdef __APPLE__
8117 sbytes += i;
8118#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008119 }
8120 }
8121 if (trailers != NULL) {
8122 if (!PySequence_Check(trailers)) {
8123 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008124 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008125 return NULL;
8126 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008127 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008128 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008129 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008130 (i = iov_setup(&(sf.trailers), &tbuf,
8131 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008132 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008133#ifdef __APPLE__
8134 sbytes += i;
8135#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008136 }
8137 }
8138
Steve Dower8fc89802015-04-12 00:26:27 -04008139 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008140 do {
8141 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008142#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008143 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008144#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008145 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008146#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008147 Py_END_ALLOW_THREADS
8148 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008149 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008150
8151 if (sf.headers != NULL)
8152 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8153 if (sf.trailers != NULL)
8154 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8155
8156 if (ret < 0) {
8157 if ((errno == EAGAIN) || (errno == EBUSY)) {
8158 if (sbytes != 0) {
8159 // some data has been sent
8160 goto done;
8161 }
8162 else {
8163 // no data has been sent; upper application is supposed
8164 // to retry on EAGAIN or EBUSY
8165 return posix_error();
8166 }
8167 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008168 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008169 }
8170 goto done;
8171
8172done:
8173 #if !defined(HAVE_LARGEFILE_SUPPORT)
8174 return Py_BuildValue("l", sbytes);
8175 #else
8176 return Py_BuildValue("L", sbytes);
8177 #endif
8178
8179#else
8180 Py_ssize_t count;
8181 PyObject *offobj;
8182 static char *keywords[] = {"out", "in",
8183 "offset", "count", NULL};
8184 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8185 keywords, &out, &in, &offobj, &count))
8186 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008187#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008188 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008189 do {
8190 Py_BEGIN_ALLOW_THREADS
8191 ret = sendfile(out, in, NULL, count);
8192 Py_END_ALLOW_THREADS
8193 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008194 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008195 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008196 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008197 }
8198#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008199 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008200 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008201
8202 do {
8203 Py_BEGIN_ALLOW_THREADS
8204 ret = sendfile(out, in, &offset, count);
8205 Py_END_ALLOW_THREADS
8206 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008207 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008208 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008209 return Py_BuildValue("n", ret);
8210#endif
8211}
Larry Hastings2f936352014-08-05 14:04:04 +10008212#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008213
Larry Hastings2f936352014-08-05 14:04:04 +10008214
8215/*[clinic input]
8216os.fstat
8217
8218 fd : int
8219
8220Perform a stat system call on the given file descriptor.
8221
8222Like stat(), but for an open file descriptor.
8223Equivalent to os.stat(fd).
8224[clinic start generated code]*/
8225
Larry Hastings2f936352014-08-05 14:04:04 +10008226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008227os_fstat_impl(PyObject *module, int fd)
8228/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008229{
Victor Stinner8c62be82010-05-06 00:08:46 +00008230 STRUCT_STAT st;
8231 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008232 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008233
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008234 do {
8235 Py_BEGIN_ALLOW_THREADS
8236 res = FSTAT(fd, &st);
8237 Py_END_ALLOW_THREADS
8238 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008239 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008240#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008241 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008242#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008243 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008244#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 }
Tim Peters5aa91602002-01-30 05:46:57 +00008246
Victor Stinner4195b5c2012-02-08 23:03:19 +01008247 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008248}
8249
Larry Hastings2f936352014-08-05 14:04:04 +10008250
8251/*[clinic input]
8252os.isatty -> bool
8253 fd: int
8254 /
8255
8256Return True if the fd is connected to a terminal.
8257
8258Return True if the file descriptor is an open file descriptor
8259connected to the slave end of a terminal.
8260[clinic start generated code]*/
8261
Larry Hastings2f936352014-08-05 14:04:04 +10008262static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008263os_isatty_impl(PyObject *module, int fd)
8264/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008265{
Steve Dower8fc89802015-04-12 00:26:27 -04008266 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008267 _Py_BEGIN_SUPPRESS_IPH
8268 return_value = isatty(fd);
8269 _Py_END_SUPPRESS_IPH
8270 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008271}
8272
8273
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008274#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008275/*[clinic input]
8276os.pipe
8277
8278Create a pipe.
8279
8280Returns a tuple of two file descriptors:
8281 (read_fd, write_fd)
8282[clinic start generated code]*/
8283
Larry Hastings2f936352014-08-05 14:04:04 +10008284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008285os_pipe_impl(PyObject *module)
8286/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008287{
Victor Stinner8c62be82010-05-06 00:08:46 +00008288 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008289#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008291 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008293#else
8294 int res;
8295#endif
8296
8297#ifdef MS_WINDOWS
8298 attr.nLength = sizeof(attr);
8299 attr.lpSecurityDescriptor = NULL;
8300 attr.bInheritHandle = FALSE;
8301
8302 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008303 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008304 ok = CreatePipe(&read, &write, &attr, 0);
8305 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008306 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8307 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008308 if (fds[0] == -1 || fds[1] == -1) {
8309 CloseHandle(read);
8310 CloseHandle(write);
8311 ok = 0;
8312 }
8313 }
Steve Dowerc3630612016-11-19 18:41:16 -08008314 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008315 Py_END_ALLOW_THREADS
8316
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008318 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008319#else
8320
8321#ifdef HAVE_PIPE2
8322 Py_BEGIN_ALLOW_THREADS
8323 res = pipe2(fds, O_CLOEXEC);
8324 Py_END_ALLOW_THREADS
8325
8326 if (res != 0 && errno == ENOSYS)
8327 {
8328#endif
8329 Py_BEGIN_ALLOW_THREADS
8330 res = pipe(fds);
8331 Py_END_ALLOW_THREADS
8332
8333 if (res == 0) {
8334 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8335 close(fds[0]);
8336 close(fds[1]);
8337 return NULL;
8338 }
8339 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8340 close(fds[0]);
8341 close(fds[1]);
8342 return NULL;
8343 }
8344 }
8345#ifdef HAVE_PIPE2
8346 }
8347#endif
8348
8349 if (res != 0)
8350 return PyErr_SetFromErrno(PyExc_OSError);
8351#endif /* !MS_WINDOWS */
8352 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008353}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008354#endif /* HAVE_PIPE */
8355
Larry Hastings2f936352014-08-05 14:04:04 +10008356
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008357#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008358/*[clinic input]
8359os.pipe2
8360
8361 flags: int
8362 /
8363
8364Create a pipe with flags set atomically.
8365
8366Returns a tuple of two file descriptors:
8367 (read_fd, write_fd)
8368
8369flags can be constructed by ORing together one or more of these values:
8370O_NONBLOCK, O_CLOEXEC.
8371[clinic start generated code]*/
8372
Larry Hastings2f936352014-08-05 14:04:04 +10008373static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008374os_pipe2_impl(PyObject *module, int flags)
8375/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008376{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008377 int fds[2];
8378 int res;
8379
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008380 res = pipe2(fds, flags);
8381 if (res != 0)
8382 return posix_error();
8383 return Py_BuildValue("(ii)", fds[0], fds[1]);
8384}
8385#endif /* HAVE_PIPE2 */
8386
Larry Hastings2f936352014-08-05 14:04:04 +10008387
Ross Lagerwall7807c352011-03-17 20:20:30 +02008388#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008389/*[clinic input]
8390os.writev -> Py_ssize_t
8391 fd: int
8392 buffers: object
8393 /
8394
8395Iterate over buffers, and write the contents of each to a file descriptor.
8396
8397Returns the total number of bytes written.
8398buffers must be a sequence of bytes-like objects.
8399[clinic start generated code]*/
8400
Larry Hastings2f936352014-08-05 14:04:04 +10008401static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008402os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8403/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008404{
8405 int cnt;
8406 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008407 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008408 struct iovec *iov;
8409 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008410
8411 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008412 PyErr_SetString(PyExc_TypeError,
8413 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008414 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008415 }
Larry Hastings2f936352014-08-05 14:04:04 +10008416 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008417
Larry Hastings2f936352014-08-05 14:04:04 +10008418 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8419 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008420 }
8421
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422 do {
8423 Py_BEGIN_ALLOW_THREADS
8424 result = writev(fd, iov, cnt);
8425 Py_END_ALLOW_THREADS
8426 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008427
8428 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008429 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008430 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008431
Georg Brandl306336b2012-06-24 12:55:33 +02008432 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008433}
Larry Hastings2f936352014-08-05 14:04:04 +10008434#endif /* HAVE_WRITEV */
8435
8436
8437#ifdef HAVE_PWRITE
8438/*[clinic input]
8439os.pwrite -> Py_ssize_t
8440
8441 fd: int
8442 buffer: Py_buffer
8443 offset: Py_off_t
8444 /
8445
8446Write bytes to a file descriptor starting at a particular offset.
8447
8448Write buffer to fd, starting at offset bytes from the beginning of
8449the file. Returns the number of bytes writte. Does not change the
8450current file offset.
8451[clinic start generated code]*/
8452
Larry Hastings2f936352014-08-05 14:04:04 +10008453static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008454os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8455/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008456{
8457 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008458 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008459
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008460 do {
8461 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008462 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008463 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008464 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008465 Py_END_ALLOW_THREADS
8466 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008467
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008468 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008469 posix_error();
8470 return size;
8471}
8472#endif /* HAVE_PWRITE */
8473
8474
8475#ifdef HAVE_MKFIFO
8476/*[clinic input]
8477os.mkfifo
8478
8479 path: path_t
8480 mode: int=0o666
8481 *
8482 dir_fd: dir_fd(requires='mkfifoat')=None
8483
8484Create a "fifo" (a POSIX named pipe).
8485
8486If dir_fd is not None, it should be a file descriptor open to a directory,
8487 and path should be relative; path will then be relative to that directory.
8488dir_fd may not be implemented on your platform.
8489 If it is unavailable, using it will raise a NotImplementedError.
8490[clinic start generated code]*/
8491
Larry Hastings2f936352014-08-05 14:04:04 +10008492static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008493os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8494/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008495{
8496 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008497 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008498
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008499 do {
8500 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008501#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008502 if (dir_fd != DEFAULT_DIR_FD)
8503 result = mkfifoat(dir_fd, path->narrow, mode);
8504 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008505#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008506 result = mkfifo(path->narrow, mode);
8507 Py_END_ALLOW_THREADS
8508 } while (result != 0 && errno == EINTR &&
8509 !(async_err = PyErr_CheckSignals()));
8510 if (result != 0)
8511 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008512
8513 Py_RETURN_NONE;
8514}
8515#endif /* HAVE_MKFIFO */
8516
8517
8518#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8519/*[clinic input]
8520os.mknod
8521
8522 path: path_t
8523 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008524 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008525 *
8526 dir_fd: dir_fd(requires='mknodat')=None
8527
8528Create a node in the file system.
8529
8530Create a node in the file system (file, device special file or named pipe)
8531at path. mode specifies both the permissions to use and the
8532type of node to be created, being combined (bitwise OR) with one of
8533S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8534device defines the newly created device special file (probably using
8535os.makedev()). Otherwise device is ignored.
8536
8537If dir_fd is not None, it should be a file descriptor open to a directory,
8538 and path should be relative; path will then be relative to that directory.
8539dir_fd may not be implemented on your platform.
8540 If it is unavailable, using it will raise a NotImplementedError.
8541[clinic start generated code]*/
8542
Larry Hastings2f936352014-08-05 14:04:04 +10008543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008544os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008545 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008546/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008547{
8548 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008549 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008550
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008551 do {
8552 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008553#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008554 if (dir_fd != DEFAULT_DIR_FD)
8555 result = mknodat(dir_fd, path->narrow, mode, device);
8556 else
Larry Hastings2f936352014-08-05 14:04:04 +10008557#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008558 result = mknod(path->narrow, mode, device);
8559 Py_END_ALLOW_THREADS
8560 } while (result != 0 && errno == EINTR &&
8561 !(async_err = PyErr_CheckSignals()));
8562 if (result != 0)
8563 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008564
8565 Py_RETURN_NONE;
8566}
8567#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8568
8569
8570#ifdef HAVE_DEVICE_MACROS
8571/*[clinic input]
8572os.major -> unsigned_int
8573
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008574 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008575 /
8576
8577Extracts a device major number from a raw device number.
8578[clinic start generated code]*/
8579
Larry Hastings2f936352014-08-05 14:04:04 +10008580static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008581os_major_impl(PyObject *module, dev_t device)
8582/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008583{
8584 return major(device);
8585}
8586
8587
8588/*[clinic input]
8589os.minor -> unsigned_int
8590
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008591 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008592 /
8593
8594Extracts a device minor number from a raw device number.
8595[clinic start generated code]*/
8596
Larry Hastings2f936352014-08-05 14:04:04 +10008597static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008598os_minor_impl(PyObject *module, dev_t device)
8599/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008600{
8601 return minor(device);
8602}
8603
8604
8605/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008606os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008607
8608 major: int
8609 minor: int
8610 /
8611
8612Composes a raw device number from the major and minor device numbers.
8613[clinic start generated code]*/
8614
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008615static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008616os_makedev_impl(PyObject *module, int major, int minor)
8617/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008618{
8619 return makedev(major, minor);
8620}
8621#endif /* HAVE_DEVICE_MACROS */
8622
8623
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008624#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008625/*[clinic input]
8626os.ftruncate
8627
8628 fd: int
8629 length: Py_off_t
8630 /
8631
8632Truncate a file, specified by file descriptor, to a specific length.
8633[clinic start generated code]*/
8634
Larry Hastings2f936352014-08-05 14:04:04 +10008635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008636os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8637/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008638{
8639 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008641
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008642 do {
8643 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008644 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008645#ifdef MS_WINDOWS
8646 result = _chsize_s(fd, length);
8647#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008649#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008650 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008651 Py_END_ALLOW_THREADS
8652 } while (result != 0 && errno == EINTR &&
8653 !(async_err = PyErr_CheckSignals()));
8654 if (result != 0)
8655 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008656 Py_RETURN_NONE;
8657}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008658#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008659
8660
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008661#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008662/*[clinic input]
8663os.truncate
8664 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8665 length: Py_off_t
8666
8667Truncate a file, specified by path, to a specific length.
8668
8669On some platforms, path may also be specified as an open file descriptor.
8670 If this functionality is unavailable, using it raises an exception.
8671[clinic start generated code]*/
8672
Larry Hastings2f936352014-08-05 14:04:04 +10008673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008674os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8675/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008676{
8677 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008678#ifdef MS_WINDOWS
8679 int fd;
8680#endif
8681
8682 if (path->fd != -1)
8683 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008684
8685 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008686 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008687#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008688 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008689 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008690 result = -1;
8691 else {
8692 result = _chsize_s(fd, length);
8693 close(fd);
8694 if (result < 0)
8695 errno = result;
8696 }
8697#else
8698 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008699#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008700 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008701 Py_END_ALLOW_THREADS
8702 if (result < 0)
8703 return path_error(path);
8704
8705 Py_RETURN_NONE;
8706}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008707#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008708
Ross Lagerwall7807c352011-03-17 20:20:30 +02008709
Victor Stinnerd6b17692014-09-30 12:20:05 +02008710/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8711 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8712 defined, which is the case in Python on AIX. AIX bug report:
8713 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8714#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8715# define POSIX_FADVISE_AIX_BUG
8716#endif
8717
Victor Stinnerec39e262014-09-30 12:35:58 +02008718
Victor Stinnerd6b17692014-09-30 12:20:05 +02008719#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008720/*[clinic input]
8721os.posix_fallocate
8722
8723 fd: int
8724 offset: Py_off_t
8725 length: Py_off_t
8726 /
8727
8728Ensure a file has allocated at least a particular number of bytes on disk.
8729
8730Ensure that the file specified by fd encompasses a range of bytes
8731starting at offset bytes from the beginning and continuing for length bytes.
8732[clinic start generated code]*/
8733
Larry Hastings2f936352014-08-05 14:04:04 +10008734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008735os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008736 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008737/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008738{
8739 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008740 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008741
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008742 do {
8743 Py_BEGIN_ALLOW_THREADS
8744 result = posix_fallocate(fd, offset, length);
8745 Py_END_ALLOW_THREADS
8746 } while (result != 0 && errno == EINTR &&
8747 !(async_err = PyErr_CheckSignals()));
8748 if (result != 0)
8749 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008750 Py_RETURN_NONE;
8751}
Victor Stinnerec39e262014-09-30 12:35:58 +02008752#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008753
Ross Lagerwall7807c352011-03-17 20:20:30 +02008754
Victor Stinnerd6b17692014-09-30 12:20:05 +02008755#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008756/*[clinic input]
8757os.posix_fadvise
8758
8759 fd: int
8760 offset: Py_off_t
8761 length: Py_off_t
8762 advice: int
8763 /
8764
8765Announce an intention to access data in a specific pattern.
8766
8767Announce an intention to access data in a specific pattern, thus allowing
8768the kernel to make optimizations.
8769The advice applies to the region of the file specified by fd starting at
8770offset and continuing for length bytes.
8771advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8772POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8773POSIX_FADV_DONTNEED.
8774[clinic start generated code]*/
8775
Larry Hastings2f936352014-08-05 14:04:04 +10008776static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008777os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008778 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008779/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008780{
8781 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008782 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008783
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008784 do {
8785 Py_BEGIN_ALLOW_THREADS
8786 result = posix_fadvise(fd, offset, length, advice);
8787 Py_END_ALLOW_THREADS
8788 } while (result != 0 && errno == EINTR &&
8789 !(async_err = PyErr_CheckSignals()));
8790 if (result != 0)
8791 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008792 Py_RETURN_NONE;
8793}
Victor Stinnerec39e262014-09-30 12:35:58 +02008794#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008795
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008796#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008797
Fred Drake762e2061999-08-26 17:23:54 +00008798/* Save putenv() parameters as values here, so we can collect them when they
8799 * get re-set with another call for the same key. */
8800static PyObject *posix_putenv_garbage;
8801
Larry Hastings2f936352014-08-05 14:04:04 +10008802static void
8803posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008804{
Larry Hastings2f936352014-08-05 14:04:04 +10008805 /* Install the first arg and newstr in posix_putenv_garbage;
8806 * this will cause previous value to be collected. This has to
8807 * happen after the real putenv() call because the old value
8808 * was still accessible until then. */
8809 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8810 /* really not much we can do; just leak */
8811 PyErr_Clear();
8812 else
8813 Py_DECREF(value);
8814}
8815
8816
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008817#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008818/*[clinic input]
8819os.putenv
8820
8821 name: unicode
8822 value: unicode
8823 /
8824
8825Change or add an environment variable.
8826[clinic start generated code]*/
8827
Larry Hastings2f936352014-08-05 14:04:04 +10008828static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008829os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8830/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008831{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008832 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008833
8834 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8835 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008836 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008837 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008838 }
Larry Hastings2f936352014-08-05 14:04:04 +10008839 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008840 PyErr_Format(PyExc_ValueError,
8841 "the environment variable is longer than %u characters",
8842 _MAX_ENV);
8843 goto error;
8844 }
8845
Larry Hastings2f936352014-08-05 14:04:04 +10008846 env = PyUnicode_AsUnicode(unicode);
8847 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008848 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008849 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008851 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008853
Larry Hastings2f936352014-08-05 14:04:04 +10008854 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008855 Py_RETURN_NONE;
8856
8857error:
Larry Hastings2f936352014-08-05 14:04:04 +10008858 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008859 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008860}
Larry Hastings2f936352014-08-05 14:04:04 +10008861#else /* MS_WINDOWS */
8862/*[clinic input]
8863os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008864
Larry Hastings2f936352014-08-05 14:04:04 +10008865 name: FSConverter
8866 value: FSConverter
8867 /
8868
8869Change or add an environment variable.
8870[clinic start generated code]*/
8871
Larry Hastings2f936352014-08-05 14:04:04 +10008872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008873os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8874/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008875{
8876 PyObject *bytes = NULL;
8877 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008878 const char *name_string = PyBytes_AsString(name);
8879 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008880
8881 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8882 if (bytes == NULL) {
8883 PyErr_NoMemory();
8884 return NULL;
8885 }
8886
8887 env = PyBytes_AS_STRING(bytes);
8888 if (putenv(env)) {
8889 Py_DECREF(bytes);
8890 return posix_error();
8891 }
8892
8893 posix_putenv_garbage_setitem(name, bytes);
8894 Py_RETURN_NONE;
8895}
8896#endif /* MS_WINDOWS */
8897#endif /* HAVE_PUTENV */
8898
8899
8900#ifdef HAVE_UNSETENV
8901/*[clinic input]
8902os.unsetenv
8903 name: FSConverter
8904 /
8905
8906Delete an environment variable.
8907[clinic start generated code]*/
8908
Larry Hastings2f936352014-08-05 14:04:04 +10008909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008910os_unsetenv_impl(PyObject *module, PyObject *name)
8911/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008912{
Victor Stinner984890f2011-11-24 13:53:38 +01008913#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008914 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008915#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008916
Victor Stinner984890f2011-11-24 13:53:38 +01008917#ifdef HAVE_BROKEN_UNSETENV
8918 unsetenv(PyBytes_AS_STRING(name));
8919#else
Victor Stinner65170952011-11-22 22:16:17 +01008920 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008921 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008922 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008923#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008924
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 /* Remove the key from posix_putenv_garbage;
8926 * this will cause it to be collected. This has to
8927 * happen after the real unsetenv() call because the
8928 * old value was still accessible until then.
8929 */
Victor Stinner65170952011-11-22 22:16:17 +01008930 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 /* really not much we can do; just leak */
8932 PyErr_Clear();
8933 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008934 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008935}
Larry Hastings2f936352014-08-05 14:04:04 +10008936#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008937
Larry Hastings2f936352014-08-05 14:04:04 +10008938
8939/*[clinic input]
8940os.strerror
8941
8942 code: int
8943 /
8944
8945Translate an error code to a message string.
8946[clinic start generated code]*/
8947
Larry Hastings2f936352014-08-05 14:04:04 +10008948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008949os_strerror_impl(PyObject *module, int code)
8950/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008951{
8952 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 if (message == NULL) {
8954 PyErr_SetString(PyExc_ValueError,
8955 "strerror() argument out of range");
8956 return NULL;
8957 }
Victor Stinner1b579672011-12-17 05:47:23 +01008958 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008959}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008960
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008961
Guido van Rossumc9641791998-08-04 15:26:23 +00008962#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008963#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008964/*[clinic input]
8965os.WCOREDUMP -> bool
8966
8967 status: int
8968 /
8969
8970Return True if the process returning status was dumped to a core file.
8971[clinic start generated code]*/
8972
Larry Hastings2f936352014-08-05 14:04:04 +10008973static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008974os_WCOREDUMP_impl(PyObject *module, int status)
8975/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008976{
8977 WAIT_TYPE wait_status;
8978 WAIT_STATUS_INT(wait_status) = status;
8979 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008980}
8981#endif /* WCOREDUMP */
8982
Larry Hastings2f936352014-08-05 14:04:04 +10008983
Fred Drake106c1a02002-04-23 15:58:02 +00008984#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008985/*[clinic input]
8986os.WIFCONTINUED -> bool
8987
8988 status: int
8989
8990Return True if a particular process was continued from a job control stop.
8991
8992Return True if the process returning status was continued from a
8993job control stop.
8994[clinic start generated code]*/
8995
Larry Hastings2f936352014-08-05 14:04:04 +10008996static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008997os_WIFCONTINUED_impl(PyObject *module, int status)
8998/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008999{
9000 WAIT_TYPE wait_status;
9001 WAIT_STATUS_INT(wait_status) = status;
9002 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009003}
9004#endif /* WIFCONTINUED */
9005
Larry Hastings2f936352014-08-05 14:04:04 +10009006
Guido van Rossumc9641791998-08-04 15:26:23 +00009007#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009008/*[clinic input]
9009os.WIFSTOPPED -> bool
9010
9011 status: int
9012
9013Return True if the process returning status was stopped.
9014[clinic start generated code]*/
9015
Larry Hastings2f936352014-08-05 14:04:04 +10009016static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009017os_WIFSTOPPED_impl(PyObject *module, int status)
9018/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009019{
9020 WAIT_TYPE wait_status;
9021 WAIT_STATUS_INT(wait_status) = status;
9022 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009023}
9024#endif /* WIFSTOPPED */
9025
Larry Hastings2f936352014-08-05 14:04:04 +10009026
Guido van Rossumc9641791998-08-04 15:26:23 +00009027#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009028/*[clinic input]
9029os.WIFSIGNALED -> bool
9030
9031 status: int
9032
9033Return True if the process returning status was terminated by a signal.
9034[clinic start generated code]*/
9035
Larry Hastings2f936352014-08-05 14:04:04 +10009036static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009037os_WIFSIGNALED_impl(PyObject *module, int status)
9038/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009039{
9040 WAIT_TYPE wait_status;
9041 WAIT_STATUS_INT(wait_status) = status;
9042 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009043}
9044#endif /* WIFSIGNALED */
9045
Larry Hastings2f936352014-08-05 14:04:04 +10009046
Guido van Rossumc9641791998-08-04 15:26:23 +00009047#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009048/*[clinic input]
9049os.WIFEXITED -> bool
9050
9051 status: int
9052
9053Return True if the process returning status exited via the exit() system call.
9054[clinic start generated code]*/
9055
Larry Hastings2f936352014-08-05 14:04:04 +10009056static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009057os_WIFEXITED_impl(PyObject *module, int status)
9058/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009059{
9060 WAIT_TYPE wait_status;
9061 WAIT_STATUS_INT(wait_status) = status;
9062 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009063}
9064#endif /* WIFEXITED */
9065
Larry Hastings2f936352014-08-05 14:04:04 +10009066
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009067#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009068/*[clinic input]
9069os.WEXITSTATUS -> int
9070
9071 status: int
9072
9073Return the process return code from status.
9074[clinic start generated code]*/
9075
Larry Hastings2f936352014-08-05 14:04:04 +10009076static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009077os_WEXITSTATUS_impl(PyObject *module, int status)
9078/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009079{
9080 WAIT_TYPE wait_status;
9081 WAIT_STATUS_INT(wait_status) = status;
9082 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009083}
9084#endif /* WEXITSTATUS */
9085
Larry Hastings2f936352014-08-05 14:04:04 +10009086
Guido van Rossumc9641791998-08-04 15:26:23 +00009087#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009088/*[clinic input]
9089os.WTERMSIG -> int
9090
9091 status: int
9092
9093Return the signal that terminated the process that provided the status value.
9094[clinic start generated code]*/
9095
Larry Hastings2f936352014-08-05 14:04:04 +10009096static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009097os_WTERMSIG_impl(PyObject *module, int status)
9098/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009099{
9100 WAIT_TYPE wait_status;
9101 WAIT_STATUS_INT(wait_status) = status;
9102 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009103}
9104#endif /* WTERMSIG */
9105
Larry Hastings2f936352014-08-05 14:04:04 +10009106
Guido van Rossumc9641791998-08-04 15:26:23 +00009107#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009108/*[clinic input]
9109os.WSTOPSIG -> int
9110
9111 status: int
9112
9113Return the signal that stopped the process that provided the status value.
9114[clinic start generated code]*/
9115
Larry Hastings2f936352014-08-05 14:04:04 +10009116static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009117os_WSTOPSIG_impl(PyObject *module, int status)
9118/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009119{
9120 WAIT_TYPE wait_status;
9121 WAIT_STATUS_INT(wait_status) = status;
9122 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009123}
9124#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009125#endif /* HAVE_SYS_WAIT_H */
9126
9127
Thomas Wouters477c8d52006-05-27 19:21:47 +00009128#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009129#ifdef _SCO_DS
9130/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9131 needed definitions in sys/statvfs.h */
9132#define _SVID3
9133#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009134#include <sys/statvfs.h>
9135
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009136static PyObject*
9137_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9139 if (v == NULL)
9140 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009141
9142#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9144 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9145 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9146 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9147 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9148 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9149 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9150 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9151 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9152 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009153#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9155 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9156 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009157 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009159 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009161 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009163 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009165 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009167 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9169 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009170#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009171 if (PyErr_Occurred()) {
9172 Py_DECREF(v);
9173 return NULL;
9174 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009175
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009177}
9178
Larry Hastings2f936352014-08-05 14:04:04 +10009179
9180/*[clinic input]
9181os.fstatvfs
9182 fd: int
9183 /
9184
9185Perform an fstatvfs system call on the given fd.
9186
9187Equivalent to statvfs(fd).
9188[clinic start generated code]*/
9189
Larry Hastings2f936352014-08-05 14:04:04 +10009190static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009191os_fstatvfs_impl(PyObject *module, int fd)
9192/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009193{
9194 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009195 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009196 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009197
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009198 do {
9199 Py_BEGIN_ALLOW_THREADS
9200 result = fstatvfs(fd, &st);
9201 Py_END_ALLOW_THREADS
9202 } while (result != 0 && errno == EINTR &&
9203 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009204 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009205 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009206
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009208}
Larry Hastings2f936352014-08-05 14:04:04 +10009209#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009210
9211
Thomas Wouters477c8d52006-05-27 19:21:47 +00009212#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009213#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009214/*[clinic input]
9215os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009216
Larry Hastings2f936352014-08-05 14:04:04 +10009217 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9218
9219Perform a statvfs system call on the given path.
9220
9221path may always be specified as a string.
9222On some platforms, path may also be specified as an open file descriptor.
9223 If this functionality is unavailable, using it raises an exception.
9224[clinic start generated code]*/
9225
Larry Hastings2f936352014-08-05 14:04:04 +10009226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009227os_statvfs_impl(PyObject *module, path_t *path)
9228/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009229{
9230 int result;
9231 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009232
9233 Py_BEGIN_ALLOW_THREADS
9234#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009235 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009236#ifdef __APPLE__
9237 /* handle weak-linking on Mac OS X 10.3 */
9238 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009239 fd_specified("statvfs", path->fd);
9240 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009241 }
9242#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009243 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009244 }
9245 else
9246#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009247 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009248 Py_END_ALLOW_THREADS
9249
9250 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009251 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009252 }
9253
Larry Hastings2f936352014-08-05 14:04:04 +10009254 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009255}
Larry Hastings2f936352014-08-05 14:04:04 +10009256#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9257
Guido van Rossum94f6f721999-01-06 18:42:14 +00009258
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009259#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009260/*[clinic input]
9261os._getdiskusage
9262
9263 path: Py_UNICODE
9264
9265Return disk usage statistics about the given path as a (total, free) tuple.
9266[clinic start generated code]*/
9267
Larry Hastings2f936352014-08-05 14:04:04 +10009268static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009269os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9270/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009271{
9272 BOOL retval;
9273 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009274
9275 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009276 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009277 Py_END_ALLOW_THREADS
9278 if (retval == 0)
9279 return PyErr_SetFromWindowsErr(0);
9280
9281 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9282}
Larry Hastings2f936352014-08-05 14:04:04 +10009283#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009284
9285
Fred Drakec9680921999-12-13 16:37:25 +00009286/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9287 * It maps strings representing configuration variable names to
9288 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009289 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009290 * rarely-used constants. There are three separate tables that use
9291 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009292 *
9293 * This code is always included, even if none of the interfaces that
9294 * need it are included. The #if hackery needed to avoid it would be
9295 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009296 */
9297struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009298 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009299 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009300};
9301
Fred Drake12c6e2d1999-12-14 21:25:03 +00009302static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009303conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009304 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009305{
Christian Heimes217cfd12007-12-02 14:31:20 +00009306 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009307 int value = _PyLong_AsInt(arg);
9308 if (value == -1 && PyErr_Occurred())
9309 return 0;
9310 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009311 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009312 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009313 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009314 /* look up the value in the table using a binary search */
9315 size_t lo = 0;
9316 size_t mid;
9317 size_t hi = tablesize;
9318 int cmp;
9319 const char *confname;
9320 if (!PyUnicode_Check(arg)) {
9321 PyErr_SetString(PyExc_TypeError,
9322 "configuration names must be strings or integers");
9323 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009325 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009326 if (confname == NULL)
9327 return 0;
9328 while (lo < hi) {
9329 mid = (lo + hi) / 2;
9330 cmp = strcmp(confname, table[mid].name);
9331 if (cmp < 0)
9332 hi = mid;
9333 else if (cmp > 0)
9334 lo = mid + 1;
9335 else {
9336 *valuep = table[mid].value;
9337 return 1;
9338 }
9339 }
9340 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9341 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009343}
9344
9345
9346#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9347static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009348#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009350#endif
9351#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009353#endif
Fred Drakec9680921999-12-13 16:37:25 +00009354#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009356#endif
9357#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009359#endif
9360#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009362#endif
9363#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009399#ifdef _PC_ACL_ENABLED
9400 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9401#endif
9402#ifdef _PC_MIN_HOLE_SIZE
9403 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9404#endif
9405#ifdef _PC_ALLOC_SIZE_MIN
9406 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9407#endif
9408#ifdef _PC_REC_INCR_XFER_SIZE
9409 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9410#endif
9411#ifdef _PC_REC_MAX_XFER_SIZE
9412 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9413#endif
9414#ifdef _PC_REC_MIN_XFER_SIZE
9415 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9416#endif
9417#ifdef _PC_REC_XFER_ALIGN
9418 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9419#endif
9420#ifdef _PC_SYMLINK_MAX
9421 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9422#endif
9423#ifdef _PC_XATTR_ENABLED
9424 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9425#endif
9426#ifdef _PC_XATTR_EXISTS
9427 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9428#endif
9429#ifdef _PC_TIMESTAMP_RESOLUTION
9430 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9431#endif
Fred Drakec9680921999-12-13 16:37:25 +00009432};
9433
Fred Drakec9680921999-12-13 16:37:25 +00009434static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009435conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009436{
9437 return conv_confname(arg, valuep, posix_constants_pathconf,
9438 sizeof(posix_constants_pathconf)
9439 / sizeof(struct constdef));
9440}
9441#endif
9442
Larry Hastings2f936352014-08-05 14:04:04 +10009443
Fred Drakec9680921999-12-13 16:37:25 +00009444#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009445/*[clinic input]
9446os.fpathconf -> long
9447
9448 fd: int
9449 name: path_confname
9450 /
9451
9452Return the configuration limit name for the file descriptor fd.
9453
9454If there is no limit, return -1.
9455[clinic start generated code]*/
9456
Larry Hastings2f936352014-08-05 14:04:04 +10009457static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009458os_fpathconf_impl(PyObject *module, int fd, int name)
9459/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009460{
9461 long limit;
9462
9463 errno = 0;
9464 limit = fpathconf(fd, name);
9465 if (limit == -1 && errno != 0)
9466 posix_error();
9467
9468 return limit;
9469}
9470#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009471
9472
9473#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009474/*[clinic input]
9475os.pathconf -> long
9476 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9477 name: path_confname
9478
9479Return the configuration limit name for the file or directory path.
9480
9481If there is no limit, return -1.
9482On some platforms, path may also be specified as an open file descriptor.
9483 If this functionality is unavailable, using it raises an exception.
9484[clinic start generated code]*/
9485
Larry Hastings2f936352014-08-05 14:04:04 +10009486static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009487os_pathconf_impl(PyObject *module, path_t *path, int name)
9488/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009489{
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009491
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009493#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009494 if (path->fd != -1)
9495 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009496 else
9497#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009498 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 if (limit == -1 && errno != 0) {
9500 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009501 /* could be a path or name problem */
9502 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009503 else
Larry Hastings2f936352014-08-05 14:04:04 +10009504 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 }
Larry Hastings2f936352014-08-05 14:04:04 +10009506
9507 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009508}
Larry Hastings2f936352014-08-05 14:04:04 +10009509#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009510
9511#ifdef HAVE_CONFSTR
9512static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009513#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009515#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009516#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009518#endif
9519#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009521#endif
Fred Draked86ed291999-12-15 15:34:33 +00009522#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009524#endif
9525#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009527#endif
9528#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009530#endif
9531#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009533#endif
Fred Drakec9680921999-12-13 16:37:25 +00009534#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009536#endif
9537#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
Fred Draked86ed291999-12-15 15:34:33 +00009558#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009560#endif
Fred Drakec9680921999-12-13 16:37:25 +00009561#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
Fred Draked86ed291999-12-15 15:34:33 +00009564#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009566#endif
9567#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009569#endif
9570#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009572#endif
9573#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009575#endif
Fred Drakec9680921999-12-13 16:37:25 +00009576#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
Fred Draked86ed291999-12-15 15:34:33 +00009624#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009626#endif
9627#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009629#endif
9630#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009632#endif
9633#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009635#endif
9636#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009638#endif
9639#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009641#endif
9642#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009644#endif
9645#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009647#endif
9648#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
9654#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
9657#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
Fred Drakec9680921999-12-13 16:37:25 +00009663};
9664
9665static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009666conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009667{
9668 return conv_confname(arg, valuep, posix_constants_confstr,
9669 sizeof(posix_constants_confstr)
9670 / sizeof(struct constdef));
9671}
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673
9674/*[clinic input]
9675os.confstr
9676
9677 name: confstr_confname
9678 /
9679
9680Return a string-valued system configuration variable.
9681[clinic start generated code]*/
9682
Larry Hastings2f936352014-08-05 14:04:04 +10009683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009684os_confstr_impl(PyObject *module, int name)
9685/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009686{
9687 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009688 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009689 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009690
Victor Stinnercb043522010-09-10 23:49:04 +00009691 errno = 0;
9692 len = confstr(name, buffer, sizeof(buffer));
9693 if (len == 0) {
9694 if (errno) {
9695 posix_error();
9696 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009697 }
9698 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009699 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009700 }
9701 }
Victor Stinnercb043522010-09-10 23:49:04 +00009702
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009703 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009704 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009705 char *buf = PyMem_Malloc(len);
9706 if (buf == NULL)
9707 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009708 len2 = confstr(name, buf, len);
9709 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009710 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009711 PyMem_Free(buf);
9712 }
9713 else
9714 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009715 return result;
9716}
Larry Hastings2f936352014-08-05 14:04:04 +10009717#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009718
9719
9720#ifdef HAVE_SYSCONF
9721static struct constdef posix_constants_sysconf[] = {
9722#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
Fred Draked86ed291999-12-15 15:34:33 +00009752#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009754#endif
9755#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
Fred Drakec9680921999-12-13 16:37:25 +00009758#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
Fred Drakec9680921999-12-13 16:37:25 +00009761#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
Fred Draked86ed291999-12-15 15:34:33 +00009776#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009778#endif
Fred Drakec9680921999-12-13 16:37:25 +00009779#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
Fred Draked86ed291999-12-15 15:34:33 +00009794#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009796#endif
Fred Drakec9680921999-12-13 16:37:25 +00009797#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
Fred Draked86ed291999-12-15 15:34:33 +00009866#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009868#endif
Fred Drakec9680921999-12-13 16:37:25 +00009869#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
Fred Draked86ed291999-12-15 15:34:33 +00009878#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009880#endif
Fred Drakec9680921999-12-13 16:37:25 +00009881#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
Fred Draked86ed291999-12-15 15:34:33 +00009884#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009886#endif
9887#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009889#endif
Fred Drakec9680921999-12-13 16:37:25 +00009890#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
Fred Draked86ed291999-12-15 15:34:33 +00009902#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009904#endif
Fred Drakec9680921999-12-13 16:37:25 +00009905#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
Fred Draked86ed291999-12-15 15:34:33 +00009926#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009928#endif
Fred Drakec9680921999-12-13 16:37:25 +00009929#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
Fred Draked86ed291999-12-15 15:34:33 +00009935#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009937#endif
Fred Drakec9680921999-12-13 16:37:25 +00009938#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
Fred Draked86ed291999-12-15 15:34:33 +00009965#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009967#endif
9968#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009970#endif
Fred Drakec9680921999-12-13 16:37:25 +00009971#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
Fred Draked86ed291999-12-15 15:34:33 +000010076#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010078#endif
Fred Drakec9680921999-12-13 16:37:25 +000010079#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214};
10215
10216static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010217conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010218{
10219 return conv_confname(arg, valuep, posix_constants_sysconf,
10220 sizeof(posix_constants_sysconf)
10221 / sizeof(struct constdef));
10222}
10223
Larry Hastings2f936352014-08-05 14:04:04 +100010224
10225/*[clinic input]
10226os.sysconf -> long
10227 name: sysconf_confname
10228 /
10229
10230Return an integer-valued system configuration variable.
10231[clinic start generated code]*/
10232
Larry Hastings2f936352014-08-05 14:04:04 +100010233static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010234os_sysconf_impl(PyObject *module, int name)
10235/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010236{
10237 long value;
10238
10239 errno = 0;
10240 value = sysconf(name);
10241 if (value == -1 && errno != 0)
10242 posix_error();
10243 return value;
10244}
10245#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010246
10247
Fred Drakebec628d1999-12-15 18:31:10 +000010248/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010249 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010250 * the exported dictionaries that are used to publish information about the
10251 * names available on the host platform.
10252 *
10253 * Sorting the table at runtime ensures that the table is properly ordered
10254 * when used, even for platforms we're not able to test on. It also makes
10255 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010256 */
Fred Drakebec628d1999-12-15 18:31:10 +000010257
10258static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010259cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010260{
10261 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010263 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010265
10266 return strcmp(c1->name, c2->name);
10267}
10268
10269static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010270setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010271 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010272{
Fred Drakebec628d1999-12-15 18:31:10 +000010273 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010274 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010275
10276 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10277 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010278 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010280
Barry Warsaw3155db32000-04-13 15:20:40 +000010281 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 PyObject *o = PyLong_FromLong(table[i].value);
10283 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10284 Py_XDECREF(o);
10285 Py_DECREF(d);
10286 return -1;
10287 }
10288 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010289 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010290 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010291}
10292
Fred Drakebec628d1999-12-15 18:31:10 +000010293/* Return -1 on failure, 0 on success. */
10294static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010295setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010296{
10297#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010298 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010299 sizeof(posix_constants_pathconf)
10300 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010301 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010302 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010303#endif
10304#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010305 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010306 sizeof(posix_constants_confstr)
10307 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010308 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010309 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010310#endif
10311#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010312 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010313 sizeof(posix_constants_sysconf)
10314 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010315 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010316 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010317#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010318 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010319}
Fred Draked86ed291999-12-15 15:34:33 +000010320
10321
Larry Hastings2f936352014-08-05 14:04:04 +100010322/*[clinic input]
10323os.abort
10324
10325Abort the interpreter immediately.
10326
10327This function 'dumps core' or otherwise fails in the hardest way possible
10328on the hosting operating system. This function never returns.
10329[clinic start generated code]*/
10330
Larry Hastings2f936352014-08-05 14:04:04 +100010331static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010332os_abort_impl(PyObject *module)
10333/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010334{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010335 abort();
10336 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010337#ifndef __clang__
10338 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10339 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10340 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010341 Py_FatalError("abort() called from Python code didn't abort!");
10342 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010343#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010344}
Fred Drakebec628d1999-12-15 18:31:10 +000010345
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010346#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010347/* Grab ShellExecute dynamically from shell32 */
10348static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010349static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10350 LPCWSTR, INT);
10351static int
10352check_ShellExecute()
10353{
10354 HINSTANCE hShell32;
10355
10356 /* only recheck */
10357 if (-1 == has_ShellExecute) {
10358 Py_BEGIN_ALLOW_THREADS
10359 hShell32 = LoadLibraryW(L"SHELL32");
10360 Py_END_ALLOW_THREADS
10361 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010362 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10363 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010364 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010365 } else {
10366 has_ShellExecute = 0;
10367 }
10368 }
10369 return has_ShellExecute;
10370}
10371
10372
Steve Dowercc16be82016-09-08 10:35:16 -070010373/*[clinic input]
10374os.startfile
10375 filepath: path_t
10376 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010377
Steve Dowercc16be82016-09-08 10:35:16 -070010378startfile(filepath [, operation])
10379
10380Start a file with its associated application.
10381
10382When "operation" is not specified or "open", this acts like
10383double-clicking the file in Explorer, or giving the file name as an
10384argument to the DOS "start" command: the file is opened with whatever
10385application (if any) its extension is associated.
10386When another "operation" is given, it specifies what should be done with
10387the file. A typical operation is "print".
10388
10389startfile returns as soon as the associated application is launched.
10390There is no option to wait for the application to close, and no way
10391to retrieve the application's exit status.
10392
10393The filepath is relative to the current directory. If you want to use
10394an absolute path, make sure the first character is not a slash ("/");
10395the underlying Win32 ShellExecute function doesn't work if it is.
10396[clinic start generated code]*/
10397
10398static PyObject *
10399os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10400/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10401{
10402 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010403
10404 if(!check_ShellExecute()) {
10405 /* If the OS doesn't have ShellExecute, return a
10406 NotImplementedError. */
10407 return PyErr_Format(PyExc_NotImplementedError,
10408 "startfile not available on this platform");
10409 }
10410
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010412 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010413 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 Py_END_ALLOW_THREADS
10415
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010417 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010418 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 }
Steve Dowercc16be82016-09-08 10:35:16 -070010420 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010421}
Larry Hastings2f936352014-08-05 14:04:04 +100010422#endif /* MS_WINDOWS */
10423
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010424
Martin v. Löwis438b5342002-12-27 10:16:42 +000010425#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010426/*[clinic input]
10427os.getloadavg
10428
10429Return average recent system load information.
10430
10431Return the number of processes in the system run queue averaged over
10432the last 1, 5, and 15 minutes as a tuple of three floats.
10433Raises OSError if the load average was unobtainable.
10434[clinic start generated code]*/
10435
Larry Hastings2f936352014-08-05 14:04:04 +100010436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010437os_getloadavg_impl(PyObject *module)
10438/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010439{
10440 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010441 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010442 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10443 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010444 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010445 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010446}
Larry Hastings2f936352014-08-05 14:04:04 +100010447#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010448
Larry Hastings2f936352014-08-05 14:04:04 +100010449
10450/*[clinic input]
10451os.device_encoding
10452 fd: int
10453
10454Return a string describing the encoding of a terminal's file descriptor.
10455
10456The file descriptor must be attached to a terminal.
10457If the device is not a terminal, return None.
10458[clinic start generated code]*/
10459
Larry Hastings2f936352014-08-05 14:04:04 +100010460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010461os_device_encoding_impl(PyObject *module, int fd)
10462/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010463{
Brett Cannonefb00c02012-02-29 18:31:31 -050010464 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010465}
10466
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010467
Larry Hastings2f936352014-08-05 14:04:04 +100010468#ifdef HAVE_SETRESUID
10469/*[clinic input]
10470os.setresuid
10471
10472 ruid: uid_t
10473 euid: uid_t
10474 suid: uid_t
10475 /
10476
10477Set the current process's real, effective, and saved user ids.
10478[clinic start generated code]*/
10479
Larry Hastings2f936352014-08-05 14:04:04 +100010480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010481os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10482/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010483{
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 if (setresuid(ruid, euid, suid) < 0)
10485 return posix_error();
10486 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010487}
Larry Hastings2f936352014-08-05 14:04:04 +100010488#endif /* HAVE_SETRESUID */
10489
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010490
10491#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010492/*[clinic input]
10493os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010494
Larry Hastings2f936352014-08-05 14:04:04 +100010495 rgid: gid_t
10496 egid: gid_t
10497 sgid: gid_t
10498 /
10499
10500Set the current process's real, effective, and saved group ids.
10501[clinic start generated code]*/
10502
Larry Hastings2f936352014-08-05 14:04:04 +100010503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010504os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10505/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010506{
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 if (setresgid(rgid, egid, sgid) < 0)
10508 return posix_error();
10509 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010510}
Larry Hastings2f936352014-08-05 14:04:04 +100010511#endif /* HAVE_SETRESGID */
10512
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010513
10514#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010515/*[clinic input]
10516os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010517
Larry Hastings2f936352014-08-05 14:04:04 +100010518Return a tuple of the current process's real, effective, and saved user ids.
10519[clinic start generated code]*/
10520
Larry Hastings2f936352014-08-05 14:04:04 +100010521static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010522os_getresuid_impl(PyObject *module)
10523/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010524{
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 if (getresuid(&ruid, &euid, &suid) < 0)
10527 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010528 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10529 _PyLong_FromUid(euid),
10530 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010531}
Larry Hastings2f936352014-08-05 14:04:04 +100010532#endif /* HAVE_GETRESUID */
10533
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010534
10535#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010536/*[clinic input]
10537os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010538
Larry Hastings2f936352014-08-05 14:04:04 +100010539Return a tuple of the current process's real, effective, and saved group ids.
10540[clinic start generated code]*/
10541
Larry Hastings2f936352014-08-05 14:04:04 +100010542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010543os_getresgid_impl(PyObject *module)
10544/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010545{
10546 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 if (getresgid(&rgid, &egid, &sgid) < 0)
10548 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010549 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10550 _PyLong_FromGid(egid),
10551 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010552}
Larry Hastings2f936352014-08-05 14:04:04 +100010553#endif /* HAVE_GETRESGID */
10554
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010555
Benjamin Peterson9428d532011-09-14 11:45:52 -040010556#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010557/*[clinic input]
10558os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010559
Larry Hastings2f936352014-08-05 14:04:04 +100010560 path: path_t(allow_fd=True)
10561 attribute: path_t
10562 *
10563 follow_symlinks: bool = True
10564
10565Return the value of extended attribute attribute on path.
10566
10567path may be either a string or an open file descriptor.
10568If follow_symlinks is False, and the last element of the path is a symbolic
10569 link, getxattr will examine the symbolic link itself instead of the file
10570 the link points to.
10571
10572[clinic start generated code]*/
10573
Larry Hastings2f936352014-08-05 14:04:04 +100010574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010575os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010576 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010577/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010578{
10579 Py_ssize_t i;
10580 PyObject *buffer = NULL;
10581
10582 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10583 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010584
Larry Hastings9cf065c2012-06-22 16:30:09 -070010585 for (i = 0; ; i++) {
10586 void *ptr;
10587 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010588 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010589 Py_ssize_t buffer_size = buffer_sizes[i];
10590 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010591 path_error(path);
10592 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010593 }
10594 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10595 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010596 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010597 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010598
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010600 if (path->fd >= 0)
10601 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010602 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010603 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010604 else
Larry Hastings2f936352014-08-05 14:04:04 +100010605 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010607
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 if (result < 0) {
10609 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 if (errno == ERANGE)
10611 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010612 path_error(path);
10613 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010615
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 if (result != buffer_size) {
10617 /* Can only shrink. */
10618 _PyBytes_Resize(&buffer, result);
10619 }
10620 break;
10621 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622
Larry Hastings9cf065c2012-06-22 16:30:09 -070010623 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010624}
10625
Larry Hastings2f936352014-08-05 14:04:04 +100010626
10627/*[clinic input]
10628os.setxattr
10629
10630 path: path_t(allow_fd=True)
10631 attribute: path_t
10632 value: Py_buffer
10633 flags: int = 0
10634 *
10635 follow_symlinks: bool = True
10636
10637Set extended attribute attribute on path to value.
10638
10639path may be either a string or an open file descriptor.
10640If follow_symlinks is False, and the last element of the path is a symbolic
10641 link, setxattr will modify the symbolic link itself instead of the file
10642 the link points to.
10643
10644[clinic start generated code]*/
10645
Benjamin Peterson799bd802011-08-31 22:15:17 -040010646static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010647os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010648 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010649/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650{
Larry Hastings2f936352014-08-05 14:04:04 +100010651 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652
Larry Hastings2f936352014-08-05 14:04:04 +100010653 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010654 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010655
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010657 if (path->fd > -1)
10658 result = fsetxattr(path->fd, attribute->narrow,
10659 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010660 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010661 result = setxattr(path->narrow, attribute->narrow,
10662 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010663 else
Larry Hastings2f936352014-08-05 14:04:04 +100010664 result = lsetxattr(path->narrow, attribute->narrow,
10665 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010666 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010667
Larry Hastings9cf065c2012-06-22 16:30:09 -070010668 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010669 path_error(path);
10670 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010671 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010672
Larry Hastings2f936352014-08-05 14:04:04 +100010673 Py_RETURN_NONE;
10674}
10675
10676
10677/*[clinic input]
10678os.removexattr
10679
10680 path: path_t(allow_fd=True)
10681 attribute: path_t
10682 *
10683 follow_symlinks: bool = True
10684
10685Remove extended attribute attribute on path.
10686
10687path may be either a string or an open file descriptor.
10688If follow_symlinks is False, and the last element of the path is a symbolic
10689 link, removexattr will modify the symbolic link itself instead of the file
10690 the link points to.
10691
10692[clinic start generated code]*/
10693
Larry Hastings2f936352014-08-05 14:04:04 +100010694static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010695os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010696 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010697/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010698{
10699 ssize_t result;
10700
10701 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10702 return NULL;
10703
10704 Py_BEGIN_ALLOW_THREADS;
10705 if (path->fd > -1)
10706 result = fremovexattr(path->fd, attribute->narrow);
10707 else if (follow_symlinks)
10708 result = removexattr(path->narrow, attribute->narrow);
10709 else
10710 result = lremovexattr(path->narrow, attribute->narrow);
10711 Py_END_ALLOW_THREADS;
10712
10713 if (result) {
10714 return path_error(path);
10715 }
10716
10717 Py_RETURN_NONE;
10718}
10719
10720
10721/*[clinic input]
10722os.listxattr
10723
10724 path: path_t(allow_fd=True, nullable=True) = None
10725 *
10726 follow_symlinks: bool = True
10727
10728Return a list of extended attributes on path.
10729
10730path may be either None, a string, or an open file descriptor.
10731if path is None, listxattr will examine the current directory.
10732If follow_symlinks is False, and the last element of the path is a symbolic
10733 link, listxattr will examine the symbolic link itself instead of the file
10734 the link points to.
10735[clinic start generated code]*/
10736
Larry Hastings2f936352014-08-05 14:04:04 +100010737static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010738os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10739/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010740{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741 Py_ssize_t i;
10742 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010743 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010744 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010745
Larry Hastings2f936352014-08-05 14:04:04 +100010746 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010748
Larry Hastings2f936352014-08-05 14:04:04 +100010749 name = path->narrow ? path->narrow : ".";
10750
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010752 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010754 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 Py_ssize_t buffer_size = buffer_sizes[i];
10756 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010757 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010758 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010759 break;
10760 }
10761 buffer = PyMem_MALLOC(buffer_size);
10762 if (!buffer) {
10763 PyErr_NoMemory();
10764 break;
10765 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010766
Larry Hastings9cf065c2012-06-22 16:30:09 -070010767 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010768 if (path->fd > -1)
10769 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010770 else if (follow_symlinks)
10771 length = listxattr(name, buffer, buffer_size);
10772 else
10773 length = llistxattr(name, buffer, buffer_size);
10774 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010775
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010777 if (errno == ERANGE) {
10778 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010779 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010780 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010781 }
Larry Hastings2f936352014-08-05 14:04:04 +100010782 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783 break;
10784 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010785
Larry Hastings9cf065c2012-06-22 16:30:09 -070010786 result = PyList_New(0);
10787 if (!result) {
10788 goto exit;
10789 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010790
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 end = buffer + length;
10792 for (trace = start = buffer; trace != end; trace++) {
10793 if (!*trace) {
10794 int error;
10795 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10796 trace - start);
10797 if (!attribute) {
10798 Py_DECREF(result);
10799 result = NULL;
10800 goto exit;
10801 }
10802 error = PyList_Append(result, attribute);
10803 Py_DECREF(attribute);
10804 if (error) {
10805 Py_DECREF(result);
10806 result = NULL;
10807 goto exit;
10808 }
10809 start = trace + 1;
10810 }
10811 }
10812 break;
10813 }
10814exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010815 if (buffer)
10816 PyMem_FREE(buffer);
10817 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010819#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010821
Larry Hastings2f936352014-08-05 14:04:04 +100010822/*[clinic input]
10823os.urandom
10824
10825 size: Py_ssize_t
10826 /
10827
10828Return a bytes object containing random bytes suitable for cryptographic use.
10829[clinic start generated code]*/
10830
Larry Hastings2f936352014-08-05 14:04:04 +100010831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010832os_urandom_impl(PyObject *module, Py_ssize_t size)
10833/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010834{
10835 PyObject *bytes;
10836 int result;
10837
Georg Brandl2fb477c2012-02-21 00:33:36 +010010838 if (size < 0)
10839 return PyErr_Format(PyExc_ValueError,
10840 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010841 bytes = PyBytes_FromStringAndSize(NULL, size);
10842 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010843 return NULL;
10844
Victor Stinnere66987e2016-09-06 16:33:52 -070010845 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010846 if (result == -1) {
10847 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010848 return NULL;
10849 }
Larry Hastings2f936352014-08-05 14:04:04 +100010850 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010851}
10852
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010853/* Terminal size querying */
10854
10855static PyTypeObject TerminalSizeType;
10856
10857PyDoc_STRVAR(TerminalSize_docstring,
10858 "A tuple of (columns, lines) for holding terminal window size");
10859
10860static PyStructSequence_Field TerminalSize_fields[] = {
10861 {"columns", "width of the terminal window in characters"},
10862 {"lines", "height of the terminal window in characters"},
10863 {NULL, NULL}
10864};
10865
10866static PyStructSequence_Desc TerminalSize_desc = {
10867 "os.terminal_size",
10868 TerminalSize_docstring,
10869 TerminalSize_fields,
10870 2,
10871};
10872
10873#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010874/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010875PyDoc_STRVAR(termsize__doc__,
10876 "Return the size of the terminal window as (columns, lines).\n" \
10877 "\n" \
10878 "The optional argument fd (default standard output) specifies\n" \
10879 "which file descriptor should be queried.\n" \
10880 "\n" \
10881 "If the file descriptor is not connected to a terminal, an OSError\n" \
10882 "is thrown.\n" \
10883 "\n" \
10884 "This function will only be defined if an implementation is\n" \
10885 "available for this system.\n" \
10886 "\n" \
10887 "shutil.get_terminal_size is the high-level function which should \n" \
10888 "normally be used, os.get_terminal_size is the low-level implementation.");
10889
10890static PyObject*
10891get_terminal_size(PyObject *self, PyObject *args)
10892{
10893 int columns, lines;
10894 PyObject *termsize;
10895
10896 int fd = fileno(stdout);
10897 /* Under some conditions stdout may not be connected and
10898 * fileno(stdout) may point to an invalid file descriptor. For example
10899 * GUI apps don't have valid standard streams by default.
10900 *
10901 * If this happens, and the optional fd argument is not present,
10902 * the ioctl below will fail returning EBADF. This is what we want.
10903 */
10904
10905 if (!PyArg_ParseTuple(args, "|i", &fd))
10906 return NULL;
10907
10908#ifdef TERMSIZE_USE_IOCTL
10909 {
10910 struct winsize w;
10911 if (ioctl(fd, TIOCGWINSZ, &w))
10912 return PyErr_SetFromErrno(PyExc_OSError);
10913 columns = w.ws_col;
10914 lines = w.ws_row;
10915 }
10916#endif /* TERMSIZE_USE_IOCTL */
10917
10918#ifdef TERMSIZE_USE_CONIO
10919 {
10920 DWORD nhandle;
10921 HANDLE handle;
10922 CONSOLE_SCREEN_BUFFER_INFO csbi;
10923 switch (fd) {
10924 case 0: nhandle = STD_INPUT_HANDLE;
10925 break;
10926 case 1: nhandle = STD_OUTPUT_HANDLE;
10927 break;
10928 case 2: nhandle = STD_ERROR_HANDLE;
10929 break;
10930 default:
10931 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10932 }
10933 handle = GetStdHandle(nhandle);
10934 if (handle == NULL)
10935 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10936 if (handle == INVALID_HANDLE_VALUE)
10937 return PyErr_SetFromWindowsErr(0);
10938
10939 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10940 return PyErr_SetFromWindowsErr(0);
10941
10942 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10943 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10944 }
10945#endif /* TERMSIZE_USE_CONIO */
10946
10947 termsize = PyStructSequence_New(&TerminalSizeType);
10948 if (termsize == NULL)
10949 return NULL;
10950 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10951 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10952 if (PyErr_Occurred()) {
10953 Py_DECREF(termsize);
10954 return NULL;
10955 }
10956 return termsize;
10957}
10958#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10959
Larry Hastings2f936352014-08-05 14:04:04 +100010960
10961/*[clinic input]
10962os.cpu_count
10963
Charles-François Natali80d62e62015-08-13 20:37:08 +010010964Return the number of CPUs in the system; return None if indeterminable.
10965
10966This number is not equivalent to the number of CPUs the current process can
10967use. The number of usable CPUs can be obtained with
10968``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010969[clinic start generated code]*/
10970
Larry Hastings2f936352014-08-05 14:04:04 +100010971static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010972os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010973/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010974{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010975 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010976#ifdef MS_WINDOWS
10977 SYSTEM_INFO sysinfo;
10978 GetSystemInfo(&sysinfo);
10979 ncpu = sysinfo.dwNumberOfProcessors;
10980#elif defined(__hpux)
10981 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10982#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10983 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010984#elif defined(__DragonFly__) || \
10985 defined(__OpenBSD__) || \
10986 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010987 defined(__NetBSD__) || \
10988 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010989 int mib[2];
10990 size_t len = sizeof(ncpu);
10991 mib[0] = CTL_HW;
10992 mib[1] = HW_NCPU;
10993 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10994 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010995#endif
10996 if (ncpu >= 1)
10997 return PyLong_FromLong(ncpu);
10998 else
10999 Py_RETURN_NONE;
11000}
11001
Victor Stinnerdaf45552013-08-28 00:53:59 +020011002
Larry Hastings2f936352014-08-05 14:04:04 +100011003/*[clinic input]
11004os.get_inheritable -> bool
11005
11006 fd: int
11007 /
11008
11009Get the close-on-exe flag of the specified file descriptor.
11010[clinic start generated code]*/
11011
Larry Hastings2f936352014-08-05 14:04:04 +100011012static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011013os_get_inheritable_impl(PyObject *module, int fd)
11014/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011015{
Steve Dower8fc89802015-04-12 00:26:27 -040011016 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011017 _Py_BEGIN_SUPPRESS_IPH
11018 return_value = _Py_get_inheritable(fd);
11019 _Py_END_SUPPRESS_IPH
11020 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011021}
11022
11023
11024/*[clinic input]
11025os.set_inheritable
11026 fd: int
11027 inheritable: int
11028 /
11029
11030Set the inheritable flag of the specified file descriptor.
11031[clinic start generated code]*/
11032
Larry Hastings2f936352014-08-05 14:04:04 +100011033static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011034os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11035/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011036{
Steve Dower8fc89802015-04-12 00:26:27 -040011037 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011038
Steve Dower8fc89802015-04-12 00:26:27 -040011039 _Py_BEGIN_SUPPRESS_IPH
11040 result = _Py_set_inheritable(fd, inheritable, NULL);
11041 _Py_END_SUPPRESS_IPH
11042 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011043 return NULL;
11044 Py_RETURN_NONE;
11045}
11046
11047
11048#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011049/*[clinic input]
11050os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011051 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011052 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011053
Larry Hastings2f936352014-08-05 14:04:04 +100011054Get the close-on-exe flag of the specified file descriptor.
11055[clinic start generated code]*/
11056
Larry Hastings2f936352014-08-05 14:04:04 +100011057static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011058os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011059/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011060{
11061 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011062
11063 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11064 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011065 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011066 }
11067
Larry Hastings2f936352014-08-05 14:04:04 +100011068 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011069}
11070
Victor Stinnerdaf45552013-08-28 00:53:59 +020011071
Larry Hastings2f936352014-08-05 14:04:04 +100011072/*[clinic input]
11073os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011074 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011075 inheritable: bool
11076 /
11077
11078Set the inheritable flag of the specified handle.
11079[clinic start generated code]*/
11080
Larry Hastings2f936352014-08-05 14:04:04 +100011081static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011082os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011083 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011084/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011085{
11086 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011087 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11088 PyErr_SetFromWindowsErr(0);
11089 return NULL;
11090 }
11091 Py_RETURN_NONE;
11092}
Larry Hastings2f936352014-08-05 14:04:04 +100011093#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011094
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011095#ifndef MS_WINDOWS
11096PyDoc_STRVAR(get_blocking__doc__,
11097 "get_blocking(fd) -> bool\n" \
11098 "\n" \
11099 "Get the blocking mode of the file descriptor:\n" \
11100 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11101
11102static PyObject*
11103posix_get_blocking(PyObject *self, PyObject *args)
11104{
11105 int fd;
11106 int blocking;
11107
11108 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11109 return NULL;
11110
Steve Dower8fc89802015-04-12 00:26:27 -040011111 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011112 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011113 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011114 if (blocking < 0)
11115 return NULL;
11116 return PyBool_FromLong(blocking);
11117}
11118
11119PyDoc_STRVAR(set_blocking__doc__,
11120 "set_blocking(fd, blocking)\n" \
11121 "\n" \
11122 "Set the blocking mode of the specified file descriptor.\n" \
11123 "Set the O_NONBLOCK flag if blocking is False,\n" \
11124 "clear the O_NONBLOCK flag otherwise.");
11125
11126static PyObject*
11127posix_set_blocking(PyObject *self, PyObject *args)
11128{
Steve Dower8fc89802015-04-12 00:26:27 -040011129 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011130
11131 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11132 return NULL;
11133
Steve Dower8fc89802015-04-12 00:26:27 -040011134 _Py_BEGIN_SUPPRESS_IPH
11135 result = _Py_set_blocking(fd, blocking);
11136 _Py_END_SUPPRESS_IPH
11137 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011138 return NULL;
11139 Py_RETURN_NONE;
11140}
11141#endif /* !MS_WINDOWS */
11142
11143
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011144/*[clinic input]
11145class os.DirEntry "DirEntry *" "&DirEntryType"
11146[clinic start generated code]*/
11147/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011148
11149typedef struct {
11150 PyObject_HEAD
11151 PyObject *name;
11152 PyObject *path;
11153 PyObject *stat;
11154 PyObject *lstat;
11155#ifdef MS_WINDOWS
11156 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011157 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011158 int got_file_index;
11159#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011160#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011161 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011162#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011163 ino_t d_ino;
11164#endif
11165} DirEntry;
11166
11167static void
11168DirEntry_dealloc(DirEntry *entry)
11169{
11170 Py_XDECREF(entry->name);
11171 Py_XDECREF(entry->path);
11172 Py_XDECREF(entry->stat);
11173 Py_XDECREF(entry->lstat);
11174 Py_TYPE(entry)->tp_free((PyObject *)entry);
11175}
11176
11177/* Forward reference */
11178static int
11179DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11180
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011181/*[clinic input]
11182os.DirEntry.is_symlink -> bool
11183
11184Return True if the entry is a symbolic link; cached per entry.
11185[clinic start generated code]*/
11186
Victor Stinner6036e442015-03-08 01:58:04 +010011187static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011188os_DirEntry_is_symlink_impl(DirEntry *self)
11189/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011190{
11191#ifdef MS_WINDOWS
11192 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011193#elif defined(HAVE_DIRENT_D_TYPE)
11194 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011195 if (self->d_type != DT_UNKNOWN)
11196 return self->d_type == DT_LNK;
11197 else
11198 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011199#else
11200 /* POSIX without d_type */
11201 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011202#endif
11203}
11204
11205static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011206DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11207{
11208 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011209 STRUCT_STAT st;
11210 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011211
11212#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011213 if (PyUnicode_FSDecoder(self->path, &ub)) {
11214 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011215#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011216 if (PyUnicode_FSConverter(self->path, &ub)) {
11217 const char *path = PyBytes_AS_STRING(ub);
11218#endif
11219 if (follow_symlinks)
11220 result = STAT(path, &st);
11221 else
11222 result = LSTAT(path, &st);
11223 Py_DECREF(ub);
11224 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011225 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011226
11227 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011228 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011229
11230 return _pystat_fromstructstat(&st);
11231}
11232
11233static PyObject *
11234DirEntry_get_lstat(DirEntry *self)
11235{
11236 if (!self->lstat) {
11237#ifdef MS_WINDOWS
11238 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11239#else /* POSIX */
11240 self->lstat = DirEntry_fetch_stat(self, 0);
11241#endif
11242 }
11243 Py_XINCREF(self->lstat);
11244 return self->lstat;
11245}
11246
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011247/*[clinic input]
11248os.DirEntry.stat
11249 *
11250 follow_symlinks: bool = True
11251
11252Return stat_result object for the entry; cached per entry.
11253[clinic start generated code]*/
11254
Victor Stinner6036e442015-03-08 01:58:04 +010011255static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011256os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11257/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011258{
11259 if (!follow_symlinks)
11260 return DirEntry_get_lstat(self);
11261
11262 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011263 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011264 if (result == -1)
11265 return NULL;
11266 else if (result)
11267 self->stat = DirEntry_fetch_stat(self, 1);
11268 else
11269 self->stat = DirEntry_get_lstat(self);
11270 }
11271
11272 Py_XINCREF(self->stat);
11273 return self->stat;
11274}
11275
Victor Stinner6036e442015-03-08 01:58:04 +010011276/* Set exception and return -1 on error, 0 for False, 1 for True */
11277static int
11278DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11279{
11280 PyObject *stat = NULL;
11281 PyObject *st_mode = NULL;
11282 long mode;
11283 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011284#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011285 int is_symlink;
11286 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011287#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011288#ifdef MS_WINDOWS
11289 unsigned long dir_bits;
11290#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011291 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011292
11293#ifdef MS_WINDOWS
11294 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11295 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011296#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011297 is_symlink = self->d_type == DT_LNK;
11298 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11299#endif
11300
Victor Stinner35a97c02015-03-08 02:59:09 +010011301#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011302 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011303#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011304 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011305 if (!stat) {
11306 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11307 /* If file doesn't exist (anymore), then return False
11308 (i.e., say it's not a file/directory) */
11309 PyErr_Clear();
11310 return 0;
11311 }
11312 goto error;
11313 }
11314 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11315 if (!st_mode)
11316 goto error;
11317
11318 mode = PyLong_AsLong(st_mode);
11319 if (mode == -1 && PyErr_Occurred())
11320 goto error;
11321 Py_CLEAR(st_mode);
11322 Py_CLEAR(stat);
11323 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011324#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011325 }
11326 else if (is_symlink) {
11327 assert(mode_bits != S_IFLNK);
11328 result = 0;
11329 }
11330 else {
11331 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11332#ifdef MS_WINDOWS
11333 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11334 if (mode_bits == S_IFDIR)
11335 result = dir_bits != 0;
11336 else
11337 result = dir_bits == 0;
11338#else /* POSIX */
11339 if (mode_bits == S_IFDIR)
11340 result = self->d_type == DT_DIR;
11341 else
11342 result = self->d_type == DT_REG;
11343#endif
11344 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011345#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011346
11347 return result;
11348
11349error:
11350 Py_XDECREF(st_mode);
11351 Py_XDECREF(stat);
11352 return -1;
11353}
11354
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011355/*[clinic input]
11356os.DirEntry.is_dir -> bool
11357 *
11358 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011359
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011360Return True if the entry is a directory; cached per entry.
11361[clinic start generated code]*/
11362
11363static int
11364os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11365/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11366{
11367 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011368}
11369
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011370/*[clinic input]
11371os.DirEntry.is_file -> bool
11372 *
11373 follow_symlinks: bool = True
11374
11375Return True if the entry is a file; cached per entry.
11376[clinic start generated code]*/
11377
11378static int
11379os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11380/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011381{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011382 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011383}
11384
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011385/*[clinic input]
11386os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011387
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011388Return inode of the entry; cached per entry.
11389[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011390
11391static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011392os_DirEntry_inode_impl(DirEntry *self)
11393/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011394{
11395#ifdef MS_WINDOWS
11396 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011397 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011398 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011399 STRUCT_STAT stat;
11400 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011401
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011402 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011403 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011404 path = PyUnicode_AsUnicode(unicode);
11405 result = LSTAT(path, &stat);
11406 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011407
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011408 if (result != 0)
11409 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011410
11411 self->win32_file_index = stat.st_ino;
11412 self->got_file_index = 1;
11413 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011414 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11415 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011416#else /* POSIX */
11417#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011418 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011419#else
11420 return PyLong_FromLong((long)self->d_ino);
11421#endif
11422#endif
11423}
11424
11425static PyObject *
11426DirEntry_repr(DirEntry *self)
11427{
11428 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11429}
11430
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011431/*[clinic input]
11432os.DirEntry.__fspath__
11433
11434Returns the path for the entry.
11435[clinic start generated code]*/
11436
Brett Cannon96881cd2016-06-10 14:37:21 -070011437static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011438os_DirEntry___fspath___impl(DirEntry *self)
11439/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011440{
11441 Py_INCREF(self->path);
11442 return self->path;
11443}
11444
Victor Stinner6036e442015-03-08 01:58:04 +010011445static PyMemberDef DirEntry_members[] = {
11446 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11447 "the entry's base filename, relative to scandir() \"path\" argument"},
11448 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11449 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11450 {NULL}
11451};
11452
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011453#include "clinic/posixmodule.c.h"
11454
Victor Stinner6036e442015-03-08 01:58:04 +010011455static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011456 OS_DIRENTRY_IS_DIR_METHODDEF
11457 OS_DIRENTRY_IS_FILE_METHODDEF
11458 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11459 OS_DIRENTRY_STAT_METHODDEF
11460 OS_DIRENTRY_INODE_METHODDEF
11461 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011462 {NULL}
11463};
11464
Benjamin Peterson5646de42015-04-12 17:56:34 -040011465static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011466 PyVarObject_HEAD_INIT(NULL, 0)
11467 MODNAME ".DirEntry", /* tp_name */
11468 sizeof(DirEntry), /* tp_basicsize */
11469 0, /* tp_itemsize */
11470 /* methods */
11471 (destructor)DirEntry_dealloc, /* tp_dealloc */
11472 0, /* tp_print */
11473 0, /* tp_getattr */
11474 0, /* tp_setattr */
11475 0, /* tp_compare */
11476 (reprfunc)DirEntry_repr, /* tp_repr */
11477 0, /* tp_as_number */
11478 0, /* tp_as_sequence */
11479 0, /* tp_as_mapping */
11480 0, /* tp_hash */
11481 0, /* tp_call */
11482 0, /* tp_str */
11483 0, /* tp_getattro */
11484 0, /* tp_setattro */
11485 0, /* tp_as_buffer */
11486 Py_TPFLAGS_DEFAULT, /* tp_flags */
11487 0, /* tp_doc */
11488 0, /* tp_traverse */
11489 0, /* tp_clear */
11490 0, /* tp_richcompare */
11491 0, /* tp_weaklistoffset */
11492 0, /* tp_iter */
11493 0, /* tp_iternext */
11494 DirEntry_methods, /* tp_methods */
11495 DirEntry_members, /* tp_members */
11496};
11497
11498#ifdef MS_WINDOWS
11499
11500static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011501join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011502{
11503 Py_ssize_t path_len;
11504 Py_ssize_t size;
11505 wchar_t *result;
11506 wchar_t ch;
11507
11508 if (!path_wide) { /* Default arg: "." */
11509 path_wide = L".";
11510 path_len = 1;
11511 }
11512 else {
11513 path_len = wcslen(path_wide);
11514 }
11515
11516 /* The +1's are for the path separator and the NUL */
11517 size = path_len + 1 + wcslen(filename) + 1;
11518 result = PyMem_New(wchar_t, size);
11519 if (!result) {
11520 PyErr_NoMemory();
11521 return NULL;
11522 }
11523 wcscpy(result, path_wide);
11524 if (path_len > 0) {
11525 ch = result[path_len - 1];
11526 if (ch != SEP && ch != ALTSEP && ch != L':')
11527 result[path_len++] = SEP;
11528 wcscpy(result + path_len, filename);
11529 }
11530 return result;
11531}
11532
11533static PyObject *
11534DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11535{
11536 DirEntry *entry;
11537 BY_HANDLE_FILE_INFORMATION file_info;
11538 ULONG reparse_tag;
11539 wchar_t *joined_path;
11540
11541 entry = PyObject_New(DirEntry, &DirEntryType);
11542 if (!entry)
11543 return NULL;
11544 entry->name = NULL;
11545 entry->path = NULL;
11546 entry->stat = NULL;
11547 entry->lstat = NULL;
11548 entry->got_file_index = 0;
11549
11550 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11551 if (!entry->name)
11552 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011553 if (path->narrow) {
11554 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11555 if (!entry->name)
11556 goto error;
11557 }
Victor Stinner6036e442015-03-08 01:58:04 +010011558
11559 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11560 if (!joined_path)
11561 goto error;
11562
11563 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11564 PyMem_Free(joined_path);
11565 if (!entry->path)
11566 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011567 if (path->narrow) {
11568 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11569 if (!entry->path)
11570 goto error;
11571 }
Victor Stinner6036e442015-03-08 01:58:04 +010011572
Steve Dowercc16be82016-09-08 10:35:16 -070011573 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011574 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11575
11576 return (PyObject *)entry;
11577
11578error:
11579 Py_DECREF(entry);
11580 return NULL;
11581}
11582
11583#else /* POSIX */
11584
11585static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011586join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011587{
11588 Py_ssize_t path_len;
11589 Py_ssize_t size;
11590 char *result;
11591
11592 if (!path_narrow) { /* Default arg: "." */
11593 path_narrow = ".";
11594 path_len = 1;
11595 }
11596 else {
11597 path_len = strlen(path_narrow);
11598 }
11599
11600 if (filename_len == -1)
11601 filename_len = strlen(filename);
11602
11603 /* The +1's are for the path separator and the NUL */
11604 size = path_len + 1 + filename_len + 1;
11605 result = PyMem_New(char, size);
11606 if (!result) {
11607 PyErr_NoMemory();
11608 return NULL;
11609 }
11610 strcpy(result, path_narrow);
11611 if (path_len > 0 && result[path_len - 1] != '/')
11612 result[path_len++] = '/';
11613 strcpy(result + path_len, filename);
11614 return result;
11615}
11616
11617static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011618DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011619 ino_t d_ino
11620#ifdef HAVE_DIRENT_D_TYPE
11621 , unsigned char d_type
11622#endif
11623 )
Victor Stinner6036e442015-03-08 01:58:04 +010011624{
11625 DirEntry *entry;
11626 char *joined_path;
11627
11628 entry = PyObject_New(DirEntry, &DirEntryType);
11629 if (!entry)
11630 return NULL;
11631 entry->name = NULL;
11632 entry->path = NULL;
11633 entry->stat = NULL;
11634 entry->lstat = NULL;
11635
11636 joined_path = join_path_filename(path->narrow, name, name_len);
11637 if (!joined_path)
11638 goto error;
11639
11640 if (!path->narrow || !PyBytes_Check(path->object)) {
11641 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11642 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11643 }
11644 else {
11645 entry->name = PyBytes_FromStringAndSize(name, name_len);
11646 entry->path = PyBytes_FromString(joined_path);
11647 }
11648 PyMem_Free(joined_path);
11649 if (!entry->name || !entry->path)
11650 goto error;
11651
Victor Stinner35a97c02015-03-08 02:59:09 +010011652#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011653 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011654#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011655 entry->d_ino = d_ino;
11656
11657 return (PyObject *)entry;
11658
11659error:
11660 Py_XDECREF(entry);
11661 return NULL;
11662}
11663
11664#endif
11665
11666
11667typedef struct {
11668 PyObject_HEAD
11669 path_t path;
11670#ifdef MS_WINDOWS
11671 HANDLE handle;
11672 WIN32_FIND_DATAW file_data;
11673 int first_time;
11674#else /* POSIX */
11675 DIR *dirp;
11676#endif
11677} ScandirIterator;
11678
11679#ifdef MS_WINDOWS
11680
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011681static int
11682ScandirIterator_is_closed(ScandirIterator *iterator)
11683{
11684 return iterator->handle == INVALID_HANDLE_VALUE;
11685}
11686
Victor Stinner6036e442015-03-08 01:58:04 +010011687static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011688ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011689{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011690 HANDLE handle = iterator->handle;
11691
11692 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011693 return;
11694
Victor Stinner6036e442015-03-08 01:58:04 +010011695 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011696 Py_BEGIN_ALLOW_THREADS
11697 FindClose(handle);
11698 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011699}
11700
11701static PyObject *
11702ScandirIterator_iternext(ScandirIterator *iterator)
11703{
11704 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11705 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011706 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011707
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011708 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011709 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011710 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011711
11712 while (1) {
11713 if (!iterator->first_time) {
11714 Py_BEGIN_ALLOW_THREADS
11715 success = FindNextFileW(iterator->handle, file_data);
11716 Py_END_ALLOW_THREADS
11717 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011718 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011719 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011720 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011721 break;
11722 }
11723 }
11724 iterator->first_time = 0;
11725
11726 /* Skip over . and .. */
11727 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011728 wcscmp(file_data->cFileName, L"..") != 0) {
11729 entry = DirEntry_from_find_data(&iterator->path, file_data);
11730 if (!entry)
11731 break;
11732 return entry;
11733 }
Victor Stinner6036e442015-03-08 01:58:04 +010011734
11735 /* Loop till we get a non-dot directory or finish iterating */
11736 }
11737
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011738 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011739 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011740 return NULL;
11741}
11742
11743#else /* POSIX */
11744
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011745static int
11746ScandirIterator_is_closed(ScandirIterator *iterator)
11747{
11748 return !iterator->dirp;
11749}
11750
Victor Stinner6036e442015-03-08 01:58:04 +010011751static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011752ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011753{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011754 DIR *dirp = iterator->dirp;
11755
11756 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011757 return;
11758
Victor Stinner6036e442015-03-08 01:58:04 +010011759 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011760 Py_BEGIN_ALLOW_THREADS
11761 closedir(dirp);
11762 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011763 return;
11764}
11765
11766static PyObject *
11767ScandirIterator_iternext(ScandirIterator *iterator)
11768{
11769 struct dirent *direntp;
11770 Py_ssize_t name_len;
11771 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011772 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011773
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011774 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011775 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011776 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011777
11778 while (1) {
11779 errno = 0;
11780 Py_BEGIN_ALLOW_THREADS
11781 direntp = readdir(iterator->dirp);
11782 Py_END_ALLOW_THREADS
11783
11784 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011785 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011786 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011787 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011788 break;
11789 }
11790
11791 /* Skip over . and .. */
11792 name_len = NAMLEN(direntp);
11793 is_dot = direntp->d_name[0] == '.' &&
11794 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11795 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011796 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011797 name_len, direntp->d_ino
11798#ifdef HAVE_DIRENT_D_TYPE
11799 , direntp->d_type
11800#endif
11801 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011802 if (!entry)
11803 break;
11804 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011805 }
11806
11807 /* Loop till we get a non-dot directory or finish iterating */
11808 }
11809
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011810 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011811 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011812 return NULL;
11813}
11814
11815#endif
11816
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011817static PyObject *
11818ScandirIterator_close(ScandirIterator *self, PyObject *args)
11819{
11820 ScandirIterator_closedir(self);
11821 Py_RETURN_NONE;
11822}
11823
11824static PyObject *
11825ScandirIterator_enter(PyObject *self, PyObject *args)
11826{
11827 Py_INCREF(self);
11828 return self;
11829}
11830
11831static PyObject *
11832ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11833{
11834 ScandirIterator_closedir(self);
11835 Py_RETURN_NONE;
11836}
11837
Victor Stinner6036e442015-03-08 01:58:04 +010011838static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011839ScandirIterator_finalize(ScandirIterator *iterator)
11840{
11841 PyObject *error_type, *error_value, *error_traceback;
11842
11843 /* Save the current exception, if any. */
11844 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11845
11846 if (!ScandirIterator_is_closed(iterator)) {
11847 ScandirIterator_closedir(iterator);
11848
11849 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11850 "unclosed scandir iterator %R", iterator)) {
11851 /* Spurious errors can appear at shutdown */
11852 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11853 PyErr_WriteUnraisable((PyObject *) iterator);
11854 }
11855 }
11856 }
11857
Victor Stinner7bfa4092016-03-23 00:43:54 +010011858 path_cleanup(&iterator->path);
11859
11860 /* Restore the saved exception. */
11861 PyErr_Restore(error_type, error_value, error_traceback);
11862}
11863
11864static void
Victor Stinner6036e442015-03-08 01:58:04 +010011865ScandirIterator_dealloc(ScandirIterator *iterator)
11866{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011867 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11868 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011869
Victor Stinner6036e442015-03-08 01:58:04 +010011870 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11871}
11872
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011873static PyMethodDef ScandirIterator_methods[] = {
11874 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11875 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11876 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11877 {NULL}
11878};
11879
Benjamin Peterson5646de42015-04-12 17:56:34 -040011880static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011881 PyVarObject_HEAD_INIT(NULL, 0)
11882 MODNAME ".ScandirIterator", /* tp_name */
11883 sizeof(ScandirIterator), /* tp_basicsize */
11884 0, /* tp_itemsize */
11885 /* methods */
11886 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11887 0, /* tp_print */
11888 0, /* tp_getattr */
11889 0, /* tp_setattr */
11890 0, /* tp_compare */
11891 0, /* tp_repr */
11892 0, /* tp_as_number */
11893 0, /* tp_as_sequence */
11894 0, /* tp_as_mapping */
11895 0, /* tp_hash */
11896 0, /* tp_call */
11897 0, /* tp_str */
11898 0, /* tp_getattro */
11899 0, /* tp_setattro */
11900 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011901 Py_TPFLAGS_DEFAULT
11902 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011903 0, /* tp_doc */
11904 0, /* tp_traverse */
11905 0, /* tp_clear */
11906 0, /* tp_richcompare */
11907 0, /* tp_weaklistoffset */
11908 PyObject_SelfIter, /* tp_iter */
11909 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011910 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011911 0, /* tp_members */
11912 0, /* tp_getset */
11913 0, /* tp_base */
11914 0, /* tp_dict */
11915 0, /* tp_descr_get */
11916 0, /* tp_descr_set */
11917 0, /* tp_dictoffset */
11918 0, /* tp_init */
11919 0, /* tp_alloc */
11920 0, /* tp_new */
11921 0, /* tp_free */
11922 0, /* tp_is_gc */
11923 0, /* tp_bases */
11924 0, /* tp_mro */
11925 0, /* tp_cache */
11926 0, /* tp_subclasses */
11927 0, /* tp_weaklist */
11928 0, /* tp_del */
11929 0, /* tp_version_tag */
11930 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011931};
11932
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011933/*[clinic input]
11934os.scandir
11935
11936 path : path_t(nullable=True) = None
11937
11938Return an iterator of DirEntry objects for given path.
11939
11940path can be specified as either str, bytes or path-like object. If path
11941is bytes, the names of yielded DirEntry objects will also be bytes; in
11942all other circumstances they will be str.
11943
11944If path is None, uses the path='.'.
11945[clinic start generated code]*/
11946
Victor Stinner6036e442015-03-08 01:58:04 +010011947static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011948os_scandir_impl(PyObject *module, path_t *path)
11949/*[clinic end generated code: output=6eb2668b675ca89e input=e62b08b3cd41f604]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011950{
11951 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010011952#ifdef MS_WINDOWS
11953 wchar_t *path_strW;
11954#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011955 const char *path_str;
Victor Stinner6036e442015-03-08 01:58:04 +010011956#endif
11957
11958 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11959 if (!iterator)
11960 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011961
11962#ifdef MS_WINDOWS
11963 iterator->handle = INVALID_HANDLE_VALUE;
11964#else
11965 iterator->dirp = NULL;
11966#endif
11967
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011968 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020011969 /* Move the ownership to iterator->path */
11970 path->object = NULL;
11971 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011972
11973#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011974 iterator->first_time = 1;
11975
11976 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11977 if (!path_strW)
11978 goto error;
11979
11980 Py_BEGIN_ALLOW_THREADS
11981 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11982 Py_END_ALLOW_THREADS
11983
11984 PyMem_Free(path_strW);
11985
11986 if (iterator->handle == INVALID_HANDLE_VALUE) {
11987 path_error(&iterator->path);
11988 goto error;
11989 }
11990#else /* POSIX */
11991 if (iterator->path.narrow)
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011992 path_str = iterator->path.narrow;
Victor Stinner6036e442015-03-08 01:58:04 +010011993 else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011994 path_str = ".";
Victor Stinner6036e442015-03-08 01:58:04 +010011995
11996 errno = 0;
11997 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011998 iterator->dirp = opendir(path_str);
Victor Stinner6036e442015-03-08 01:58:04 +010011999 Py_END_ALLOW_THREADS
12000
12001 if (!iterator->dirp) {
12002 path_error(&iterator->path);
12003 goto error;
12004 }
12005#endif
12006
12007 return (PyObject *)iterator;
12008
12009error:
12010 Py_DECREF(iterator);
12011 return NULL;
12012}
12013
Ethan Furman410ef8e2016-06-04 12:06:26 -070012014/*
12015 Return the file system path representation of the object.
12016
12017 If the object is str or bytes, then allow it to pass through with
12018 an incremented refcount. If the object defines __fspath__(), then
12019 return the result of that method. All other types raise a TypeError.
12020*/
12021PyObject *
12022PyOS_FSPath(PyObject *path)
12023{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012024 /* For error message reasons, this function is manually inlined in
12025 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012026 _Py_IDENTIFIER(__fspath__);
12027 PyObject *func = NULL;
12028 PyObject *path_repr = NULL;
12029
12030 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12031 Py_INCREF(path);
12032 return path;
12033 }
12034
12035 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12036 if (NULL == func) {
12037 return PyErr_Format(PyExc_TypeError,
12038 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012039 "not %.200s",
12040 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012041 }
12042
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012043 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012044 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012045 if (NULL == path_repr) {
12046 return NULL;
12047 }
12048
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012049 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12050 PyErr_Format(PyExc_TypeError,
12051 "expected %.200s.__fspath__() to return str or bytes, "
12052 "not %.200s", Py_TYPE(path)->tp_name,
12053 Py_TYPE(path_repr)->tp_name);
12054 Py_DECREF(path_repr);
12055 return NULL;
12056 }
12057
Ethan Furman410ef8e2016-06-04 12:06:26 -070012058 return path_repr;
12059}
12060
12061/*[clinic input]
12062os.fspath
12063
12064 path: object
12065
12066Return the file system path representation of the object.
12067
Brett Cannonb4f43e92016-06-09 14:32:08 -070012068If the object is str or bytes, then allow it to pass through as-is. If the
12069object defines __fspath__(), then return the result of that method. All other
12070types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012071[clinic start generated code]*/
12072
12073static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012074os_fspath_impl(PyObject *module, PyObject *path)
12075/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012076{
12077 return PyOS_FSPath(path);
12078}
Victor Stinner6036e442015-03-08 01:58:04 +010012079
Victor Stinner9b1f4742016-09-06 16:18:52 -070012080#ifdef HAVE_GETRANDOM_SYSCALL
12081/*[clinic input]
12082os.getrandom
12083
12084 size: Py_ssize_t
12085 flags: int=0
12086
12087Obtain a series of random bytes.
12088[clinic start generated code]*/
12089
12090static PyObject *
12091os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12092/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12093{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012094 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012095 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012096
12097 if (size < 0) {
12098 errno = EINVAL;
12099 return posix_error();
12100 }
12101
Victor Stinnerec2319c2016-09-20 23:00:59 +020012102 bytes = PyBytes_FromStringAndSize(NULL, size);
12103 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012104 PyErr_NoMemory();
12105 return NULL;
12106 }
12107
12108 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012109 n = syscall(SYS_getrandom,
12110 PyBytes_AS_STRING(bytes),
12111 PyBytes_GET_SIZE(bytes),
12112 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012113 if (n < 0 && errno == EINTR) {
12114 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012115 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012116 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012117
12118 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012119 continue;
12120 }
12121 break;
12122 }
12123
12124 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012125 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012126 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012127 }
12128
Victor Stinnerec2319c2016-09-20 23:00:59 +020012129 if (n != size) {
12130 _PyBytes_Resize(&bytes, n);
12131 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012132
12133 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012134
12135error:
12136 Py_DECREF(bytes);
12137 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012138}
12139#endif /* HAVE_GETRANDOM_SYSCALL */
12140
Larry Hastings31826802013-10-19 00:09:25 -070012141
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012142static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012143
12144 OS_STAT_METHODDEF
12145 OS_ACCESS_METHODDEF
12146 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012147 OS_CHDIR_METHODDEF
12148 OS_CHFLAGS_METHODDEF
12149 OS_CHMOD_METHODDEF
12150 OS_FCHMOD_METHODDEF
12151 OS_LCHMOD_METHODDEF
12152 OS_CHOWN_METHODDEF
12153 OS_FCHOWN_METHODDEF
12154 OS_LCHOWN_METHODDEF
12155 OS_LCHFLAGS_METHODDEF
12156 OS_CHROOT_METHODDEF
12157 OS_CTERMID_METHODDEF
12158 OS_GETCWD_METHODDEF
12159 OS_GETCWDB_METHODDEF
12160 OS_LINK_METHODDEF
12161 OS_LISTDIR_METHODDEF
12162 OS_LSTAT_METHODDEF
12163 OS_MKDIR_METHODDEF
12164 OS_NICE_METHODDEF
12165 OS_GETPRIORITY_METHODDEF
12166 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012167#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012168 {"readlink", (PyCFunction)posix_readlink,
12169 METH_VARARGS | METH_KEYWORDS,
12170 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012171#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012172#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012173 {"readlink", (PyCFunction)win_readlink,
12174 METH_VARARGS | METH_KEYWORDS,
12175 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012176#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012177 OS_RENAME_METHODDEF
12178 OS_REPLACE_METHODDEF
12179 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012180 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012181 OS_SYMLINK_METHODDEF
12182 OS_SYSTEM_METHODDEF
12183 OS_UMASK_METHODDEF
12184 OS_UNAME_METHODDEF
12185 OS_UNLINK_METHODDEF
12186 OS_REMOVE_METHODDEF
12187 OS_UTIME_METHODDEF
12188 OS_TIMES_METHODDEF
12189 OS__EXIT_METHODDEF
12190 OS_EXECV_METHODDEF
12191 OS_EXECVE_METHODDEF
12192 OS_SPAWNV_METHODDEF
12193 OS_SPAWNVE_METHODDEF
12194 OS_FORK1_METHODDEF
12195 OS_FORK_METHODDEF
12196 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12197 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12198 OS_SCHED_GETPARAM_METHODDEF
12199 OS_SCHED_GETSCHEDULER_METHODDEF
12200 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12201 OS_SCHED_SETPARAM_METHODDEF
12202 OS_SCHED_SETSCHEDULER_METHODDEF
12203 OS_SCHED_YIELD_METHODDEF
12204 OS_SCHED_SETAFFINITY_METHODDEF
12205 OS_SCHED_GETAFFINITY_METHODDEF
12206 OS_OPENPTY_METHODDEF
12207 OS_FORKPTY_METHODDEF
12208 OS_GETEGID_METHODDEF
12209 OS_GETEUID_METHODDEF
12210 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012211#ifdef HAVE_GETGROUPLIST
12212 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12213#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012214 OS_GETGROUPS_METHODDEF
12215 OS_GETPID_METHODDEF
12216 OS_GETPGRP_METHODDEF
12217 OS_GETPPID_METHODDEF
12218 OS_GETUID_METHODDEF
12219 OS_GETLOGIN_METHODDEF
12220 OS_KILL_METHODDEF
12221 OS_KILLPG_METHODDEF
12222 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012223#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012224 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012225#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012226 OS_SETUID_METHODDEF
12227 OS_SETEUID_METHODDEF
12228 OS_SETREUID_METHODDEF
12229 OS_SETGID_METHODDEF
12230 OS_SETEGID_METHODDEF
12231 OS_SETREGID_METHODDEF
12232 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012233#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012234 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012235#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012236 OS_GETPGID_METHODDEF
12237 OS_SETPGRP_METHODDEF
12238 OS_WAIT_METHODDEF
12239 OS_WAIT3_METHODDEF
12240 OS_WAIT4_METHODDEF
12241 OS_WAITID_METHODDEF
12242 OS_WAITPID_METHODDEF
12243 OS_GETSID_METHODDEF
12244 OS_SETSID_METHODDEF
12245 OS_SETPGID_METHODDEF
12246 OS_TCGETPGRP_METHODDEF
12247 OS_TCSETPGRP_METHODDEF
12248 OS_OPEN_METHODDEF
12249 OS_CLOSE_METHODDEF
12250 OS_CLOSERANGE_METHODDEF
12251 OS_DEVICE_ENCODING_METHODDEF
12252 OS_DUP_METHODDEF
12253 OS_DUP2_METHODDEF
12254 OS_LOCKF_METHODDEF
12255 OS_LSEEK_METHODDEF
12256 OS_READ_METHODDEF
12257 OS_READV_METHODDEF
12258 OS_PREAD_METHODDEF
12259 OS_WRITE_METHODDEF
12260 OS_WRITEV_METHODDEF
12261 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012262#ifdef HAVE_SENDFILE
12263 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12264 posix_sendfile__doc__},
12265#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012266 OS_FSTAT_METHODDEF
12267 OS_ISATTY_METHODDEF
12268 OS_PIPE_METHODDEF
12269 OS_PIPE2_METHODDEF
12270 OS_MKFIFO_METHODDEF
12271 OS_MKNOD_METHODDEF
12272 OS_MAJOR_METHODDEF
12273 OS_MINOR_METHODDEF
12274 OS_MAKEDEV_METHODDEF
12275 OS_FTRUNCATE_METHODDEF
12276 OS_TRUNCATE_METHODDEF
12277 OS_POSIX_FALLOCATE_METHODDEF
12278 OS_POSIX_FADVISE_METHODDEF
12279 OS_PUTENV_METHODDEF
12280 OS_UNSETENV_METHODDEF
12281 OS_STRERROR_METHODDEF
12282 OS_FCHDIR_METHODDEF
12283 OS_FSYNC_METHODDEF
12284 OS_SYNC_METHODDEF
12285 OS_FDATASYNC_METHODDEF
12286 OS_WCOREDUMP_METHODDEF
12287 OS_WIFCONTINUED_METHODDEF
12288 OS_WIFSTOPPED_METHODDEF
12289 OS_WIFSIGNALED_METHODDEF
12290 OS_WIFEXITED_METHODDEF
12291 OS_WEXITSTATUS_METHODDEF
12292 OS_WTERMSIG_METHODDEF
12293 OS_WSTOPSIG_METHODDEF
12294 OS_FSTATVFS_METHODDEF
12295 OS_STATVFS_METHODDEF
12296 OS_CONFSTR_METHODDEF
12297 OS_SYSCONF_METHODDEF
12298 OS_FPATHCONF_METHODDEF
12299 OS_PATHCONF_METHODDEF
12300 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012301 OS__GETFULLPATHNAME_METHODDEF
12302 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012303 OS__GETDISKUSAGE_METHODDEF
12304 OS__GETFINALPATHNAME_METHODDEF
12305 OS__GETVOLUMEPATHNAME_METHODDEF
12306 OS_GETLOADAVG_METHODDEF
12307 OS_URANDOM_METHODDEF
12308 OS_SETRESUID_METHODDEF
12309 OS_SETRESGID_METHODDEF
12310 OS_GETRESUID_METHODDEF
12311 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012312
Larry Hastings2f936352014-08-05 14:04:04 +100012313 OS_GETXATTR_METHODDEF
12314 OS_SETXATTR_METHODDEF
12315 OS_REMOVEXATTR_METHODDEF
12316 OS_LISTXATTR_METHODDEF
12317
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012318#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12319 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12320#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012321 OS_CPU_COUNT_METHODDEF
12322 OS_GET_INHERITABLE_METHODDEF
12323 OS_SET_INHERITABLE_METHODDEF
12324 OS_GET_HANDLE_INHERITABLE_METHODDEF
12325 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012326#ifndef MS_WINDOWS
12327 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12328 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12329#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012330 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012331 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012332 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012333 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012334};
12335
12336
Brian Curtin52173d42010-12-02 18:29:18 +000012337#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012338static int
Brian Curtin52173d42010-12-02 18:29:18 +000012339enable_symlink()
12340{
12341 HANDLE tok;
12342 TOKEN_PRIVILEGES tok_priv;
12343 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012344
12345 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012346 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012347
12348 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012349 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012350
12351 tok_priv.PrivilegeCount = 1;
12352 tok_priv.Privileges[0].Luid = luid;
12353 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12354
12355 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12356 sizeof(TOKEN_PRIVILEGES),
12357 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012358 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012359
Brian Curtin3b4499c2010-12-28 14:31:47 +000012360 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12361 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012362}
12363#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12364
Barry Warsaw4a342091996-12-19 23:50:02 +000012365static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012366all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012367{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012368#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012369 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012370#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012371#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012372 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012373#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012374#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012375 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012376#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012377#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012378 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012379#endif
Fred Drakec9680921999-12-13 16:37:25 +000012380#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012381 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012382#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012383#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012384 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012385#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012386#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012387 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012388#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012389#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012390 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012391#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012392#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012393 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012394#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012395#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012396 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012397#endif
12398#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012399 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012400#endif
12401#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012402 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012403#endif
12404#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012405 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012406#endif
12407#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012408 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012409#endif
12410#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012411 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012412#endif
12413#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012414 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012415#endif
12416#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012417 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012418#endif
12419#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012420 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012421#endif
12422#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012423 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012424#endif
12425#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012426 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012427#endif
12428#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012429 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012430#endif
12431#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012433#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012434#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012435 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012436#endif
12437#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012438 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012439#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012440#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012441 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012442#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012443#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012445#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012446#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012447#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012449#endif
12450#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012452#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012453#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012454#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012456#endif
12457#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012459#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012460#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012462#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012463#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012464 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012465#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012466#ifdef O_TMPFILE
12467 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12468#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012469#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012470 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012471#endif
12472#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012473 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012474#endif
12475#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012476 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012477#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012478#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012480#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012481#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012483#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012484
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012485
Jesus Cea94363612012-06-22 18:32:07 +020012486#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012487 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012488#endif
12489#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012490 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012491#endif
12492
Tim Peters5aa91602002-01-30 05:46:57 +000012493/* MS Windows */
12494#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012495 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012497#endif
12498#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012499 /* Optimize for short life (keep in memory). */
12500 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012501 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012502#endif
12503#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012504 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012505 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012506#endif
12507#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012508 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012509 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012510#endif
12511#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012512 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012513 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012514#endif
12515
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012516/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012517#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012518 /* Send a SIGIO signal whenever input or output
12519 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012520 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012521#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012522#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012523 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012525#endif
12526#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012527 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012528 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012529#endif
12530#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012531 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012532 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012533#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012534#ifdef O_NOLINKS
12535 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012536 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012537#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012538#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012539 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012540 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012541#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012542
Victor Stinner8c62be82010-05-06 00:08:46 +000012543 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012544#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012545 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012546#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012547#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012548 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012549#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012550#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012551 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012552#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012553#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012555#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012556#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012557 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012558#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012559#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012560 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012561#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012562#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012563 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012564#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012565#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012567#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012568#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012569 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012570#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012571#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012573#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012574#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012576#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012577#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012578 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012579#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012580#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012581 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012582#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012583#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012584 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012585#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012586#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012587 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012588#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012589#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012591#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012592#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012594#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012595
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012596 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012597#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012599#endif /* ST_RDONLY */
12600#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012601 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012602#endif /* ST_NOSUID */
12603
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012604 /* GNU extensions */
12605#ifdef ST_NODEV
12606 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12607#endif /* ST_NODEV */
12608#ifdef ST_NOEXEC
12609 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12610#endif /* ST_NOEXEC */
12611#ifdef ST_SYNCHRONOUS
12612 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12613#endif /* ST_SYNCHRONOUS */
12614#ifdef ST_MANDLOCK
12615 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12616#endif /* ST_MANDLOCK */
12617#ifdef ST_WRITE
12618 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12619#endif /* ST_WRITE */
12620#ifdef ST_APPEND
12621 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12622#endif /* ST_APPEND */
12623#ifdef ST_NOATIME
12624 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12625#endif /* ST_NOATIME */
12626#ifdef ST_NODIRATIME
12627 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12628#endif /* ST_NODIRATIME */
12629#ifdef ST_RELATIME
12630 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12631#endif /* ST_RELATIME */
12632
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012633 /* FreeBSD sendfile() constants */
12634#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012636#endif
12637#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012639#endif
12640#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012642#endif
12643
Ross Lagerwall7807c352011-03-17 20:20:30 +020012644 /* constants for posix_fadvise */
12645#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012647#endif
12648#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012649 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012650#endif
12651#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012653#endif
12654#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012656#endif
12657#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012659#endif
12660#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012662#endif
12663
12664 /* constants for waitid */
12665#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012666 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12667 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12668 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012669#endif
12670#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012672#endif
12673#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012675#endif
12676#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012678#endif
12679#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012681#endif
12682#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684#endif
12685#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691
12692 /* constants for lockf */
12693#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012695#endif
12696#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012698#endif
12699#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012701#endif
12702#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012704#endif
12705
Guido van Rossum246bc171999-02-01 23:54:31 +000012706#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12708 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12709 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12710 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12711 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012712#endif
12713
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012714#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012715#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012717#endif
12718#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012719 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012720#endif
12721#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012722 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012723#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012724#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012726#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012727#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012729#endif
12730#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012732#endif
12733#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012735#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012736#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012738#endif
12739#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012741#endif
12742#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012744#endif
12745#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012747#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012748#endif
12749
Benjamin Peterson9428d532011-09-14 11:45:52 -040012750#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012751 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12752 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12753 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012754#endif
12755
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012756#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012758#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012759#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012761#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012762#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012764#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012765#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012767#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012768#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012770#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012771#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012773#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012774#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012776#endif
12777
Victor Stinner9b1f4742016-09-06 16:18:52 -070012778#ifdef HAVE_GETRANDOM_SYSCALL
12779 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12780 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12781#endif
12782
Victor Stinner8c62be82010-05-06 00:08:46 +000012783 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012784}
12785
12786
Martin v. Löwis1a214512008-06-11 05:26:20 +000012787static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012788 PyModuleDef_HEAD_INIT,
12789 MODNAME,
12790 posix__doc__,
12791 -1,
12792 posix_methods,
12793 NULL,
12794 NULL,
12795 NULL,
12796 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012797};
12798
12799
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012800static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012801
12802#ifdef HAVE_FACCESSAT
12803 "HAVE_FACCESSAT",
12804#endif
12805
12806#ifdef HAVE_FCHDIR
12807 "HAVE_FCHDIR",
12808#endif
12809
12810#ifdef HAVE_FCHMOD
12811 "HAVE_FCHMOD",
12812#endif
12813
12814#ifdef HAVE_FCHMODAT
12815 "HAVE_FCHMODAT",
12816#endif
12817
12818#ifdef HAVE_FCHOWN
12819 "HAVE_FCHOWN",
12820#endif
12821
Larry Hastings00964ed2013-08-12 13:49:30 -040012822#ifdef HAVE_FCHOWNAT
12823 "HAVE_FCHOWNAT",
12824#endif
12825
Larry Hastings9cf065c2012-06-22 16:30:09 -070012826#ifdef HAVE_FEXECVE
12827 "HAVE_FEXECVE",
12828#endif
12829
12830#ifdef HAVE_FDOPENDIR
12831 "HAVE_FDOPENDIR",
12832#endif
12833
Georg Brandl306336b2012-06-24 12:55:33 +020012834#ifdef HAVE_FPATHCONF
12835 "HAVE_FPATHCONF",
12836#endif
12837
Larry Hastings9cf065c2012-06-22 16:30:09 -070012838#ifdef HAVE_FSTATAT
12839 "HAVE_FSTATAT",
12840#endif
12841
12842#ifdef HAVE_FSTATVFS
12843 "HAVE_FSTATVFS",
12844#endif
12845
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012846#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012847 "HAVE_FTRUNCATE",
12848#endif
12849
Larry Hastings9cf065c2012-06-22 16:30:09 -070012850#ifdef HAVE_FUTIMENS
12851 "HAVE_FUTIMENS",
12852#endif
12853
12854#ifdef HAVE_FUTIMES
12855 "HAVE_FUTIMES",
12856#endif
12857
12858#ifdef HAVE_FUTIMESAT
12859 "HAVE_FUTIMESAT",
12860#endif
12861
12862#ifdef HAVE_LINKAT
12863 "HAVE_LINKAT",
12864#endif
12865
12866#ifdef HAVE_LCHFLAGS
12867 "HAVE_LCHFLAGS",
12868#endif
12869
12870#ifdef HAVE_LCHMOD
12871 "HAVE_LCHMOD",
12872#endif
12873
12874#ifdef HAVE_LCHOWN
12875 "HAVE_LCHOWN",
12876#endif
12877
12878#ifdef HAVE_LSTAT
12879 "HAVE_LSTAT",
12880#endif
12881
12882#ifdef HAVE_LUTIMES
12883 "HAVE_LUTIMES",
12884#endif
12885
12886#ifdef HAVE_MKDIRAT
12887 "HAVE_MKDIRAT",
12888#endif
12889
12890#ifdef HAVE_MKFIFOAT
12891 "HAVE_MKFIFOAT",
12892#endif
12893
12894#ifdef HAVE_MKNODAT
12895 "HAVE_MKNODAT",
12896#endif
12897
12898#ifdef HAVE_OPENAT
12899 "HAVE_OPENAT",
12900#endif
12901
12902#ifdef HAVE_READLINKAT
12903 "HAVE_READLINKAT",
12904#endif
12905
12906#ifdef HAVE_RENAMEAT
12907 "HAVE_RENAMEAT",
12908#endif
12909
12910#ifdef HAVE_SYMLINKAT
12911 "HAVE_SYMLINKAT",
12912#endif
12913
12914#ifdef HAVE_UNLINKAT
12915 "HAVE_UNLINKAT",
12916#endif
12917
12918#ifdef HAVE_UTIMENSAT
12919 "HAVE_UTIMENSAT",
12920#endif
12921
12922#ifdef MS_WINDOWS
12923 "MS_WINDOWS",
12924#endif
12925
12926 NULL
12927};
12928
12929
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012930PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012931INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012932{
Victor Stinner8c62be82010-05-06 00:08:46 +000012933 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012934 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012935 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012936
Brian Curtin52173d42010-12-02 18:29:18 +000012937#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012938 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012939#endif
12940
Victor Stinner8c62be82010-05-06 00:08:46 +000012941 m = PyModule_Create(&posixmodule);
12942 if (m == NULL)
12943 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012944
Victor Stinner8c62be82010-05-06 00:08:46 +000012945 /* Initialize environ dictionary */
12946 v = convertenviron();
12947 Py_XINCREF(v);
12948 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12949 return NULL;
12950 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012951
Victor Stinner8c62be82010-05-06 00:08:46 +000012952 if (all_ins(m))
12953 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012954
Victor Stinner8c62be82010-05-06 00:08:46 +000012955 if (setup_confname_tables(m))
12956 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012957
Victor Stinner8c62be82010-05-06 00:08:46 +000012958 Py_INCREF(PyExc_OSError);
12959 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012960
Guido van Rossumb3d39562000-01-31 18:41:26 +000012961#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012962 if (posix_putenv_garbage == NULL)
12963 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012964#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012965
Victor Stinner8c62be82010-05-06 00:08:46 +000012966 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012967#if defined(HAVE_WAITID) && !defined(__APPLE__)
12968 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012969 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12970 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012971#endif
12972
Christian Heimes25827622013-10-12 01:27:08 +020012973 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012974 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12975 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12976 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012977 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12978 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 structseq_new = StatResultType.tp_new;
12980 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012981
Christian Heimes25827622013-10-12 01:27:08 +020012982 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012983 if (PyStructSequence_InitType2(&StatVFSResultType,
12984 &statvfs_result_desc) < 0)
12985 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012986#ifdef NEED_TICKS_PER_SECOND
12987# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012988 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012989# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012990 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012991# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012992 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012993# endif
12994#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012995
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012996#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012997 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012998 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12999 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013000 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013001#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013002
13003 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013004 if (PyStructSequence_InitType2(&TerminalSizeType,
13005 &TerminalSize_desc) < 0)
13006 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013007
13008 /* initialize scandir types */
13009 if (PyType_Ready(&ScandirIteratorType) < 0)
13010 return NULL;
13011 if (PyType_Ready(&DirEntryType) < 0)
13012 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013014#if defined(HAVE_WAITID) && !defined(__APPLE__)
13015 Py_INCREF((PyObject*) &WaitidResultType);
13016 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13017#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013018 Py_INCREF((PyObject*) &StatResultType);
13019 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13020 Py_INCREF((PyObject*) &StatVFSResultType);
13021 PyModule_AddObject(m, "statvfs_result",
13022 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013023
13024#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013025 Py_INCREF(&SchedParamType);
13026 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013027#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013028
Larry Hastings605a62d2012-06-24 04:33:36 -070013029 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013030 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13031 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013032 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13033
13034 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013035 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13036 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013037 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13038
Thomas Wouters477c8d52006-05-27 19:21:47 +000013039#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013040 /*
13041 * Step 2 of weak-linking support on Mac OS X.
13042 *
13043 * The code below removes functions that are not available on the
13044 * currently active platform.
13045 *
13046 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013047 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013048 * OSX 10.4.
13049 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013050#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013051 if (fstatvfs == NULL) {
13052 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13053 return NULL;
13054 }
13055 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013056#endif /* HAVE_FSTATVFS */
13057
13058#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013059 if (statvfs == NULL) {
13060 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13061 return NULL;
13062 }
13063 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013064#endif /* HAVE_STATVFS */
13065
13066# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013067 if (lchown == NULL) {
13068 if (PyObject_DelAttrString(m, "lchown") == -1) {
13069 return NULL;
13070 }
13071 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013072#endif /* HAVE_LCHOWN */
13073
13074
13075#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013076
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013077 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013078 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13079
Larry Hastings6fe20b32012-04-19 15:07:49 -070013080 billion = PyLong_FromLong(1000000000);
13081 if (!billion)
13082 return NULL;
13083
Larry Hastings9cf065c2012-06-22 16:30:09 -070013084 /* suppress "function not used" warnings */
13085 {
13086 int ignored;
13087 fd_specified("", -1);
13088 follow_symlinks_specified("", 1);
13089 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13090 dir_fd_converter(Py_None, &ignored);
13091 dir_fd_unavailable(Py_None, &ignored);
13092 }
13093
13094 /*
13095 * provide list of locally available functions
13096 * so os.py can populate support_* lists
13097 */
13098 list = PyList_New(0);
13099 if (!list)
13100 return NULL;
13101 for (trace = have_functions; *trace; trace++) {
13102 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13103 if (!unicode)
13104 return NULL;
13105 if (PyList_Append(list, unicode))
13106 return NULL;
13107 Py_DECREF(unicode);
13108 }
13109 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013110
13111 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013112 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013113
13114 initialized = 1;
13115
Victor Stinner8c62be82010-05-06 00:08:46 +000013116 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013117}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013118
13119#ifdef __cplusplus
13120}
13121#endif