blob: e8c15a9473cfb1a64ac7192578f25d09eb13620d [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{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006645 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 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);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006653 if (len < 0) {
6654 return NULL;
6655 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 if (len > MAX_GROUPS) {
6657 PyErr_SetString(PyExc_ValueError, "too many groups");
6658 return NULL;
6659 }
6660 for(i = 0; i < len; i++) {
6661 PyObject *elem;
6662 elem = PySequence_GetItem(groups, i);
6663 if (!elem)
6664 return NULL;
6665 if (!PyLong_Check(elem)) {
6666 PyErr_SetString(PyExc_TypeError,
6667 "groups must be integers");
6668 Py_DECREF(elem);
6669 return NULL;
6670 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006671 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006672 Py_DECREF(elem);
6673 return NULL;
6674 }
6675 }
6676 Py_DECREF(elem);
6677 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006678
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 if (setgroups(len, grouplist) < 0)
6680 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006681 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006682}
6683#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006684
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006685#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6686static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006687wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006688{
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 PyObject *result;
6690 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006691 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006692
Victor Stinner8c62be82010-05-06 00:08:46 +00006693 if (pid == -1)
6694 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006695
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 if (struct_rusage == NULL) {
6697 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6698 if (m == NULL)
6699 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006700 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 Py_DECREF(m);
6702 if (struct_rusage == NULL)
6703 return NULL;
6704 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006705
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6707 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6708 if (!result)
6709 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006710
6711#ifndef doubletime
6712#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6713#endif
6714
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006716 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006718 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006719#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6721 SET_INT(result, 2, ru->ru_maxrss);
6722 SET_INT(result, 3, ru->ru_ixrss);
6723 SET_INT(result, 4, ru->ru_idrss);
6724 SET_INT(result, 5, ru->ru_isrss);
6725 SET_INT(result, 6, ru->ru_minflt);
6726 SET_INT(result, 7, ru->ru_majflt);
6727 SET_INT(result, 8, ru->ru_nswap);
6728 SET_INT(result, 9, ru->ru_inblock);
6729 SET_INT(result, 10, ru->ru_oublock);
6730 SET_INT(result, 11, ru->ru_msgsnd);
6731 SET_INT(result, 12, ru->ru_msgrcv);
6732 SET_INT(result, 13, ru->ru_nsignals);
6733 SET_INT(result, 14, ru->ru_nvcsw);
6734 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006735#undef SET_INT
6736
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 if (PyErr_Occurred()) {
6738 Py_DECREF(result);
6739 return NULL;
6740 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006741
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006743}
6744#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6745
Larry Hastings2f936352014-08-05 14:04:04 +10006746
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006747#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006748/*[clinic input]
6749os.wait3
6750
6751 options: int
6752Wait for completion of a child process.
6753
6754Returns a tuple of information about the child process:
6755 (pid, status, rusage)
6756[clinic start generated code]*/
6757
Larry Hastings2f936352014-08-05 14:04:04 +10006758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006759os_wait3_impl(PyObject *module, int options)
6760/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006761{
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006764 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 WAIT_TYPE status;
6766 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006767
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006768 do {
6769 Py_BEGIN_ALLOW_THREADS
6770 pid = wait3(&status, options, &ru);
6771 Py_END_ALLOW_THREADS
6772 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6773 if (pid < 0)
6774 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006775
Victor Stinner4195b5c2012-02-08 23:03:19 +01006776 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006777}
6778#endif /* HAVE_WAIT3 */
6779
Larry Hastings2f936352014-08-05 14:04:04 +10006780
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006781#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006782/*[clinic input]
6783
6784os.wait4
6785
6786 pid: pid_t
6787 options: int
6788
6789Wait for completion of a specific child process.
6790
6791Returns a tuple of information about the child process:
6792 (pid, status, rusage)
6793[clinic start generated code]*/
6794
Larry Hastings2f936352014-08-05 14:04:04 +10006795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006796os_wait4_impl(PyObject *module, pid_t pid, int options)
6797/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006798{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006799 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006801 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 WAIT_TYPE status;
6803 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006804
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006805 do {
6806 Py_BEGIN_ALLOW_THREADS
6807 res = wait4(pid, &status, options, &ru);
6808 Py_END_ALLOW_THREADS
6809 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6810 if (res < 0)
6811 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006812
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006813 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006814}
6815#endif /* HAVE_WAIT4 */
6816
Larry Hastings2f936352014-08-05 14:04:04 +10006817
Ross Lagerwall7807c352011-03-17 20:20:30 +02006818#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006819/*[clinic input]
6820os.waitid
6821
6822 idtype: idtype_t
6823 Must be one of be P_PID, P_PGID or P_ALL.
6824 id: id_t
6825 The id to wait on.
6826 options: int
6827 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6828 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6829 /
6830
6831Returns the result of waiting for a process or processes.
6832
6833Returns either waitid_result or None if WNOHANG is specified and there are
6834no children in a waitable state.
6835[clinic start generated code]*/
6836
Larry Hastings2f936352014-08-05 14:04:04 +10006837static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006838os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6839/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006840{
6841 PyObject *result;
6842 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006843 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006844 siginfo_t si;
6845 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006846
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006847 do {
6848 Py_BEGIN_ALLOW_THREADS
6849 res = waitid(idtype, id, &si, options);
6850 Py_END_ALLOW_THREADS
6851 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6852 if (res < 0)
6853 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006854
6855 if (si.si_pid == 0)
6856 Py_RETURN_NONE;
6857
6858 result = PyStructSequence_New(&WaitidResultType);
6859 if (!result)
6860 return NULL;
6861
6862 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006863 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006864 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6865 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6866 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6867 if (PyErr_Occurred()) {
6868 Py_DECREF(result);
6869 return NULL;
6870 }
6871
6872 return result;
6873}
Larry Hastings2f936352014-08-05 14:04:04 +10006874#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006875
Larry Hastings2f936352014-08-05 14:04:04 +10006876
6877#if defined(HAVE_WAITPID)
6878/*[clinic input]
6879os.waitpid
6880 pid: pid_t
6881 options: int
6882 /
6883
6884Wait for completion of a given child process.
6885
6886Returns a tuple of information regarding the child process:
6887 (pid, status)
6888
6889The options argument is ignored on Windows.
6890[clinic start generated code]*/
6891
Larry Hastings2f936352014-08-05 14:04:04 +10006892static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006893os_waitpid_impl(PyObject *module, pid_t pid, int options)
6894/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006895{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006896 pid_t res;
6897 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 WAIT_TYPE status;
6899 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006900
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006901 do {
6902 Py_BEGIN_ALLOW_THREADS
6903 res = waitpid(pid, &status, options);
6904 Py_END_ALLOW_THREADS
6905 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6906 if (res < 0)
6907 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006908
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006909 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006910}
Tim Petersab034fa2002-02-01 11:27:43 +00006911#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006912/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006913/*[clinic input]
6914os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006915 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006916 options: int
6917 /
6918
6919Wait for completion of a given process.
6920
6921Returns a tuple of information regarding the process:
6922 (pid, status << 8)
6923
6924The options argument is ignored on Windows.
6925[clinic start generated code]*/
6926
Larry Hastings2f936352014-08-05 14:04:04 +10006927static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006928os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006929/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006930{
6931 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006932 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006933 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 do {
6936 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006937 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006938 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006939 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006940 Py_END_ALLOW_THREADS
6941 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006942 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006943 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006944
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006947}
Larry Hastings2f936352014-08-05 14:04:04 +10006948#endif
6949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006950
Guido van Rossumad0ee831995-03-01 10:34:45 +00006951#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006952/*[clinic input]
6953os.wait
6954
6955Wait for completion of a child process.
6956
6957Returns a tuple of information about the child process:
6958 (pid, status)
6959[clinic start generated code]*/
6960
Larry Hastings2f936352014-08-05 14:04:04 +10006961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006962os_wait_impl(PyObject *module)
6963/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006964{
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006966 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 WAIT_TYPE status;
6968 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006969
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006970 do {
6971 Py_BEGIN_ALLOW_THREADS
6972 pid = wait(&status);
6973 Py_END_ALLOW_THREADS
6974 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6975 if (pid < 0)
6976 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006977
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006979}
Larry Hastings2f936352014-08-05 14:04:04 +10006980#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006982
Larry Hastings9cf065c2012-06-22 16:30:09 -07006983#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6984PyDoc_STRVAR(readlink__doc__,
6985"readlink(path, *, dir_fd=None) -> path\n\n\
6986Return a string representing the path to which the symbolic link points.\n\
6987\n\
6988If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6989 and path should be relative; path will then be relative to that directory.\n\
6990dir_fd may not be implemented on your platform.\n\
6991 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006992#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006993
Guido van Rossumb6775db1994-08-01 11:34:53 +00006994#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006995
Larry Hastings2f936352014-08-05 14:04:04 +10006996/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006997static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006998posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006999{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007000 path_t path;
7001 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007002 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007003 ssize_t length;
7004 PyObject *return_value = NULL;
7005 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007006
Larry Hastings9cf065c2012-06-22 16:30:09 -07007007 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007008 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007009 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7010 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007011 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007013
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007015#ifdef HAVE_READLINKAT
7016 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007017 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007018 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007019#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007020 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007021 Py_END_ALLOW_THREADS
7022
7023 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007024 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007025 goto exit;
7026 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007027 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007028
7029 if (PyUnicode_Check(path.object))
7030 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7031 else
7032 return_value = PyBytes_FromStringAndSize(buffer, length);
7033exit:
7034 path_cleanup(&path);
7035 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007036}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007037
Guido van Rossumb6775db1994-08-01 11:34:53 +00007038#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007039
Larry Hastings2f936352014-08-05 14:04:04 +10007040#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7041
7042static PyObject *
7043win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7044{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007045 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007046 DWORD n_bytes_returned;
7047 DWORD io_result;
7048 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007049 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007050 HANDLE reparse_point_handle;
7051
Martin Panter70214ad2016-08-04 02:38:59 +00007052 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7053 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007054 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007055
7056 static char *keywords[] = {"path", "dir_fd", NULL};
7057
7058 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7059 &po,
7060 dir_fd_unavailable, &dir_fd
7061 ))
7062 return NULL;
7063
7064 path = PyUnicode_AsUnicode(po);
7065 if (path == NULL)
7066 return NULL;
7067
7068 /* First get a handle to the reparse point */
7069 Py_BEGIN_ALLOW_THREADS
7070 reparse_point_handle = CreateFileW(
7071 path,
7072 0,
7073 0,
7074 0,
7075 OPEN_EXISTING,
7076 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7077 0);
7078 Py_END_ALLOW_THREADS
7079
7080 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7081 return win32_error_object("readlink", po);
7082
7083 Py_BEGIN_ALLOW_THREADS
7084 /* New call DeviceIoControl to read the reparse point */
7085 io_result = DeviceIoControl(
7086 reparse_point_handle,
7087 FSCTL_GET_REPARSE_POINT,
7088 0, 0, /* in buffer */
7089 target_buffer, sizeof(target_buffer),
7090 &n_bytes_returned,
7091 0 /* we're not using OVERLAPPED_IO */
7092 );
7093 CloseHandle(reparse_point_handle);
7094 Py_END_ALLOW_THREADS
7095
7096 if (io_result==0)
7097 return win32_error_object("readlink", po);
7098
7099 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7100 {
7101 PyErr_SetString(PyExc_ValueError,
7102 "not a symbolic link");
7103 return NULL;
7104 }
7105 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7106 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7107
7108 result = PyUnicode_FromWideChar(print_name,
7109 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7110 return result;
7111}
7112
7113#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7114
7115
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007116
Larry Hastings9cf065c2012-06-22 16:30:09 -07007117#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118
7119#if defined(MS_WINDOWS)
7120
7121/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007122static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007123
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007125check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126{
7127 HINSTANCE hKernel32;
7128 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007129 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130 return 1;
7131 hKernel32 = GetModuleHandleW(L"KERNEL32");
7132 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7133 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007134 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135}
7136
Victor Stinner31b3b922013-06-05 01:49:17 +02007137/* Remove the last portion of the path */
7138static void
7139_dirnameW(WCHAR *path)
7140{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007141 WCHAR *ptr;
7142
7143 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007144 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007145 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007146 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007147 }
7148 *ptr = 0;
7149}
7150
Victor Stinner31b3b922013-06-05 01:49:17 +02007151/* Is this path absolute? */
7152static int
7153_is_absW(const WCHAR *path)
7154{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007155 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7156
7157}
7158
Victor Stinner31b3b922013-06-05 01:49:17 +02007159/* join root and rest with a backslash */
7160static void
7161_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7162{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007163 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007164
Victor Stinner31b3b922013-06-05 01:49:17 +02007165 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007166 wcscpy(dest_path, rest);
7167 return;
7168 }
7169
7170 root_len = wcslen(root);
7171
7172 wcscpy(dest_path, root);
7173 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007174 dest_path[root_len] = L'\\';
7175 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007176 }
7177 wcscpy(dest_path+root_len, rest);
7178}
7179
Victor Stinner31b3b922013-06-05 01:49:17 +02007180/* Return True if the path at src relative to dest is a directory */
7181static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007182_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007183{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007184 WIN32_FILE_ATTRIBUTE_DATA src_info;
7185 WCHAR dest_parent[MAX_PATH];
7186 WCHAR src_resolved[MAX_PATH] = L"";
7187
7188 /* dest_parent = os.path.dirname(dest) */
7189 wcscpy(dest_parent, dest);
7190 _dirnameW(dest_parent);
7191 /* src_resolved = os.path.join(dest_parent, src) */
7192 _joinW(src_resolved, dest_parent, src);
7193 return (
7194 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7195 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7196 );
7197}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007198#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007199
Larry Hastings2f936352014-08-05 14:04:04 +10007200
7201/*[clinic input]
7202os.symlink
7203 src: path_t
7204 dst: path_t
7205 target_is_directory: bool = False
7206 *
7207 dir_fd: dir_fd(requires='symlinkat')=None
7208
7209# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7210
7211Create a symbolic link pointing to src named dst.
7212
7213target_is_directory is required on Windows if the target is to be
7214 interpreted as a directory. (On Windows, symlink requires
7215 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7216 target_is_directory is ignored on non-Windows platforms.
7217
7218If dir_fd is not None, it should be a file descriptor open to a directory,
7219 and path should be relative; path will then be relative to that directory.
7220dir_fd may not be implemented on your platform.
7221 If it is unavailable, using it will raise a NotImplementedError.
7222
7223[clinic start generated code]*/
7224
Larry Hastings2f936352014-08-05 14:04:04 +10007225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007226os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007227 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007228/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007229{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007230#ifdef MS_WINDOWS
7231 DWORD result;
7232#else
7233 int result;
7234#endif
7235
Larry Hastings9cf065c2012-06-22 16:30:09 -07007236#ifdef MS_WINDOWS
7237 if (!check_CreateSymbolicLink()) {
7238 PyErr_SetString(PyExc_NotImplementedError,
7239 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007240 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007241 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007242 if (!win32_can_symlink) {
7243 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007244 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007245 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007246#endif
7247
Larry Hastings2f936352014-08-05 14:04:04 +10007248 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007249 PyErr_SetString(PyExc_ValueError,
7250 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007251 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007252 }
7253
7254#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007255
Larry Hastings9cf065c2012-06-22 16:30:09 -07007256 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007257 /* if src is a directory, ensure target_is_directory==1 */
7258 target_is_directory |= _check_dirW(src->wide, dst->wide);
7259 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7260 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007261 Py_END_ALLOW_THREADS
7262
Larry Hastings2f936352014-08-05 14:04:04 +10007263 if (!result)
7264 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007265
7266#else
7267
7268 Py_BEGIN_ALLOW_THREADS
7269#if HAVE_SYMLINKAT
7270 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007271 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007272 else
7273#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007274 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275 Py_END_ALLOW_THREADS
7276
Larry Hastings2f936352014-08-05 14:04:04 +10007277 if (result)
7278 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007279#endif
7280
Larry Hastings2f936352014-08-05 14:04:04 +10007281 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007282}
7283#endif /* HAVE_SYMLINK */
7284
Larry Hastings9cf065c2012-06-22 16:30:09 -07007285
Brian Curtind40e6f72010-07-08 21:39:08 +00007286
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007287
Larry Hastings605a62d2012-06-24 04:33:36 -07007288static PyStructSequence_Field times_result_fields[] = {
7289 {"user", "user time"},
7290 {"system", "system time"},
7291 {"children_user", "user time of children"},
7292 {"children_system", "system time of children"},
7293 {"elapsed", "elapsed time since an arbitrary point in the past"},
7294 {NULL}
7295};
7296
7297PyDoc_STRVAR(times_result__doc__,
7298"times_result: Result from os.times().\n\n\
7299This object may be accessed either as a tuple of\n\
7300 (user, system, children_user, children_system, elapsed),\n\
7301or via the attributes user, system, children_user, children_system,\n\
7302and elapsed.\n\
7303\n\
7304See os.times for more information.");
7305
7306static PyStructSequence_Desc times_result_desc = {
7307 "times_result", /* name */
7308 times_result__doc__, /* doc */
7309 times_result_fields,
7310 5
7311};
7312
7313static PyTypeObject TimesResultType;
7314
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007315#ifdef MS_WINDOWS
7316#define HAVE_TIMES /* mandatory, for the method table */
7317#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007318
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007319#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007320
7321static PyObject *
7322build_times_result(double user, double system,
7323 double children_user, double children_system,
7324 double elapsed)
7325{
7326 PyObject *value = PyStructSequence_New(&TimesResultType);
7327 if (value == NULL)
7328 return NULL;
7329
7330#define SET(i, field) \
7331 { \
7332 PyObject *o = PyFloat_FromDouble(field); \
7333 if (!o) { \
7334 Py_DECREF(value); \
7335 return NULL; \
7336 } \
7337 PyStructSequence_SET_ITEM(value, i, o); \
7338 } \
7339
7340 SET(0, user);
7341 SET(1, system);
7342 SET(2, children_user);
7343 SET(3, children_system);
7344 SET(4, elapsed);
7345
7346#undef SET
7347
7348 return value;
7349}
7350
Larry Hastings605a62d2012-06-24 04:33:36 -07007351
Larry Hastings2f936352014-08-05 14:04:04 +10007352#ifndef MS_WINDOWS
7353#define NEED_TICKS_PER_SECOND
7354static long ticks_per_second = -1;
7355#endif /* MS_WINDOWS */
7356
7357/*[clinic input]
7358os.times
7359
7360Return a collection containing process timing information.
7361
7362The object returned behaves like a named tuple with these fields:
7363 (utime, stime, cutime, cstime, elapsed_time)
7364All fields are floating point numbers.
7365[clinic start generated code]*/
7366
Larry Hastings2f936352014-08-05 14:04:04 +10007367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007368os_times_impl(PyObject *module)
7369/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007370#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007371{
Victor Stinner8c62be82010-05-06 00:08:46 +00007372 FILETIME create, exit, kernel, user;
7373 HANDLE hProc;
7374 hProc = GetCurrentProcess();
7375 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7376 /* The fields of a FILETIME structure are the hi and lo part
7377 of a 64-bit value expressed in 100 nanosecond units.
7378 1e7 is one second in such units; 1e-7 the inverse.
7379 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7380 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007381 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007382 (double)(user.dwHighDateTime*429.4967296 +
7383 user.dwLowDateTime*1e-7),
7384 (double)(kernel.dwHighDateTime*429.4967296 +
7385 kernel.dwLowDateTime*1e-7),
7386 (double)0,
7387 (double)0,
7388 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007389}
Larry Hastings2f936352014-08-05 14:04:04 +10007390#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007391{
Larry Hastings2f936352014-08-05 14:04:04 +10007392
7393
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007394 struct tms t;
7395 clock_t c;
7396 errno = 0;
7397 c = times(&t);
7398 if (c == (clock_t) -1)
7399 return posix_error();
7400 return build_times_result(
7401 (double)t.tms_utime / ticks_per_second,
7402 (double)t.tms_stime / ticks_per_second,
7403 (double)t.tms_cutime / ticks_per_second,
7404 (double)t.tms_cstime / ticks_per_second,
7405 (double)c / ticks_per_second);
7406}
Larry Hastings2f936352014-08-05 14:04:04 +10007407#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007408#endif /* HAVE_TIMES */
7409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007410
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007411#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007412/*[clinic input]
7413os.getsid
7414
7415 pid: pid_t
7416 /
7417
7418Call the system call getsid(pid) and return the result.
7419[clinic start generated code]*/
7420
Larry Hastings2f936352014-08-05 14:04:04 +10007421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007422os_getsid_impl(PyObject *module, pid_t pid)
7423/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007424{
Victor Stinner8c62be82010-05-06 00:08:46 +00007425 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 sid = getsid(pid);
7427 if (sid < 0)
7428 return posix_error();
7429 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007430}
7431#endif /* HAVE_GETSID */
7432
7433
Guido van Rossumb6775db1994-08-01 11:34:53 +00007434#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007435/*[clinic input]
7436os.setsid
7437
7438Call the system call setsid().
7439[clinic start generated code]*/
7440
Larry Hastings2f936352014-08-05 14:04:04 +10007441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007442os_setsid_impl(PyObject *module)
7443/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007444{
Victor Stinner8c62be82010-05-06 00:08:46 +00007445 if (setsid() < 0)
7446 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007447 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007448}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007449#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007450
Larry Hastings2f936352014-08-05 14:04:04 +10007451
Guido van Rossumb6775db1994-08-01 11:34:53 +00007452#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007453/*[clinic input]
7454os.setpgid
7455
7456 pid: pid_t
7457 pgrp: pid_t
7458 /
7459
7460Call the system call setpgid(pid, pgrp).
7461[clinic start generated code]*/
7462
Larry Hastings2f936352014-08-05 14:04:04 +10007463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007464os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7465/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007466{
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 if (setpgid(pid, pgrp) < 0)
7468 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007469 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007470}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007471#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007472
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007473
Guido van Rossumb6775db1994-08-01 11:34:53 +00007474#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007475/*[clinic input]
7476os.tcgetpgrp
7477
7478 fd: int
7479 /
7480
7481Return the process group associated with the terminal specified by fd.
7482[clinic start generated code]*/
7483
Larry Hastings2f936352014-08-05 14:04:04 +10007484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007485os_tcgetpgrp_impl(PyObject *module, int fd)
7486/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007487{
7488 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007489 if (pgid < 0)
7490 return posix_error();
7491 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007492}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007493#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007494
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007495
Guido van Rossumb6775db1994-08-01 11:34:53 +00007496#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007497/*[clinic input]
7498os.tcsetpgrp
7499
7500 fd: int
7501 pgid: pid_t
7502 /
7503
7504Set the process group associated with the terminal specified by fd.
7505[clinic start generated code]*/
7506
Larry Hastings2f936352014-08-05 14:04:04 +10007507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007508os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7509/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007510{
Victor Stinner8c62be82010-05-06 00:08:46 +00007511 if (tcsetpgrp(fd, pgid) < 0)
7512 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007513 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007514}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007515#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007516
Guido van Rossum687dd131993-05-17 08:34:16 +00007517/* Functions acting on file descriptors */
7518
Victor Stinnerdaf45552013-08-28 00:53:59 +02007519#ifdef O_CLOEXEC
7520extern int _Py_open_cloexec_works;
7521#endif
7522
Larry Hastings2f936352014-08-05 14:04:04 +10007523
7524/*[clinic input]
7525os.open -> int
7526 path: path_t
7527 flags: int
7528 mode: int = 0o777
7529 *
7530 dir_fd: dir_fd(requires='openat') = None
7531
7532# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7533
7534Open a file for low level IO. Returns a file descriptor (integer).
7535
7536If dir_fd is not None, it should be a file descriptor open to a directory,
7537 and path should be relative; path will then be relative to that directory.
7538dir_fd may not be implemented on your platform.
7539 If it is unavailable, using it will raise a NotImplementedError.
7540[clinic start generated code]*/
7541
Larry Hastings2f936352014-08-05 14:04:04 +10007542static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007543os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7544/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007545{
7546 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007547 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007548
Victor Stinnerdaf45552013-08-28 00:53:59 +02007549#ifdef O_CLOEXEC
7550 int *atomic_flag_works = &_Py_open_cloexec_works;
7551#elif !defined(MS_WINDOWS)
7552 int *atomic_flag_works = NULL;
7553#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007554
Victor Stinnerdaf45552013-08-28 00:53:59 +02007555#ifdef MS_WINDOWS
7556 flags |= O_NOINHERIT;
7557#elif defined(O_CLOEXEC)
7558 flags |= O_CLOEXEC;
7559#endif
7560
Steve Dower8fc89802015-04-12 00:26:27 -04007561 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007562 do {
7563 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007564#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007565 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007566#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007567#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007568 if (dir_fd != DEFAULT_DIR_FD)
7569 fd = openat(dir_fd, path->narrow, flags, mode);
7570 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007571#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007572 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007573#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007574 Py_END_ALLOW_THREADS
7575 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007576 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007577
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007578 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007579 if (!async_err)
7580 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007581 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007582 }
7583
Victor Stinnerdaf45552013-08-28 00:53:59 +02007584#ifndef MS_WINDOWS
7585 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7586 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007587 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007588 }
7589#endif
7590
Larry Hastings2f936352014-08-05 14:04:04 +10007591 return fd;
7592}
7593
7594
7595/*[clinic input]
7596os.close
7597
7598 fd: int
7599
7600Close a file descriptor.
7601[clinic start generated code]*/
7602
Barry Warsaw53699e91996-12-10 23:23:01 +00007603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007604os_close_impl(PyObject *module, int fd)
7605/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007606{
Larry Hastings2f936352014-08-05 14:04:04 +10007607 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007608 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7609 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7610 * for more details.
7611 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007612 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007613 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007614 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007615 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 Py_END_ALLOW_THREADS
7617 if (res < 0)
7618 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007619 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007620}
7621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007622
Larry Hastings2f936352014-08-05 14:04:04 +10007623/*[clinic input]
7624os.closerange
7625
7626 fd_low: int
7627 fd_high: int
7628 /
7629
7630Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7631[clinic start generated code]*/
7632
Larry Hastings2f936352014-08-05 14:04:04 +10007633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007634os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7635/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007636{
7637 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007639 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007640 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007641 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007642 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 Py_END_ALLOW_THREADS
7644 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007645}
7646
7647
Larry Hastings2f936352014-08-05 14:04:04 +10007648/*[clinic input]
7649os.dup -> int
7650
7651 fd: int
7652 /
7653
7654Return a duplicate of a file descriptor.
7655[clinic start generated code]*/
7656
Larry Hastings2f936352014-08-05 14:04:04 +10007657static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007658os_dup_impl(PyObject *module, int fd)
7659/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007660{
7661 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007662}
7663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Larry Hastings2f936352014-08-05 14:04:04 +10007665/*[clinic input]
7666os.dup2
7667 fd: int
7668 fd2: int
7669 inheritable: bool=True
7670
7671Duplicate file descriptor.
7672[clinic start generated code]*/
7673
Larry Hastings2f936352014-08-05 14:04:04 +10007674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007675os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7676/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007677{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007678 int res;
7679#if defined(HAVE_DUP3) && \
7680 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7681 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7682 int dup3_works = -1;
7683#endif
7684
Steve Dower940f33a2016-09-08 11:21:54 -07007685 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007687
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007688 /* dup2() can fail with EINTR if the target FD is already open, because it
7689 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7690 * upon close(), and therefore below.
7691 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007692#ifdef MS_WINDOWS
7693 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007694 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007696 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007697 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 if (res < 0)
7699 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007700
7701 /* Character files like console cannot be make non-inheritable */
7702 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7703 close(fd2);
7704 return NULL;
7705 }
7706
7707#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7708 Py_BEGIN_ALLOW_THREADS
7709 if (!inheritable)
7710 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7711 else
7712 res = dup2(fd, fd2);
7713 Py_END_ALLOW_THREADS
7714 if (res < 0)
7715 return posix_error();
7716
7717#else
7718
7719#ifdef HAVE_DUP3
7720 if (!inheritable && dup3_works != 0) {
7721 Py_BEGIN_ALLOW_THREADS
7722 res = dup3(fd, fd2, O_CLOEXEC);
7723 Py_END_ALLOW_THREADS
7724 if (res < 0) {
7725 if (dup3_works == -1)
7726 dup3_works = (errno != ENOSYS);
7727 if (dup3_works)
7728 return posix_error();
7729 }
7730 }
7731
7732 if (inheritable || dup3_works == 0)
7733 {
7734#endif
7735 Py_BEGIN_ALLOW_THREADS
7736 res = dup2(fd, fd2);
7737 Py_END_ALLOW_THREADS
7738 if (res < 0)
7739 return posix_error();
7740
7741 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7742 close(fd2);
7743 return NULL;
7744 }
7745#ifdef HAVE_DUP3
7746 }
7747#endif
7748
7749#endif
7750
Larry Hastings2f936352014-08-05 14:04:04 +10007751 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007752}
7753
Larry Hastings2f936352014-08-05 14:04:04 +10007754
Ross Lagerwall7807c352011-03-17 20:20:30 +02007755#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007756/*[clinic input]
7757os.lockf
7758
7759 fd: int
7760 An open file descriptor.
7761 command: int
7762 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7763 length: Py_off_t
7764 The number of bytes to lock, starting at the current position.
7765 /
7766
7767Apply, test or remove a POSIX lock on an open file descriptor.
7768
7769[clinic start generated code]*/
7770
Larry Hastings2f936352014-08-05 14:04:04 +10007771static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007772os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7773/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007774{
7775 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007776
7777 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007778 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007779 Py_END_ALLOW_THREADS
7780
7781 if (res < 0)
7782 return posix_error();
7783
7784 Py_RETURN_NONE;
7785}
Larry Hastings2f936352014-08-05 14:04:04 +10007786#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007788
Larry Hastings2f936352014-08-05 14:04:04 +10007789/*[clinic input]
7790os.lseek -> Py_off_t
7791
7792 fd: int
7793 position: Py_off_t
7794 how: int
7795 /
7796
7797Set the position of a file descriptor. Return the new position.
7798
7799Return the new cursor position in number of bytes
7800relative to the beginning of the file.
7801[clinic start generated code]*/
7802
Larry Hastings2f936352014-08-05 14:04:04 +10007803static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007804os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7805/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007806{
7807 Py_off_t result;
7808
Guido van Rossum687dd131993-05-17 08:34:16 +00007809#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7811 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007812 case 0: how = SEEK_SET; break;
7813 case 1: how = SEEK_CUR; break;
7814 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007816#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007817
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007819 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007820
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007822 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007823#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007824 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007825#else
Larry Hastings2f936352014-08-05 14:04:04 +10007826 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007827#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007828 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007830 if (result < 0)
7831 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007832
Larry Hastings2f936352014-08-05 14:04:04 +10007833 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007834}
7835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007836
Larry Hastings2f936352014-08-05 14:04:04 +10007837/*[clinic input]
7838os.read
7839 fd: int
7840 length: Py_ssize_t
7841 /
7842
7843Read from a file descriptor. Returns a bytes object.
7844[clinic start generated code]*/
7845
Larry Hastings2f936352014-08-05 14:04:04 +10007846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007847os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7848/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007849{
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 Py_ssize_t n;
7851 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007852
7853 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 errno = EINVAL;
7855 return posix_error();
7856 }
Larry Hastings2f936352014-08-05 14:04:04 +10007857
7858#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007859 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007860 if (length > INT_MAX)
7861 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007862#endif
7863
7864 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 if (buffer == NULL)
7866 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007867
Victor Stinner66aab0c2015-03-19 22:53:20 +01007868 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7869 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007871 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 }
Larry Hastings2f936352014-08-05 14:04:04 +10007873
7874 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007876
Victor Stinner8c62be82010-05-06 00:08:46 +00007877 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007878}
7879
Ross Lagerwall7807c352011-03-17 20:20:30 +02007880#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7881 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007882static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007883iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007884{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007885 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007886 Py_ssize_t blen, total = 0;
7887
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007888 *iov = PyMem_New(struct iovec, cnt);
7889 if (*iov == NULL) {
7890 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007891 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007892 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007893
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007894 *buf = PyMem_New(Py_buffer, cnt);
7895 if (*buf == NULL) {
7896 PyMem_Del(*iov);
7897 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007898 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007899 }
7900
7901 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007902 PyObject *item = PySequence_GetItem(seq, i);
7903 if (item == NULL)
7904 goto fail;
7905 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7906 Py_DECREF(item);
7907 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007908 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007909 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007910 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007911 blen = (*buf)[i].len;
7912 (*iov)[i].iov_len = blen;
7913 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007914 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007915 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007916
7917fail:
7918 PyMem_Del(*iov);
7919 for (j = 0; j < i; j++) {
7920 PyBuffer_Release(&(*buf)[j]);
7921 }
7922 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007923 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007924}
7925
7926static void
7927iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7928{
7929 int i;
7930 PyMem_Del(iov);
7931 for (i = 0; i < cnt; i++) {
7932 PyBuffer_Release(&buf[i]);
7933 }
7934 PyMem_Del(buf);
7935}
7936#endif
7937
Larry Hastings2f936352014-08-05 14:04:04 +10007938
Ross Lagerwall7807c352011-03-17 20:20:30 +02007939#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007940/*[clinic input]
7941os.readv -> Py_ssize_t
7942
7943 fd: int
7944 buffers: object
7945 /
7946
7947Read from a file descriptor fd into an iterable of buffers.
7948
7949The buffers should be mutable buffers accepting bytes.
7950readv will transfer data into each buffer until it is full
7951and then move on to the next buffer in the sequence to hold
7952the rest of the data.
7953
7954readv returns the total number of bytes read,
7955which may be less than the total capacity of all the buffers.
7956[clinic start generated code]*/
7957
Larry Hastings2f936352014-08-05 14:04:04 +10007958static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007959os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7960/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007961{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007962 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007963 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007964 struct iovec *iov;
7965 Py_buffer *buf;
7966
Larry Hastings2f936352014-08-05 14:04:04 +10007967 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007968 PyErr_SetString(PyExc_TypeError,
7969 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007970 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007971 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972
Larry Hastings2f936352014-08-05 14:04:04 +10007973 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007974 if (cnt < 0)
7975 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10007976
7977 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7978 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007979
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007980 do {
7981 Py_BEGIN_ALLOW_THREADS
7982 n = readv(fd, iov, cnt);
7983 Py_END_ALLOW_THREADS
7984 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007985
7986 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007987 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007988 if (!async_err)
7989 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007990 return -1;
7991 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007992
Larry Hastings2f936352014-08-05 14:04:04 +10007993 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007994}
Larry Hastings2f936352014-08-05 14:04:04 +10007995#endif /* HAVE_READV */
7996
Ross Lagerwall7807c352011-03-17 20:20:30 +02007997
7998#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007999/*[clinic input]
8000# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8001os.pread
8002
8003 fd: int
8004 length: int
8005 offset: Py_off_t
8006 /
8007
8008Read a number of bytes from a file descriptor starting at a particular offset.
8009
8010Read length bytes from file descriptor fd, starting at offset bytes from
8011the beginning of the file. The file offset remains unchanged.
8012[clinic start generated code]*/
8013
Larry Hastings2f936352014-08-05 14:04:04 +10008014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008015os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8016/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008017{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008018 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008019 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008020 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008021
Larry Hastings2f936352014-08-05 14:04:04 +10008022 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023 errno = EINVAL;
8024 return posix_error();
8025 }
Larry Hastings2f936352014-08-05 14:04:04 +10008026 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008027 if (buffer == NULL)
8028 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008029
8030 do {
8031 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008032 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008033 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008034 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008035 Py_END_ALLOW_THREADS
8036 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8037
Ross Lagerwall7807c352011-03-17 20:20:30 +02008038 if (n < 0) {
8039 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008040 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008041 }
Larry Hastings2f936352014-08-05 14:04:04 +10008042 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008043 _PyBytes_Resize(&buffer, n);
8044 return buffer;
8045}
Larry Hastings2f936352014-08-05 14:04:04 +10008046#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008047
Larry Hastings2f936352014-08-05 14:04:04 +10008048
8049/*[clinic input]
8050os.write -> Py_ssize_t
8051
8052 fd: int
8053 data: Py_buffer
8054 /
8055
8056Write a bytes object to a file descriptor.
8057[clinic start generated code]*/
8058
Larry Hastings2f936352014-08-05 14:04:04 +10008059static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008060os_write_impl(PyObject *module, int fd, Py_buffer *data)
8061/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008062{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008063 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008064}
8065
8066#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008067PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008068"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008069sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008071Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072
Larry Hastings2f936352014-08-05 14:04:04 +10008073/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074static PyObject *
8075posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8076{
8077 int in, out;
8078 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008079 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008080 off_t offset;
8081
8082#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8083#ifndef __APPLE__
8084 Py_ssize_t len;
8085#endif
8086 PyObject *headers = NULL, *trailers = NULL;
8087 Py_buffer *hbuf, *tbuf;
8088 off_t sbytes;
8089 struct sf_hdtr sf;
8090 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008091 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008092 static char *keywords[] = {"out", "in",
8093 "offset", "count",
8094 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008096 sf.headers = NULL;
8097 sf.trailers = NULL;
8098
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008099#ifdef __APPLE__
8100 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008101 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008102#else
8103 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008104 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008105#endif
8106 &headers, &trailers, &flags))
8107 return NULL;
8108 if (headers != NULL) {
8109 if (!PySequence_Check(headers)) {
8110 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008111 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008112 return NULL;
8113 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008114 Py_ssize_t i = PySequence_Size(headers);
8115 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008116 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008117 if (i > INT_MAX) {
8118 PyErr_SetString(PyExc_OverflowError,
8119 "sendfile() header is too large");
8120 return NULL;
8121 }
8122 if (i > 0) {
8123 sf.hdr_cnt = (int)i;
8124 i = iov_setup(&(sf.headers), &hbuf,
8125 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8126 if (i < 0)
8127 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008128#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008129 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008130#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008131 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008132 }
8133 }
8134 if (trailers != NULL) {
8135 if (!PySequence_Check(trailers)) {
8136 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008137 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008138 return NULL;
8139 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008140 Py_ssize_t i = PySequence_Size(trailers);
8141 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008142 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008143 if (i > INT_MAX) {
8144 PyErr_SetString(PyExc_OverflowError,
8145 "sendfile() trailer is too large");
8146 return NULL;
8147 }
8148 if (i > 0) {
8149 sf.trl_cnt = (int)i;
8150 i = iov_setup(&(sf.trailers), &tbuf,
8151 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8152 if (i < 0)
8153 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008154#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008155 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008156#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008157 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008158 }
8159 }
8160
Steve Dower8fc89802015-04-12 00:26:27 -04008161 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008162 do {
8163 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008164#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008165 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008166#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008167 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008168#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008169 Py_END_ALLOW_THREADS
8170 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008171 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008172
8173 if (sf.headers != NULL)
8174 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8175 if (sf.trailers != NULL)
8176 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8177
8178 if (ret < 0) {
8179 if ((errno == EAGAIN) || (errno == EBUSY)) {
8180 if (sbytes != 0) {
8181 // some data has been sent
8182 goto done;
8183 }
8184 else {
8185 // no data has been sent; upper application is supposed
8186 // to retry on EAGAIN or EBUSY
8187 return posix_error();
8188 }
8189 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008190 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008191 }
8192 goto done;
8193
8194done:
8195 #if !defined(HAVE_LARGEFILE_SUPPORT)
8196 return Py_BuildValue("l", sbytes);
8197 #else
8198 return Py_BuildValue("L", sbytes);
8199 #endif
8200
8201#else
8202 Py_ssize_t count;
8203 PyObject *offobj;
8204 static char *keywords[] = {"out", "in",
8205 "offset", "count", NULL};
8206 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8207 keywords, &out, &in, &offobj, &count))
8208 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008209#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008210 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008211 do {
8212 Py_BEGIN_ALLOW_THREADS
8213 ret = sendfile(out, in, NULL, count);
8214 Py_END_ALLOW_THREADS
8215 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008216 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008217 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008218 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008219 }
8220#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008221 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008222 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008223
8224 do {
8225 Py_BEGIN_ALLOW_THREADS
8226 ret = sendfile(out, in, &offset, count);
8227 Py_END_ALLOW_THREADS
8228 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008229 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008230 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008231 return Py_BuildValue("n", ret);
8232#endif
8233}
Larry Hastings2f936352014-08-05 14:04:04 +10008234#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008235
Larry Hastings2f936352014-08-05 14:04:04 +10008236
8237/*[clinic input]
8238os.fstat
8239
8240 fd : int
8241
8242Perform a stat system call on the given file descriptor.
8243
8244Like stat(), but for an open file descriptor.
8245Equivalent to os.stat(fd).
8246[clinic start generated code]*/
8247
Larry Hastings2f936352014-08-05 14:04:04 +10008248static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008249os_fstat_impl(PyObject *module, int fd)
8250/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008251{
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 STRUCT_STAT st;
8253 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008254 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008255
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008256 do {
8257 Py_BEGIN_ALLOW_THREADS
8258 res = FSTAT(fd, &st);
8259 Py_END_ALLOW_THREADS
8260 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008261 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008262#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008263 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008264#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008265 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008266#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008267 }
Tim Peters5aa91602002-01-30 05:46:57 +00008268
Victor Stinner4195b5c2012-02-08 23:03:19 +01008269 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008270}
8271
Larry Hastings2f936352014-08-05 14:04:04 +10008272
8273/*[clinic input]
8274os.isatty -> bool
8275 fd: int
8276 /
8277
8278Return True if the fd is connected to a terminal.
8279
8280Return True if the file descriptor is an open file descriptor
8281connected to the slave end of a terminal.
8282[clinic start generated code]*/
8283
Larry Hastings2f936352014-08-05 14:04:04 +10008284static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008285os_isatty_impl(PyObject *module, int fd)
8286/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008287{
Steve Dower8fc89802015-04-12 00:26:27 -04008288 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008289 _Py_BEGIN_SUPPRESS_IPH
8290 return_value = isatty(fd);
8291 _Py_END_SUPPRESS_IPH
8292 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008293}
8294
8295
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008296#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008297/*[clinic input]
8298os.pipe
8299
8300Create a pipe.
8301
8302Returns a tuple of two file descriptors:
8303 (read_fd, write_fd)
8304[clinic start generated code]*/
8305
Larry Hastings2f936352014-08-05 14:04:04 +10008306static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008307os_pipe_impl(PyObject *module)
8308/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008309{
Victor Stinner8c62be82010-05-06 00:08:46 +00008310 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008311#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008312 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008313 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008315#else
8316 int res;
8317#endif
8318
8319#ifdef MS_WINDOWS
8320 attr.nLength = sizeof(attr);
8321 attr.lpSecurityDescriptor = NULL;
8322 attr.bInheritHandle = FALSE;
8323
8324 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008325 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008326 ok = CreatePipe(&read, &write, &attr, 0);
8327 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008328 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8329 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008330 if (fds[0] == -1 || fds[1] == -1) {
8331 CloseHandle(read);
8332 CloseHandle(write);
8333 ok = 0;
8334 }
8335 }
Steve Dowerc3630612016-11-19 18:41:16 -08008336 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008337 Py_END_ALLOW_THREADS
8338
Victor Stinner8c62be82010-05-06 00:08:46 +00008339 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008340 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008341#else
8342
8343#ifdef HAVE_PIPE2
8344 Py_BEGIN_ALLOW_THREADS
8345 res = pipe2(fds, O_CLOEXEC);
8346 Py_END_ALLOW_THREADS
8347
8348 if (res != 0 && errno == ENOSYS)
8349 {
8350#endif
8351 Py_BEGIN_ALLOW_THREADS
8352 res = pipe(fds);
8353 Py_END_ALLOW_THREADS
8354
8355 if (res == 0) {
8356 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8357 close(fds[0]);
8358 close(fds[1]);
8359 return NULL;
8360 }
8361 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8362 close(fds[0]);
8363 close(fds[1]);
8364 return NULL;
8365 }
8366 }
8367#ifdef HAVE_PIPE2
8368 }
8369#endif
8370
8371 if (res != 0)
8372 return PyErr_SetFromErrno(PyExc_OSError);
8373#endif /* !MS_WINDOWS */
8374 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008375}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008376#endif /* HAVE_PIPE */
8377
Larry Hastings2f936352014-08-05 14:04:04 +10008378
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008379#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008380/*[clinic input]
8381os.pipe2
8382
8383 flags: int
8384 /
8385
8386Create a pipe with flags set atomically.
8387
8388Returns a tuple of two file descriptors:
8389 (read_fd, write_fd)
8390
8391flags can be constructed by ORing together one or more of these values:
8392O_NONBLOCK, O_CLOEXEC.
8393[clinic start generated code]*/
8394
Larry Hastings2f936352014-08-05 14:04:04 +10008395static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008396os_pipe2_impl(PyObject *module, int flags)
8397/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008398{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008399 int fds[2];
8400 int res;
8401
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008402 res = pipe2(fds, flags);
8403 if (res != 0)
8404 return posix_error();
8405 return Py_BuildValue("(ii)", fds[0], fds[1]);
8406}
8407#endif /* HAVE_PIPE2 */
8408
Larry Hastings2f936352014-08-05 14:04:04 +10008409
Ross Lagerwall7807c352011-03-17 20:20:30 +02008410#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008411/*[clinic input]
8412os.writev -> Py_ssize_t
8413 fd: int
8414 buffers: object
8415 /
8416
8417Iterate over buffers, and write the contents of each to a file descriptor.
8418
8419Returns the total number of bytes written.
8420buffers must be a sequence of bytes-like objects.
8421[clinic start generated code]*/
8422
Larry Hastings2f936352014-08-05 14:04:04 +10008423static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008424os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8425/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008426{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008427 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008428 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008429 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008430 struct iovec *iov;
8431 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008432
8433 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008434 PyErr_SetString(PyExc_TypeError,
8435 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008436 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008437 }
Larry Hastings2f936352014-08-05 14:04:04 +10008438 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008439 if (cnt < 0)
8440 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008441
Larry Hastings2f936352014-08-05 14:04:04 +10008442 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8443 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008444 }
8445
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008446 do {
8447 Py_BEGIN_ALLOW_THREADS
8448 result = writev(fd, iov, cnt);
8449 Py_END_ALLOW_THREADS
8450 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008451
8452 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008453 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008454 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008455
Georg Brandl306336b2012-06-24 12:55:33 +02008456 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008457}
Larry Hastings2f936352014-08-05 14:04:04 +10008458#endif /* HAVE_WRITEV */
8459
8460
8461#ifdef HAVE_PWRITE
8462/*[clinic input]
8463os.pwrite -> Py_ssize_t
8464
8465 fd: int
8466 buffer: Py_buffer
8467 offset: Py_off_t
8468 /
8469
8470Write bytes to a file descriptor starting at a particular offset.
8471
8472Write buffer to fd, starting at offset bytes from the beginning of
8473the file. Returns the number of bytes writte. Does not change the
8474current file offset.
8475[clinic start generated code]*/
8476
Larry Hastings2f936352014-08-05 14:04:04 +10008477static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008478os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8479/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008480{
8481 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008482 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008483
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008484 do {
8485 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008486 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008487 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008488 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008489 Py_END_ALLOW_THREADS
8490 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008491
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008492 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008493 posix_error();
8494 return size;
8495}
8496#endif /* HAVE_PWRITE */
8497
8498
8499#ifdef HAVE_MKFIFO
8500/*[clinic input]
8501os.mkfifo
8502
8503 path: path_t
8504 mode: int=0o666
8505 *
8506 dir_fd: dir_fd(requires='mkfifoat')=None
8507
8508Create a "fifo" (a POSIX named pipe).
8509
8510If dir_fd is not None, it should be a file descriptor open to a directory,
8511 and path should be relative; path will then be relative to that directory.
8512dir_fd may not be implemented on your platform.
8513 If it is unavailable, using it will raise a NotImplementedError.
8514[clinic start generated code]*/
8515
Larry Hastings2f936352014-08-05 14:04:04 +10008516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008517os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8518/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008519{
8520 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008521 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008522
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008523 do {
8524 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008525#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008526 if (dir_fd != DEFAULT_DIR_FD)
8527 result = mkfifoat(dir_fd, path->narrow, mode);
8528 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008529#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008530 result = mkfifo(path->narrow, mode);
8531 Py_END_ALLOW_THREADS
8532 } while (result != 0 && errno == EINTR &&
8533 !(async_err = PyErr_CheckSignals()));
8534 if (result != 0)
8535 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008536
8537 Py_RETURN_NONE;
8538}
8539#endif /* HAVE_MKFIFO */
8540
8541
8542#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8543/*[clinic input]
8544os.mknod
8545
8546 path: path_t
8547 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008548 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008549 *
8550 dir_fd: dir_fd(requires='mknodat')=None
8551
8552Create a node in the file system.
8553
8554Create a node in the file system (file, device special file or named pipe)
8555at path. mode specifies both the permissions to use and the
8556type of node to be created, being combined (bitwise OR) with one of
8557S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8558device defines the newly created device special file (probably using
8559os.makedev()). Otherwise device is ignored.
8560
8561If dir_fd is not None, it should be a file descriptor open to a directory,
8562 and path should be relative; path will then be relative to that directory.
8563dir_fd may not be implemented on your platform.
8564 If it is unavailable, using it will raise a NotImplementedError.
8565[clinic start generated code]*/
8566
Larry Hastings2f936352014-08-05 14:04:04 +10008567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008568os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008569 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008570/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008571{
8572 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008573 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008574
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008575 do {
8576 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008577#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008578 if (dir_fd != DEFAULT_DIR_FD)
8579 result = mknodat(dir_fd, path->narrow, mode, device);
8580 else
Larry Hastings2f936352014-08-05 14:04:04 +10008581#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008582 result = mknod(path->narrow, mode, device);
8583 Py_END_ALLOW_THREADS
8584 } while (result != 0 && errno == EINTR &&
8585 !(async_err = PyErr_CheckSignals()));
8586 if (result != 0)
8587 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008588
8589 Py_RETURN_NONE;
8590}
8591#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8592
8593
8594#ifdef HAVE_DEVICE_MACROS
8595/*[clinic input]
8596os.major -> unsigned_int
8597
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008598 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008599 /
8600
8601Extracts a device major number from a raw device number.
8602[clinic start generated code]*/
8603
Larry Hastings2f936352014-08-05 14:04:04 +10008604static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008605os_major_impl(PyObject *module, dev_t device)
8606/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008607{
8608 return major(device);
8609}
8610
8611
8612/*[clinic input]
8613os.minor -> unsigned_int
8614
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008615 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008616 /
8617
8618Extracts a device minor number from a raw device number.
8619[clinic start generated code]*/
8620
Larry Hastings2f936352014-08-05 14:04:04 +10008621static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008622os_minor_impl(PyObject *module, dev_t device)
8623/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008624{
8625 return minor(device);
8626}
8627
8628
8629/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008630os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008631
8632 major: int
8633 minor: int
8634 /
8635
8636Composes a raw device number from the major and minor device numbers.
8637[clinic start generated code]*/
8638
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008639static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008640os_makedev_impl(PyObject *module, int major, int minor)
8641/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008642{
8643 return makedev(major, minor);
8644}
8645#endif /* HAVE_DEVICE_MACROS */
8646
8647
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008648#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008649/*[clinic input]
8650os.ftruncate
8651
8652 fd: int
8653 length: Py_off_t
8654 /
8655
8656Truncate a file, specified by file descriptor, to a specific length.
8657[clinic start generated code]*/
8658
Larry Hastings2f936352014-08-05 14:04:04 +10008659static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008660os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8661/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008662{
8663 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008664 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008665
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008666 do {
8667 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008668 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008669#ifdef MS_WINDOWS
8670 result = _chsize_s(fd, length);
8671#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008672 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008673#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008674 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008675 Py_END_ALLOW_THREADS
8676 } while (result != 0 && errno == EINTR &&
8677 !(async_err = PyErr_CheckSignals()));
8678 if (result != 0)
8679 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008680 Py_RETURN_NONE;
8681}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008682#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008683
8684
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008685#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008686/*[clinic input]
8687os.truncate
8688 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8689 length: Py_off_t
8690
8691Truncate a file, specified by path, to a specific length.
8692
8693On some platforms, path may also be specified as an open file descriptor.
8694 If this functionality is unavailable, using it raises an exception.
8695[clinic start generated code]*/
8696
Larry Hastings2f936352014-08-05 14:04:04 +10008697static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008698os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8699/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008700{
8701 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008702#ifdef MS_WINDOWS
8703 int fd;
8704#endif
8705
8706 if (path->fd != -1)
8707 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008708
8709 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008710 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008711#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008712 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008713 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008714 result = -1;
8715 else {
8716 result = _chsize_s(fd, length);
8717 close(fd);
8718 if (result < 0)
8719 errno = result;
8720 }
8721#else
8722 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008723#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008724 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008725 Py_END_ALLOW_THREADS
8726 if (result < 0)
8727 return path_error(path);
8728
8729 Py_RETURN_NONE;
8730}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008731#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008732
Ross Lagerwall7807c352011-03-17 20:20:30 +02008733
Victor Stinnerd6b17692014-09-30 12:20:05 +02008734/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8735 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8736 defined, which is the case in Python on AIX. AIX bug report:
8737 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8738#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8739# define POSIX_FADVISE_AIX_BUG
8740#endif
8741
Victor Stinnerec39e262014-09-30 12:35:58 +02008742
Victor Stinnerd6b17692014-09-30 12:20:05 +02008743#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008744/*[clinic input]
8745os.posix_fallocate
8746
8747 fd: int
8748 offset: Py_off_t
8749 length: Py_off_t
8750 /
8751
8752Ensure a file has allocated at least a particular number of bytes on disk.
8753
8754Ensure that the file specified by fd encompasses a range of bytes
8755starting at offset bytes from the beginning and continuing for length bytes.
8756[clinic start generated code]*/
8757
Larry Hastings2f936352014-08-05 14:04:04 +10008758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008759os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008760 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008761/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008762{
8763 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008764 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008765
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008766 do {
8767 Py_BEGIN_ALLOW_THREADS
8768 result = posix_fallocate(fd, offset, length);
8769 Py_END_ALLOW_THREADS
8770 } while (result != 0 && errno == EINTR &&
8771 !(async_err = PyErr_CheckSignals()));
8772 if (result != 0)
8773 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008774 Py_RETURN_NONE;
8775}
Victor Stinnerec39e262014-09-30 12:35:58 +02008776#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008777
Ross Lagerwall7807c352011-03-17 20:20:30 +02008778
Victor Stinnerd6b17692014-09-30 12:20:05 +02008779#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008780/*[clinic input]
8781os.posix_fadvise
8782
8783 fd: int
8784 offset: Py_off_t
8785 length: Py_off_t
8786 advice: int
8787 /
8788
8789Announce an intention to access data in a specific pattern.
8790
8791Announce an intention to access data in a specific pattern, thus allowing
8792the kernel to make optimizations.
8793The advice applies to the region of the file specified by fd starting at
8794offset and continuing for length bytes.
8795advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8796POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8797POSIX_FADV_DONTNEED.
8798[clinic start generated code]*/
8799
Larry Hastings2f936352014-08-05 14:04:04 +10008800static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008801os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008802 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008803/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008804{
8805 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008806 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008807
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008808 do {
8809 Py_BEGIN_ALLOW_THREADS
8810 result = posix_fadvise(fd, offset, length, advice);
8811 Py_END_ALLOW_THREADS
8812 } while (result != 0 && errno == EINTR &&
8813 !(async_err = PyErr_CheckSignals()));
8814 if (result != 0)
8815 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008816 Py_RETURN_NONE;
8817}
Victor Stinnerec39e262014-09-30 12:35:58 +02008818#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008819
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008820#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008821
Fred Drake762e2061999-08-26 17:23:54 +00008822/* Save putenv() parameters as values here, so we can collect them when they
8823 * get re-set with another call for the same key. */
8824static PyObject *posix_putenv_garbage;
8825
Larry Hastings2f936352014-08-05 14:04:04 +10008826static void
8827posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008828{
Larry Hastings2f936352014-08-05 14:04:04 +10008829 /* Install the first arg and newstr in posix_putenv_garbage;
8830 * this will cause previous value to be collected. This has to
8831 * happen after the real putenv() call because the old value
8832 * was still accessible until then. */
8833 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8834 /* really not much we can do; just leak */
8835 PyErr_Clear();
8836 else
8837 Py_DECREF(value);
8838}
8839
8840
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008841#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008842/*[clinic input]
8843os.putenv
8844
8845 name: unicode
8846 value: unicode
8847 /
8848
8849Change or add an environment variable.
8850[clinic start generated code]*/
8851
Larry Hastings2f936352014-08-05 14:04:04 +10008852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008853os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8854/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008855{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008856 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008857
8858 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8859 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008860 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008861 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008862 }
Larry Hastings2f936352014-08-05 14:04:04 +10008863 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008864 PyErr_Format(PyExc_ValueError,
8865 "the environment variable is longer than %u characters",
8866 _MAX_ENV);
8867 goto error;
8868 }
8869
Larry Hastings2f936352014-08-05 14:04:04 +10008870 env = PyUnicode_AsUnicode(unicode);
8871 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008872 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008873 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008875 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008877
Larry Hastings2f936352014-08-05 14:04:04 +10008878 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008879 Py_RETURN_NONE;
8880
8881error:
Larry Hastings2f936352014-08-05 14:04:04 +10008882 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008883 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008884}
Larry Hastings2f936352014-08-05 14:04:04 +10008885#else /* MS_WINDOWS */
8886/*[clinic input]
8887os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008888
Larry Hastings2f936352014-08-05 14:04:04 +10008889 name: FSConverter
8890 value: FSConverter
8891 /
8892
8893Change or add an environment variable.
8894[clinic start generated code]*/
8895
Larry Hastings2f936352014-08-05 14:04:04 +10008896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008897os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8898/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008899{
8900 PyObject *bytes = NULL;
8901 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008902 const char *name_string = PyBytes_AsString(name);
8903 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008904
8905 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8906 if (bytes == NULL) {
8907 PyErr_NoMemory();
8908 return NULL;
8909 }
8910
8911 env = PyBytes_AS_STRING(bytes);
8912 if (putenv(env)) {
8913 Py_DECREF(bytes);
8914 return posix_error();
8915 }
8916
8917 posix_putenv_garbage_setitem(name, bytes);
8918 Py_RETURN_NONE;
8919}
8920#endif /* MS_WINDOWS */
8921#endif /* HAVE_PUTENV */
8922
8923
8924#ifdef HAVE_UNSETENV
8925/*[clinic input]
8926os.unsetenv
8927 name: FSConverter
8928 /
8929
8930Delete an environment variable.
8931[clinic start generated code]*/
8932
Larry Hastings2f936352014-08-05 14:04:04 +10008933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008934os_unsetenv_impl(PyObject *module, PyObject *name)
8935/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008936{
Victor Stinner984890f2011-11-24 13:53:38 +01008937#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008938 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008939#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008940
Victor Stinner984890f2011-11-24 13:53:38 +01008941#ifdef HAVE_BROKEN_UNSETENV
8942 unsetenv(PyBytes_AS_STRING(name));
8943#else
Victor Stinner65170952011-11-22 22:16:17 +01008944 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008945 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008946 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008947#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008948
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 /* Remove the key from posix_putenv_garbage;
8950 * this will cause it to be collected. This has to
8951 * happen after the real unsetenv() call because the
8952 * old value was still accessible until then.
8953 */
Victor Stinner65170952011-11-22 22:16:17 +01008954 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 /* really not much we can do; just leak */
8956 PyErr_Clear();
8957 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008958 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008959}
Larry Hastings2f936352014-08-05 14:04:04 +10008960#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008961
Larry Hastings2f936352014-08-05 14:04:04 +10008962
8963/*[clinic input]
8964os.strerror
8965
8966 code: int
8967 /
8968
8969Translate an error code to a message string.
8970[clinic start generated code]*/
8971
Larry Hastings2f936352014-08-05 14:04:04 +10008972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008973os_strerror_impl(PyObject *module, int code)
8974/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008975{
8976 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 if (message == NULL) {
8978 PyErr_SetString(PyExc_ValueError,
8979 "strerror() argument out of range");
8980 return NULL;
8981 }
Victor Stinner1b579672011-12-17 05:47:23 +01008982 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008983}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008984
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008985
Guido van Rossumc9641791998-08-04 15:26:23 +00008986#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008987#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008988/*[clinic input]
8989os.WCOREDUMP -> bool
8990
8991 status: int
8992 /
8993
8994Return True if the process returning status was dumped to a core file.
8995[clinic start generated code]*/
8996
Larry Hastings2f936352014-08-05 14:04:04 +10008997static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008998os_WCOREDUMP_impl(PyObject *module, int status)
8999/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009000{
9001 WAIT_TYPE wait_status;
9002 WAIT_STATUS_INT(wait_status) = status;
9003 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009004}
9005#endif /* WCOREDUMP */
9006
Larry Hastings2f936352014-08-05 14:04:04 +10009007
Fred Drake106c1a02002-04-23 15:58:02 +00009008#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009009/*[clinic input]
9010os.WIFCONTINUED -> bool
9011
9012 status: int
9013
9014Return True if a particular process was continued from a job control stop.
9015
9016Return True if the process returning status was continued from a
9017job control stop.
9018[clinic start generated code]*/
9019
Larry Hastings2f936352014-08-05 14:04:04 +10009020static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009021os_WIFCONTINUED_impl(PyObject *module, int status)
9022/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009023{
9024 WAIT_TYPE wait_status;
9025 WAIT_STATUS_INT(wait_status) = status;
9026 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009027}
9028#endif /* WIFCONTINUED */
9029
Larry Hastings2f936352014-08-05 14:04:04 +10009030
Guido van Rossumc9641791998-08-04 15:26:23 +00009031#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009032/*[clinic input]
9033os.WIFSTOPPED -> bool
9034
9035 status: int
9036
9037Return True if the process returning status was stopped.
9038[clinic start generated code]*/
9039
Larry Hastings2f936352014-08-05 14:04:04 +10009040static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009041os_WIFSTOPPED_impl(PyObject *module, int status)
9042/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009043{
9044 WAIT_TYPE wait_status;
9045 WAIT_STATUS_INT(wait_status) = status;
9046 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009047}
9048#endif /* WIFSTOPPED */
9049
Larry Hastings2f936352014-08-05 14:04:04 +10009050
Guido van Rossumc9641791998-08-04 15:26:23 +00009051#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009052/*[clinic input]
9053os.WIFSIGNALED -> bool
9054
9055 status: int
9056
9057Return True if the process returning status was terminated by a signal.
9058[clinic start generated code]*/
9059
Larry Hastings2f936352014-08-05 14:04:04 +10009060static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009061os_WIFSIGNALED_impl(PyObject *module, int status)
9062/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009063{
9064 WAIT_TYPE wait_status;
9065 WAIT_STATUS_INT(wait_status) = status;
9066 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009067}
9068#endif /* WIFSIGNALED */
9069
Larry Hastings2f936352014-08-05 14:04:04 +10009070
Guido van Rossumc9641791998-08-04 15:26:23 +00009071#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009072/*[clinic input]
9073os.WIFEXITED -> bool
9074
9075 status: int
9076
9077Return True if the process returning status exited via the exit() system call.
9078[clinic start generated code]*/
9079
Larry Hastings2f936352014-08-05 14:04:04 +10009080static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009081os_WIFEXITED_impl(PyObject *module, int status)
9082/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009083{
9084 WAIT_TYPE wait_status;
9085 WAIT_STATUS_INT(wait_status) = status;
9086 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009087}
9088#endif /* WIFEXITED */
9089
Larry Hastings2f936352014-08-05 14:04:04 +10009090
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009091#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009092/*[clinic input]
9093os.WEXITSTATUS -> int
9094
9095 status: int
9096
9097Return the process return code from status.
9098[clinic start generated code]*/
9099
Larry Hastings2f936352014-08-05 14:04:04 +10009100static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009101os_WEXITSTATUS_impl(PyObject *module, int status)
9102/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009103{
9104 WAIT_TYPE wait_status;
9105 WAIT_STATUS_INT(wait_status) = status;
9106 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009107}
9108#endif /* WEXITSTATUS */
9109
Larry Hastings2f936352014-08-05 14:04:04 +10009110
Guido van Rossumc9641791998-08-04 15:26:23 +00009111#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009112/*[clinic input]
9113os.WTERMSIG -> int
9114
9115 status: int
9116
9117Return the signal that terminated the process that provided the status value.
9118[clinic start generated code]*/
9119
Larry Hastings2f936352014-08-05 14:04:04 +10009120static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009121os_WTERMSIG_impl(PyObject *module, int status)
9122/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009123{
9124 WAIT_TYPE wait_status;
9125 WAIT_STATUS_INT(wait_status) = status;
9126 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009127}
9128#endif /* WTERMSIG */
9129
Larry Hastings2f936352014-08-05 14:04:04 +10009130
Guido van Rossumc9641791998-08-04 15:26:23 +00009131#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009132/*[clinic input]
9133os.WSTOPSIG -> int
9134
9135 status: int
9136
9137Return the signal that stopped the process that provided the status value.
9138[clinic start generated code]*/
9139
Larry Hastings2f936352014-08-05 14:04:04 +10009140static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009141os_WSTOPSIG_impl(PyObject *module, int status)
9142/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009143{
9144 WAIT_TYPE wait_status;
9145 WAIT_STATUS_INT(wait_status) = status;
9146 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009147}
9148#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009149#endif /* HAVE_SYS_WAIT_H */
9150
9151
Thomas Wouters477c8d52006-05-27 19:21:47 +00009152#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009153#ifdef _SCO_DS
9154/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9155 needed definitions in sys/statvfs.h */
9156#define _SVID3
9157#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009158#include <sys/statvfs.h>
9159
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009160static PyObject*
9161_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9163 if (v == NULL)
9164 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009165
9166#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9168 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9169 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9170 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9171 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9172 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9173 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9174 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9175 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9176 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009177#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009178 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9179 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9180 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009181 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009183 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009184 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009185 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009187 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009188 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009189 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009190 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009191 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9193 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009194#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009195 if (PyErr_Occurred()) {
9196 Py_DECREF(v);
9197 return NULL;
9198 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009199
Victor Stinner8c62be82010-05-06 00:08:46 +00009200 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009201}
9202
Larry Hastings2f936352014-08-05 14:04:04 +10009203
9204/*[clinic input]
9205os.fstatvfs
9206 fd: int
9207 /
9208
9209Perform an fstatvfs system call on the given fd.
9210
9211Equivalent to statvfs(fd).
9212[clinic start generated code]*/
9213
Larry Hastings2f936352014-08-05 14:04:04 +10009214static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009215os_fstatvfs_impl(PyObject *module, int fd)
9216/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009217{
9218 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009219 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009220 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009221
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009222 do {
9223 Py_BEGIN_ALLOW_THREADS
9224 result = fstatvfs(fd, &st);
9225 Py_END_ALLOW_THREADS
9226 } while (result != 0 && errno == EINTR &&
9227 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009228 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009229 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009230
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009232}
Larry Hastings2f936352014-08-05 14:04:04 +10009233#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009234
9235
Thomas Wouters477c8d52006-05-27 19:21:47 +00009236#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009237#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009238/*[clinic input]
9239os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009240
Larry Hastings2f936352014-08-05 14:04:04 +10009241 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9242
9243Perform a statvfs system call on the given path.
9244
9245path may always be specified as a string.
9246On some platforms, path may also be specified as an open file descriptor.
9247 If this functionality is unavailable, using it raises an exception.
9248[clinic start generated code]*/
9249
Larry Hastings2f936352014-08-05 14:04:04 +10009250static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009251os_statvfs_impl(PyObject *module, path_t *path)
9252/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009253{
9254 int result;
9255 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009256
9257 Py_BEGIN_ALLOW_THREADS
9258#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009259 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009260#ifdef __APPLE__
9261 /* handle weak-linking on Mac OS X 10.3 */
9262 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009263 fd_specified("statvfs", path->fd);
9264 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009265 }
9266#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009267 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009268 }
9269 else
9270#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009271 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009272 Py_END_ALLOW_THREADS
9273
9274 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009275 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009276 }
9277
Larry Hastings2f936352014-08-05 14:04:04 +10009278 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009279}
Larry Hastings2f936352014-08-05 14:04:04 +10009280#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9281
Guido van Rossum94f6f721999-01-06 18:42:14 +00009282
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009283#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009284/*[clinic input]
9285os._getdiskusage
9286
9287 path: Py_UNICODE
9288
9289Return disk usage statistics about the given path as a (total, free) tuple.
9290[clinic start generated code]*/
9291
Larry Hastings2f936352014-08-05 14:04:04 +10009292static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009293os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9294/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009295{
9296 BOOL retval;
9297 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009298
9299 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009300 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009301 Py_END_ALLOW_THREADS
9302 if (retval == 0)
9303 return PyErr_SetFromWindowsErr(0);
9304
9305 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9306}
Larry Hastings2f936352014-08-05 14:04:04 +10009307#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009308
9309
Fred Drakec9680921999-12-13 16:37:25 +00009310/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9311 * It maps strings representing configuration variable names to
9312 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009313 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009314 * rarely-used constants. There are three separate tables that use
9315 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009316 *
9317 * This code is always included, even if none of the interfaces that
9318 * need it are included. The #if hackery needed to avoid it would be
9319 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009320 */
9321struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009322 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009323 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009324};
9325
Fred Drake12c6e2d1999-12-14 21:25:03 +00009326static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009327conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009328 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009329{
Christian Heimes217cfd12007-12-02 14:31:20 +00009330 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009331 int value = _PyLong_AsInt(arg);
9332 if (value == -1 && PyErr_Occurred())
9333 return 0;
9334 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009335 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009336 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009337 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009338 /* look up the value in the table using a binary search */
9339 size_t lo = 0;
9340 size_t mid;
9341 size_t hi = tablesize;
9342 int cmp;
9343 const char *confname;
9344 if (!PyUnicode_Check(arg)) {
9345 PyErr_SetString(PyExc_TypeError,
9346 "configuration names must be strings or integers");
9347 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009349 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009350 if (confname == NULL)
9351 return 0;
9352 while (lo < hi) {
9353 mid = (lo + hi) / 2;
9354 cmp = strcmp(confname, table[mid].name);
9355 if (cmp < 0)
9356 hi = mid;
9357 else if (cmp > 0)
9358 lo = mid + 1;
9359 else {
9360 *valuep = table[mid].value;
9361 return 1;
9362 }
9363 }
9364 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9365 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009367}
9368
9369
9370#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9371static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009372#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009374#endif
9375#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009377#endif
Fred Drakec9680921999-12-13 16:37:25 +00009378#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
9405#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
9408#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009410#endif
9411#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009416#endif
9417#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009419#endif
9420#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009422#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009423#ifdef _PC_ACL_ENABLED
9424 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9425#endif
9426#ifdef _PC_MIN_HOLE_SIZE
9427 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9428#endif
9429#ifdef _PC_ALLOC_SIZE_MIN
9430 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9431#endif
9432#ifdef _PC_REC_INCR_XFER_SIZE
9433 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9434#endif
9435#ifdef _PC_REC_MAX_XFER_SIZE
9436 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9437#endif
9438#ifdef _PC_REC_MIN_XFER_SIZE
9439 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9440#endif
9441#ifdef _PC_REC_XFER_ALIGN
9442 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9443#endif
9444#ifdef _PC_SYMLINK_MAX
9445 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9446#endif
9447#ifdef _PC_XATTR_ENABLED
9448 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9449#endif
9450#ifdef _PC_XATTR_EXISTS
9451 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9452#endif
9453#ifdef _PC_TIMESTAMP_RESOLUTION
9454 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9455#endif
Fred Drakec9680921999-12-13 16:37:25 +00009456};
9457
Fred Drakec9680921999-12-13 16:37:25 +00009458static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009459conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009460{
9461 return conv_confname(arg, valuep, posix_constants_pathconf,
9462 sizeof(posix_constants_pathconf)
9463 / sizeof(struct constdef));
9464}
9465#endif
9466
Larry Hastings2f936352014-08-05 14:04:04 +10009467
Fred Drakec9680921999-12-13 16:37:25 +00009468#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009469/*[clinic input]
9470os.fpathconf -> long
9471
9472 fd: int
9473 name: path_confname
9474 /
9475
9476Return the configuration limit name for the file descriptor fd.
9477
9478If there is no limit, return -1.
9479[clinic start generated code]*/
9480
Larry Hastings2f936352014-08-05 14:04:04 +10009481static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009482os_fpathconf_impl(PyObject *module, int fd, int name)
9483/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009484{
9485 long limit;
9486
9487 errno = 0;
9488 limit = fpathconf(fd, name);
9489 if (limit == -1 && errno != 0)
9490 posix_error();
9491
9492 return limit;
9493}
9494#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009495
9496
9497#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009498/*[clinic input]
9499os.pathconf -> long
9500 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9501 name: path_confname
9502
9503Return the configuration limit name for the file or directory path.
9504
9505If there is no limit, return -1.
9506On some platforms, path may also be specified as an open file descriptor.
9507 If this functionality is unavailable, using it raises an exception.
9508[clinic start generated code]*/
9509
Larry Hastings2f936352014-08-05 14:04:04 +10009510static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009511os_pathconf_impl(PyObject *module, path_t *path, int name)
9512/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009513{
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009515
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009517#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009518 if (path->fd != -1)
9519 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009520 else
9521#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009522 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 if (limit == -1 && errno != 0) {
9524 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009525 /* could be a path or name problem */
9526 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009527 else
Larry Hastings2f936352014-08-05 14:04:04 +10009528 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 }
Larry Hastings2f936352014-08-05 14:04:04 +10009530
9531 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009532}
Larry Hastings2f936352014-08-05 14:04:04 +10009533#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009534
9535#ifdef HAVE_CONFSTR
9536static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009537#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009540#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009542#endif
9543#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009545#endif
Fred Draked86ed291999-12-15 15:34:33 +00009546#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009548#endif
9549#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009551#endif
9552#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009554#endif
9555#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009557#endif
Fred Drakec9680921999-12-13 16:37:25 +00009558#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
Fred Draked86ed291999-12-15 15:34:33 +00009582#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009584#endif
Fred Drakec9680921999-12-13 16:37:25 +00009585#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
Fred Draked86ed291999-12-15 15:34:33 +00009588#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009590#endif
9591#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009593#endif
9594#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009596#endif
9597#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009599#endif
Fred Drakec9680921999-12-13 16:37:25 +00009600#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
Fred Draked86ed291999-12-15 15:34:33 +00009648#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
9654#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009656#endif
9657#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009659#endif
9660#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009662#endif
9663#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009665#endif
9666#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009668#endif
9669#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
9672#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009674#endif
9675#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009677#endif
9678#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009680#endif
9681#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009683#endif
9684#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009686#endif
Fred Drakec9680921999-12-13 16:37:25 +00009687};
9688
9689static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009690conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009691{
9692 return conv_confname(arg, valuep, posix_constants_confstr,
9693 sizeof(posix_constants_confstr)
9694 / sizeof(struct constdef));
9695}
9696
Larry Hastings2f936352014-08-05 14:04:04 +10009697
9698/*[clinic input]
9699os.confstr
9700
9701 name: confstr_confname
9702 /
9703
9704Return a string-valued system configuration variable.
9705[clinic start generated code]*/
9706
Larry Hastings2f936352014-08-05 14:04:04 +10009707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009708os_confstr_impl(PyObject *module, int name)
9709/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009710{
9711 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009712 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009713 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009714
Victor Stinnercb043522010-09-10 23:49:04 +00009715 errno = 0;
9716 len = confstr(name, buffer, sizeof(buffer));
9717 if (len == 0) {
9718 if (errno) {
9719 posix_error();
9720 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009721 }
9722 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009723 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009724 }
9725 }
Victor Stinnercb043522010-09-10 23:49:04 +00009726
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009727 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009728 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009729 char *buf = PyMem_Malloc(len);
9730 if (buf == NULL)
9731 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009732 len2 = confstr(name, buf, len);
9733 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009734 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009735 PyMem_Free(buf);
9736 }
9737 else
9738 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009739 return result;
9740}
Larry Hastings2f936352014-08-05 14:04:04 +10009741#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009742
9743
9744#ifdef HAVE_SYSCONF
9745static struct constdef posix_constants_sysconf[] = {
9746#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
Fred Draked86ed291999-12-15 15:34:33 +00009776#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009778#endif
9779#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009781#endif
Fred Drakec9680921999-12-13 16:37:25 +00009782#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
Fred Drakec9680921999-12-13 16:37:25 +00009785#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
Fred Draked86ed291999-12-15 15:34:33 +00009800#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009802#endif
Fred Drakec9680921999-12-13 16:37:25 +00009803#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
Fred Draked86ed291999-12-15 15:34:33 +00009818#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009820#endif
Fred Drakec9680921999-12-13 16:37:25 +00009821#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
Fred Draked86ed291999-12-15 15:34:33 +00009890#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009892#endif
Fred Drakec9680921999-12-13 16:37:25 +00009893#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
Fred Draked86ed291999-12-15 15:34:33 +00009902#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009904#endif
Fred Drakec9680921999-12-13 16:37:25 +00009905#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
Fred Draked86ed291999-12-15 15:34:33 +00009908#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009910#endif
9911#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009913#endif
Fred Drakec9680921999-12-13 16:37:25 +00009914#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
Fred Draked86ed291999-12-15 15:34:33 +00009926#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009928#endif
Fred Drakec9680921999-12-13 16:37:25 +00009929#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
Fred Draked86ed291999-12-15 15:34:33 +00009950#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009952#endif
Fred Drakec9680921999-12-13 16:37:25 +00009953#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
Fred Draked86ed291999-12-15 15:34:33 +00009959#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009961#endif
Fred Drakec9680921999-12-13 16:37:25 +00009962#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
Fred Draked86ed291999-12-15 15:34:33 +00009989#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009991#endif
9992#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009994#endif
Fred Drakec9680921999-12-13 16:37:25 +00009995#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
Fred Draked86ed291999-12-15 15:34:33 +000010100#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010102#endif
Fred Drakec9680921999-12-13 16:37:25 +000010103#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238};
10239
10240static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010241conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010242{
10243 return conv_confname(arg, valuep, posix_constants_sysconf,
10244 sizeof(posix_constants_sysconf)
10245 / sizeof(struct constdef));
10246}
10247
Larry Hastings2f936352014-08-05 14:04:04 +100010248
10249/*[clinic input]
10250os.sysconf -> long
10251 name: sysconf_confname
10252 /
10253
10254Return an integer-valued system configuration variable.
10255[clinic start generated code]*/
10256
Larry Hastings2f936352014-08-05 14:04:04 +100010257static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010258os_sysconf_impl(PyObject *module, int name)
10259/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010260{
10261 long value;
10262
10263 errno = 0;
10264 value = sysconf(name);
10265 if (value == -1 && errno != 0)
10266 posix_error();
10267 return value;
10268}
10269#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010270
10271
Fred Drakebec628d1999-12-15 18:31:10 +000010272/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010273 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010274 * the exported dictionaries that are used to publish information about the
10275 * names available on the host platform.
10276 *
10277 * Sorting the table at runtime ensures that the table is properly ordered
10278 * when used, even for platforms we're not able to test on. It also makes
10279 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010280 */
Fred Drakebec628d1999-12-15 18:31:10 +000010281
10282static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010283cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010284{
10285 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010287 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010289
10290 return strcmp(c1->name, c2->name);
10291}
10292
10293static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010294setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010295 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010296{
Fred Drakebec628d1999-12-15 18:31:10 +000010297 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010298 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010299
10300 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10301 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010302 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010304
Barry Warsaw3155db32000-04-13 15:20:40 +000010305 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 PyObject *o = PyLong_FromLong(table[i].value);
10307 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10308 Py_XDECREF(o);
10309 Py_DECREF(d);
10310 return -1;
10311 }
10312 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010313 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010314 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010315}
10316
Fred Drakebec628d1999-12-15 18:31:10 +000010317/* Return -1 on failure, 0 on success. */
10318static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010319setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010320{
10321#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010322 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010323 sizeof(posix_constants_pathconf)
10324 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010325 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010326 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010327#endif
10328#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010329 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010330 sizeof(posix_constants_confstr)
10331 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010332 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010333 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010334#endif
10335#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010336 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010337 sizeof(posix_constants_sysconf)
10338 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010339 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010340 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010341#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010342 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010343}
Fred Draked86ed291999-12-15 15:34:33 +000010344
10345
Larry Hastings2f936352014-08-05 14:04:04 +100010346/*[clinic input]
10347os.abort
10348
10349Abort the interpreter immediately.
10350
10351This function 'dumps core' or otherwise fails in the hardest way possible
10352on the hosting operating system. This function never returns.
10353[clinic start generated code]*/
10354
Larry Hastings2f936352014-08-05 14:04:04 +100010355static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010356os_abort_impl(PyObject *module)
10357/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010358{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010359 abort();
10360 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010361#ifndef __clang__
10362 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10363 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10364 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010365 Py_FatalError("abort() called from Python code didn't abort!");
10366 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010367#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010368}
Fred Drakebec628d1999-12-15 18:31:10 +000010369
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010370#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010371/* Grab ShellExecute dynamically from shell32 */
10372static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010373static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10374 LPCWSTR, INT);
10375static int
10376check_ShellExecute()
10377{
10378 HINSTANCE hShell32;
10379
10380 /* only recheck */
10381 if (-1 == has_ShellExecute) {
10382 Py_BEGIN_ALLOW_THREADS
10383 hShell32 = LoadLibraryW(L"SHELL32");
10384 Py_END_ALLOW_THREADS
10385 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010386 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10387 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010388 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010389 } else {
10390 has_ShellExecute = 0;
10391 }
10392 }
10393 return has_ShellExecute;
10394}
10395
10396
Steve Dowercc16be82016-09-08 10:35:16 -070010397/*[clinic input]
10398os.startfile
10399 filepath: path_t
10400 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010401
Steve Dowercc16be82016-09-08 10:35:16 -070010402startfile(filepath [, operation])
10403
10404Start a file with its associated application.
10405
10406When "operation" is not specified or "open", this acts like
10407double-clicking the file in Explorer, or giving the file name as an
10408argument to the DOS "start" command: the file is opened with whatever
10409application (if any) its extension is associated.
10410When another "operation" is given, it specifies what should be done with
10411the file. A typical operation is "print".
10412
10413startfile returns as soon as the associated application is launched.
10414There is no option to wait for the application to close, and no way
10415to retrieve the application's exit status.
10416
10417The filepath is relative to the current directory. If you want to use
10418an absolute path, make sure the first character is not a slash ("/");
10419the underlying Win32 ShellExecute function doesn't work if it is.
10420[clinic start generated code]*/
10421
10422static PyObject *
10423os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10424/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10425{
10426 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010427
10428 if(!check_ShellExecute()) {
10429 /* If the OS doesn't have ShellExecute, return a
10430 NotImplementedError. */
10431 return PyErr_Format(PyExc_NotImplementedError,
10432 "startfile not available on this platform");
10433 }
10434
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010436 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010437 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 Py_END_ALLOW_THREADS
10439
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010441 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010442 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 }
Steve Dowercc16be82016-09-08 10:35:16 -070010444 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010445}
Larry Hastings2f936352014-08-05 14:04:04 +100010446#endif /* MS_WINDOWS */
10447
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010448
Martin v. Löwis438b5342002-12-27 10:16:42 +000010449#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010450/*[clinic input]
10451os.getloadavg
10452
10453Return average recent system load information.
10454
10455Return the number of processes in the system run queue averaged over
10456the last 1, 5, and 15 minutes as a tuple of three floats.
10457Raises OSError if the load average was unobtainable.
10458[clinic start generated code]*/
10459
Larry Hastings2f936352014-08-05 14:04:04 +100010460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010461os_getloadavg_impl(PyObject *module)
10462/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010463{
10464 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010465 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010466 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10467 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010468 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010469 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010470}
Larry Hastings2f936352014-08-05 14:04:04 +100010471#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010472
Larry Hastings2f936352014-08-05 14:04:04 +100010473
10474/*[clinic input]
10475os.device_encoding
10476 fd: int
10477
10478Return a string describing the encoding of a terminal's file descriptor.
10479
10480The file descriptor must be attached to a terminal.
10481If the device is not a terminal, return None.
10482[clinic start generated code]*/
10483
Larry Hastings2f936352014-08-05 14:04:04 +100010484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010485os_device_encoding_impl(PyObject *module, int fd)
10486/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010487{
Brett Cannonefb00c02012-02-29 18:31:31 -050010488 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010489}
10490
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010491
Larry Hastings2f936352014-08-05 14:04:04 +100010492#ifdef HAVE_SETRESUID
10493/*[clinic input]
10494os.setresuid
10495
10496 ruid: uid_t
10497 euid: uid_t
10498 suid: uid_t
10499 /
10500
10501Set the current process's real, effective, and saved user ids.
10502[clinic start generated code]*/
10503
Larry Hastings2f936352014-08-05 14:04:04 +100010504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010505os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10506/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010507{
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 if (setresuid(ruid, euid, suid) < 0)
10509 return posix_error();
10510 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010511}
Larry Hastings2f936352014-08-05 14:04:04 +100010512#endif /* HAVE_SETRESUID */
10513
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010514
10515#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010516/*[clinic input]
10517os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010518
Larry Hastings2f936352014-08-05 14:04:04 +100010519 rgid: gid_t
10520 egid: gid_t
10521 sgid: gid_t
10522 /
10523
10524Set the current process's real, effective, and saved group ids.
10525[clinic start generated code]*/
10526
Larry Hastings2f936352014-08-05 14:04:04 +100010527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010528os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10529/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010530{
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 if (setresgid(rgid, egid, sgid) < 0)
10532 return posix_error();
10533 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010534}
Larry Hastings2f936352014-08-05 14:04:04 +100010535#endif /* HAVE_SETRESGID */
10536
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010537
10538#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010539/*[clinic input]
10540os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010541
Larry Hastings2f936352014-08-05 14:04:04 +100010542Return a tuple of the current process's real, effective, and saved user ids.
10543[clinic start generated code]*/
10544
Larry Hastings2f936352014-08-05 14:04:04 +100010545static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010546os_getresuid_impl(PyObject *module)
10547/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010548{
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 if (getresuid(&ruid, &euid, &suid) < 0)
10551 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010552 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10553 _PyLong_FromUid(euid),
10554 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010555}
Larry Hastings2f936352014-08-05 14:04:04 +100010556#endif /* HAVE_GETRESUID */
10557
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010558
10559#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010560/*[clinic input]
10561os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010562
Larry Hastings2f936352014-08-05 14:04:04 +100010563Return a tuple of the current process's real, effective, and saved group ids.
10564[clinic start generated code]*/
10565
Larry Hastings2f936352014-08-05 14:04:04 +100010566static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010567os_getresgid_impl(PyObject *module)
10568/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010569{
10570 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 if (getresgid(&rgid, &egid, &sgid) < 0)
10572 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010573 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10574 _PyLong_FromGid(egid),
10575 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010576}
Larry Hastings2f936352014-08-05 14:04:04 +100010577#endif /* HAVE_GETRESGID */
10578
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010579
Benjamin Peterson9428d532011-09-14 11:45:52 -040010580#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010581/*[clinic input]
10582os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010583
Larry Hastings2f936352014-08-05 14:04:04 +100010584 path: path_t(allow_fd=True)
10585 attribute: path_t
10586 *
10587 follow_symlinks: bool = True
10588
10589Return the value of extended attribute attribute on path.
10590
10591path may be either a string or an open file descriptor.
10592If follow_symlinks is False, and the last element of the path is a symbolic
10593 link, getxattr will examine the symbolic link itself instead of the file
10594 the link points to.
10595
10596[clinic start generated code]*/
10597
Larry Hastings2f936352014-08-05 14:04:04 +100010598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010599os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010600 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010601/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010602{
10603 Py_ssize_t i;
10604 PyObject *buffer = NULL;
10605
10606 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10607 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010608
Larry Hastings9cf065c2012-06-22 16:30:09 -070010609 for (i = 0; ; i++) {
10610 void *ptr;
10611 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010612 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010613 Py_ssize_t buffer_size = buffer_sizes[i];
10614 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010615 path_error(path);
10616 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010617 }
10618 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10619 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010620 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622
Larry Hastings9cf065c2012-06-22 16:30:09 -070010623 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010624 if (path->fd >= 0)
10625 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010626 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010627 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010628 else
Larry Hastings2f936352014-08-05 14:04:04 +100010629 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010630 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010631
Larry Hastings9cf065c2012-06-22 16:30:09 -070010632 if (result < 0) {
10633 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634 if (errno == ERANGE)
10635 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010636 path_error(path);
10637 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010638 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639
Larry Hastings9cf065c2012-06-22 16:30:09 -070010640 if (result != buffer_size) {
10641 /* Can only shrink. */
10642 _PyBytes_Resize(&buffer, result);
10643 }
10644 break;
10645 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010646
Larry Hastings9cf065c2012-06-22 16:30:09 -070010647 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648}
10649
Larry Hastings2f936352014-08-05 14:04:04 +100010650
10651/*[clinic input]
10652os.setxattr
10653
10654 path: path_t(allow_fd=True)
10655 attribute: path_t
10656 value: Py_buffer
10657 flags: int = 0
10658 *
10659 follow_symlinks: bool = True
10660
10661Set extended attribute attribute on path to value.
10662
10663path may be either a string or an open file descriptor.
10664If follow_symlinks is False, and the last element of the path is a symbolic
10665 link, setxattr will modify the symbolic link itself instead of the file
10666 the link points to.
10667
10668[clinic start generated code]*/
10669
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010671os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010672 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010673/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010674{
Larry Hastings2f936352014-08-05 14:04:04 +100010675 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010676
Larry Hastings2f936352014-08-05 14:04:04 +100010677 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010678 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010679
Benjamin Peterson799bd802011-08-31 22:15:17 -040010680 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010681 if (path->fd > -1)
10682 result = fsetxattr(path->fd, attribute->narrow,
10683 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010685 result = setxattr(path->narrow, attribute->narrow,
10686 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010687 else
Larry Hastings2f936352014-08-05 14:04:04 +100010688 result = lsetxattr(path->narrow, attribute->narrow,
10689 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010690 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010691
Larry Hastings9cf065c2012-06-22 16:30:09 -070010692 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010693 path_error(path);
10694 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010695 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010696
Larry Hastings2f936352014-08-05 14:04:04 +100010697 Py_RETURN_NONE;
10698}
10699
10700
10701/*[clinic input]
10702os.removexattr
10703
10704 path: path_t(allow_fd=True)
10705 attribute: path_t
10706 *
10707 follow_symlinks: bool = True
10708
10709Remove extended attribute attribute on path.
10710
10711path may be either a string or an open file descriptor.
10712If follow_symlinks is False, and the last element of the path is a symbolic
10713 link, removexattr will modify the symbolic link itself instead of the file
10714 the link points to.
10715
10716[clinic start generated code]*/
10717
Larry Hastings2f936352014-08-05 14:04:04 +100010718static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010719os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010720 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010721/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010722{
10723 ssize_t result;
10724
10725 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10726 return NULL;
10727
10728 Py_BEGIN_ALLOW_THREADS;
10729 if (path->fd > -1)
10730 result = fremovexattr(path->fd, attribute->narrow);
10731 else if (follow_symlinks)
10732 result = removexattr(path->narrow, attribute->narrow);
10733 else
10734 result = lremovexattr(path->narrow, attribute->narrow);
10735 Py_END_ALLOW_THREADS;
10736
10737 if (result) {
10738 return path_error(path);
10739 }
10740
10741 Py_RETURN_NONE;
10742}
10743
10744
10745/*[clinic input]
10746os.listxattr
10747
10748 path: path_t(allow_fd=True, nullable=True) = None
10749 *
10750 follow_symlinks: bool = True
10751
10752Return a list of extended attributes on path.
10753
10754path may be either None, a string, or an open file descriptor.
10755if path is None, listxattr will examine the current directory.
10756If follow_symlinks is False, and the last element of the path is a symbolic
10757 link, listxattr will examine the symbolic link itself instead of the file
10758 the link points to.
10759[clinic start generated code]*/
10760
Larry Hastings2f936352014-08-05 14:04:04 +100010761static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010762os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10763/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010764{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765 Py_ssize_t i;
10766 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010767 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010769
Larry Hastings2f936352014-08-05 14:04:04 +100010770 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010772
Larry Hastings2f936352014-08-05 14:04:04 +100010773 name = path->narrow ? path->narrow : ".";
10774
Larry Hastings9cf065c2012-06-22 16:30:09 -070010775 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010776 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010777 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010778 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010779 Py_ssize_t buffer_size = buffer_sizes[i];
10780 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010781 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010782 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783 break;
10784 }
10785 buffer = PyMem_MALLOC(buffer_size);
10786 if (!buffer) {
10787 PyErr_NoMemory();
10788 break;
10789 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010790
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010792 if (path->fd > -1)
10793 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010794 else if (follow_symlinks)
10795 length = listxattr(name, buffer, buffer_size);
10796 else
10797 length = llistxattr(name, buffer, buffer_size);
10798 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010799
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010801 if (errno == ERANGE) {
10802 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010803 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010805 }
Larry Hastings2f936352014-08-05 14:04:04 +100010806 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010807 break;
10808 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010809
Larry Hastings9cf065c2012-06-22 16:30:09 -070010810 result = PyList_New(0);
10811 if (!result) {
10812 goto exit;
10813 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010814
Larry Hastings9cf065c2012-06-22 16:30:09 -070010815 end = buffer + length;
10816 for (trace = start = buffer; trace != end; trace++) {
10817 if (!*trace) {
10818 int error;
10819 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10820 trace - start);
10821 if (!attribute) {
10822 Py_DECREF(result);
10823 result = NULL;
10824 goto exit;
10825 }
10826 error = PyList_Append(result, attribute);
10827 Py_DECREF(attribute);
10828 if (error) {
10829 Py_DECREF(result);
10830 result = NULL;
10831 goto exit;
10832 }
10833 start = trace + 1;
10834 }
10835 }
10836 break;
10837 }
10838exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839 if (buffer)
10840 PyMem_FREE(buffer);
10841 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010842}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010843#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010844
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010845
Larry Hastings2f936352014-08-05 14:04:04 +100010846/*[clinic input]
10847os.urandom
10848
10849 size: Py_ssize_t
10850 /
10851
10852Return a bytes object containing random bytes suitable for cryptographic use.
10853[clinic start generated code]*/
10854
Larry Hastings2f936352014-08-05 14:04:04 +100010855static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010856os_urandom_impl(PyObject *module, Py_ssize_t size)
10857/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010858{
10859 PyObject *bytes;
10860 int result;
10861
Georg Brandl2fb477c2012-02-21 00:33:36 +010010862 if (size < 0)
10863 return PyErr_Format(PyExc_ValueError,
10864 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010865 bytes = PyBytes_FromStringAndSize(NULL, size);
10866 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010867 return NULL;
10868
Victor Stinnere66987e2016-09-06 16:33:52 -070010869 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010870 if (result == -1) {
10871 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010872 return NULL;
10873 }
Larry Hastings2f936352014-08-05 14:04:04 +100010874 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010875}
10876
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010877/* Terminal size querying */
10878
10879static PyTypeObject TerminalSizeType;
10880
10881PyDoc_STRVAR(TerminalSize_docstring,
10882 "A tuple of (columns, lines) for holding terminal window size");
10883
10884static PyStructSequence_Field TerminalSize_fields[] = {
10885 {"columns", "width of the terminal window in characters"},
10886 {"lines", "height of the terminal window in characters"},
10887 {NULL, NULL}
10888};
10889
10890static PyStructSequence_Desc TerminalSize_desc = {
10891 "os.terminal_size",
10892 TerminalSize_docstring,
10893 TerminalSize_fields,
10894 2,
10895};
10896
10897#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010898/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010899PyDoc_STRVAR(termsize__doc__,
10900 "Return the size of the terminal window as (columns, lines).\n" \
10901 "\n" \
10902 "The optional argument fd (default standard output) specifies\n" \
10903 "which file descriptor should be queried.\n" \
10904 "\n" \
10905 "If the file descriptor is not connected to a terminal, an OSError\n" \
10906 "is thrown.\n" \
10907 "\n" \
10908 "This function will only be defined if an implementation is\n" \
10909 "available for this system.\n" \
10910 "\n" \
10911 "shutil.get_terminal_size is the high-level function which should \n" \
10912 "normally be used, os.get_terminal_size is the low-level implementation.");
10913
10914static PyObject*
10915get_terminal_size(PyObject *self, PyObject *args)
10916{
10917 int columns, lines;
10918 PyObject *termsize;
10919
10920 int fd = fileno(stdout);
10921 /* Under some conditions stdout may not be connected and
10922 * fileno(stdout) may point to an invalid file descriptor. For example
10923 * GUI apps don't have valid standard streams by default.
10924 *
10925 * If this happens, and the optional fd argument is not present,
10926 * the ioctl below will fail returning EBADF. This is what we want.
10927 */
10928
10929 if (!PyArg_ParseTuple(args, "|i", &fd))
10930 return NULL;
10931
10932#ifdef TERMSIZE_USE_IOCTL
10933 {
10934 struct winsize w;
10935 if (ioctl(fd, TIOCGWINSZ, &w))
10936 return PyErr_SetFromErrno(PyExc_OSError);
10937 columns = w.ws_col;
10938 lines = w.ws_row;
10939 }
10940#endif /* TERMSIZE_USE_IOCTL */
10941
10942#ifdef TERMSIZE_USE_CONIO
10943 {
10944 DWORD nhandle;
10945 HANDLE handle;
10946 CONSOLE_SCREEN_BUFFER_INFO csbi;
10947 switch (fd) {
10948 case 0: nhandle = STD_INPUT_HANDLE;
10949 break;
10950 case 1: nhandle = STD_OUTPUT_HANDLE;
10951 break;
10952 case 2: nhandle = STD_ERROR_HANDLE;
10953 break;
10954 default:
10955 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10956 }
10957 handle = GetStdHandle(nhandle);
10958 if (handle == NULL)
10959 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10960 if (handle == INVALID_HANDLE_VALUE)
10961 return PyErr_SetFromWindowsErr(0);
10962
10963 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10964 return PyErr_SetFromWindowsErr(0);
10965
10966 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10967 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10968 }
10969#endif /* TERMSIZE_USE_CONIO */
10970
10971 termsize = PyStructSequence_New(&TerminalSizeType);
10972 if (termsize == NULL)
10973 return NULL;
10974 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10975 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10976 if (PyErr_Occurred()) {
10977 Py_DECREF(termsize);
10978 return NULL;
10979 }
10980 return termsize;
10981}
10982#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10983
Larry Hastings2f936352014-08-05 14:04:04 +100010984
10985/*[clinic input]
10986os.cpu_count
10987
Charles-François Natali80d62e62015-08-13 20:37:08 +010010988Return the number of CPUs in the system; return None if indeterminable.
10989
10990This number is not equivalent to the number of CPUs the current process can
10991use. The number of usable CPUs can be obtained with
10992``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010993[clinic start generated code]*/
10994
Larry Hastings2f936352014-08-05 14:04:04 +100010995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010996os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010997/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010998{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010999 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011000#ifdef MS_WINDOWS
11001 SYSTEM_INFO sysinfo;
11002 GetSystemInfo(&sysinfo);
11003 ncpu = sysinfo.dwNumberOfProcessors;
11004#elif defined(__hpux)
11005 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11006#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11007 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011008#elif defined(__DragonFly__) || \
11009 defined(__OpenBSD__) || \
11010 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011011 defined(__NetBSD__) || \
11012 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011013 int mib[2];
11014 size_t len = sizeof(ncpu);
11015 mib[0] = CTL_HW;
11016 mib[1] = HW_NCPU;
11017 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11018 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011019#endif
11020 if (ncpu >= 1)
11021 return PyLong_FromLong(ncpu);
11022 else
11023 Py_RETURN_NONE;
11024}
11025
Victor Stinnerdaf45552013-08-28 00:53:59 +020011026
Larry Hastings2f936352014-08-05 14:04:04 +100011027/*[clinic input]
11028os.get_inheritable -> bool
11029
11030 fd: int
11031 /
11032
11033Get the close-on-exe flag of the specified file descriptor.
11034[clinic start generated code]*/
11035
Larry Hastings2f936352014-08-05 14:04:04 +100011036static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011037os_get_inheritable_impl(PyObject *module, int fd)
11038/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011039{
Steve Dower8fc89802015-04-12 00:26:27 -040011040 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011041 _Py_BEGIN_SUPPRESS_IPH
11042 return_value = _Py_get_inheritable(fd);
11043 _Py_END_SUPPRESS_IPH
11044 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011045}
11046
11047
11048/*[clinic input]
11049os.set_inheritable
11050 fd: int
11051 inheritable: int
11052 /
11053
11054Set the inheritable flag of the specified file descriptor.
11055[clinic start generated code]*/
11056
Larry Hastings2f936352014-08-05 14:04:04 +100011057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011058os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11059/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011060{
Steve Dower8fc89802015-04-12 00:26:27 -040011061 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011062
Steve Dower8fc89802015-04-12 00:26:27 -040011063 _Py_BEGIN_SUPPRESS_IPH
11064 result = _Py_set_inheritable(fd, inheritable, NULL);
11065 _Py_END_SUPPRESS_IPH
11066 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011067 return NULL;
11068 Py_RETURN_NONE;
11069}
11070
11071
11072#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011073/*[clinic input]
11074os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011075 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011076 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011077
Larry Hastings2f936352014-08-05 14:04:04 +100011078Get the close-on-exe flag of the specified file descriptor.
11079[clinic start generated code]*/
11080
Larry Hastings2f936352014-08-05 14:04:04 +100011081static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011082os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011083/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011084{
11085 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011086
11087 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11088 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011089 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011090 }
11091
Larry Hastings2f936352014-08-05 14:04:04 +100011092 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011093}
11094
Victor Stinnerdaf45552013-08-28 00:53:59 +020011095
Larry Hastings2f936352014-08-05 14:04:04 +100011096/*[clinic input]
11097os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011098 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011099 inheritable: bool
11100 /
11101
11102Set the inheritable flag of the specified handle.
11103[clinic start generated code]*/
11104
Larry Hastings2f936352014-08-05 14:04:04 +100011105static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011106os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011107 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011108/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011109{
11110 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011111 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11112 PyErr_SetFromWindowsErr(0);
11113 return NULL;
11114 }
11115 Py_RETURN_NONE;
11116}
Larry Hastings2f936352014-08-05 14:04:04 +100011117#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011118
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011119#ifndef MS_WINDOWS
11120PyDoc_STRVAR(get_blocking__doc__,
11121 "get_blocking(fd) -> bool\n" \
11122 "\n" \
11123 "Get the blocking mode of the file descriptor:\n" \
11124 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11125
11126static PyObject*
11127posix_get_blocking(PyObject *self, PyObject *args)
11128{
11129 int fd;
11130 int blocking;
11131
11132 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11133 return NULL;
11134
Steve Dower8fc89802015-04-12 00:26:27 -040011135 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011136 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011137 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011138 if (blocking < 0)
11139 return NULL;
11140 return PyBool_FromLong(blocking);
11141}
11142
11143PyDoc_STRVAR(set_blocking__doc__,
11144 "set_blocking(fd, blocking)\n" \
11145 "\n" \
11146 "Set the blocking mode of the specified file descriptor.\n" \
11147 "Set the O_NONBLOCK flag if blocking is False,\n" \
11148 "clear the O_NONBLOCK flag otherwise.");
11149
11150static PyObject*
11151posix_set_blocking(PyObject *self, PyObject *args)
11152{
Steve Dower8fc89802015-04-12 00:26:27 -040011153 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011154
11155 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11156 return NULL;
11157
Steve Dower8fc89802015-04-12 00:26:27 -040011158 _Py_BEGIN_SUPPRESS_IPH
11159 result = _Py_set_blocking(fd, blocking);
11160 _Py_END_SUPPRESS_IPH
11161 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011162 return NULL;
11163 Py_RETURN_NONE;
11164}
11165#endif /* !MS_WINDOWS */
11166
11167
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011168/*[clinic input]
11169class os.DirEntry "DirEntry *" "&DirEntryType"
11170[clinic start generated code]*/
11171/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011172
11173typedef struct {
11174 PyObject_HEAD
11175 PyObject *name;
11176 PyObject *path;
11177 PyObject *stat;
11178 PyObject *lstat;
11179#ifdef MS_WINDOWS
11180 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011181 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011182 int got_file_index;
11183#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011184#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011185 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011186#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011187 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011188 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011189#endif
11190} DirEntry;
11191
11192static void
11193DirEntry_dealloc(DirEntry *entry)
11194{
11195 Py_XDECREF(entry->name);
11196 Py_XDECREF(entry->path);
11197 Py_XDECREF(entry->stat);
11198 Py_XDECREF(entry->lstat);
11199 Py_TYPE(entry)->tp_free((PyObject *)entry);
11200}
11201
11202/* Forward reference */
11203static int
11204DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11205
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011206/*[clinic input]
11207os.DirEntry.is_symlink -> bool
11208
11209Return True if the entry is a symbolic link; cached per entry.
11210[clinic start generated code]*/
11211
Victor Stinner6036e442015-03-08 01:58:04 +010011212static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011213os_DirEntry_is_symlink_impl(DirEntry *self)
11214/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011215{
11216#ifdef MS_WINDOWS
11217 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011218#elif defined(HAVE_DIRENT_D_TYPE)
11219 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011220 if (self->d_type != DT_UNKNOWN)
11221 return self->d_type == DT_LNK;
11222 else
11223 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011224#else
11225 /* POSIX without d_type */
11226 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011227#endif
11228}
11229
11230static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011231DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11232{
11233 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011234 STRUCT_STAT st;
11235 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011236
11237#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011238 if (!PyUnicode_FSDecoder(self->path, &ub))
11239 return NULL;
11240 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011241#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011242 if (!PyUnicode_FSConverter(self->path, &ub))
11243 return NULL;
11244 const char *path = PyBytes_AS_STRING(ub);
11245 if (self->dir_fd != DEFAULT_DIR_FD) {
11246#ifdef HAVE_FSTATAT
11247 result = fstatat(self->dir_fd, path, &st,
11248 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11249#else
11250 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11251 return NULL;
11252#endif /* HAVE_FSTATAT */
11253 }
11254 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011255#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011256 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011257 if (follow_symlinks)
11258 result = STAT(path, &st);
11259 else
11260 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011261 }
11262 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011263
11264 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011265 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011266
11267 return _pystat_fromstructstat(&st);
11268}
11269
11270static PyObject *
11271DirEntry_get_lstat(DirEntry *self)
11272{
11273 if (!self->lstat) {
11274#ifdef MS_WINDOWS
11275 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11276#else /* POSIX */
11277 self->lstat = DirEntry_fetch_stat(self, 0);
11278#endif
11279 }
11280 Py_XINCREF(self->lstat);
11281 return self->lstat;
11282}
11283
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011284/*[clinic input]
11285os.DirEntry.stat
11286 *
11287 follow_symlinks: bool = True
11288
11289Return stat_result object for the entry; cached per entry.
11290[clinic start generated code]*/
11291
Victor Stinner6036e442015-03-08 01:58:04 +010011292static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011293os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11294/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011295{
11296 if (!follow_symlinks)
11297 return DirEntry_get_lstat(self);
11298
11299 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011300 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011301 if (result == -1)
11302 return NULL;
11303 else if (result)
11304 self->stat = DirEntry_fetch_stat(self, 1);
11305 else
11306 self->stat = DirEntry_get_lstat(self);
11307 }
11308
11309 Py_XINCREF(self->stat);
11310 return self->stat;
11311}
11312
Victor Stinner6036e442015-03-08 01:58:04 +010011313/* Set exception and return -1 on error, 0 for False, 1 for True */
11314static int
11315DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11316{
11317 PyObject *stat = NULL;
11318 PyObject *st_mode = NULL;
11319 long mode;
11320 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011321#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011322 int is_symlink;
11323 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011324#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011325#ifdef MS_WINDOWS
11326 unsigned long dir_bits;
11327#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011328 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011329
11330#ifdef MS_WINDOWS
11331 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11332 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011333#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011334 is_symlink = self->d_type == DT_LNK;
11335 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11336#endif
11337
Victor Stinner35a97c02015-03-08 02:59:09 +010011338#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011339 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011340#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011341 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011342 if (!stat) {
11343 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11344 /* If file doesn't exist (anymore), then return False
11345 (i.e., say it's not a file/directory) */
11346 PyErr_Clear();
11347 return 0;
11348 }
11349 goto error;
11350 }
11351 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11352 if (!st_mode)
11353 goto error;
11354
11355 mode = PyLong_AsLong(st_mode);
11356 if (mode == -1 && PyErr_Occurred())
11357 goto error;
11358 Py_CLEAR(st_mode);
11359 Py_CLEAR(stat);
11360 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011361#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011362 }
11363 else if (is_symlink) {
11364 assert(mode_bits != S_IFLNK);
11365 result = 0;
11366 }
11367 else {
11368 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11369#ifdef MS_WINDOWS
11370 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11371 if (mode_bits == S_IFDIR)
11372 result = dir_bits != 0;
11373 else
11374 result = dir_bits == 0;
11375#else /* POSIX */
11376 if (mode_bits == S_IFDIR)
11377 result = self->d_type == DT_DIR;
11378 else
11379 result = self->d_type == DT_REG;
11380#endif
11381 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011382#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011383
11384 return result;
11385
11386error:
11387 Py_XDECREF(st_mode);
11388 Py_XDECREF(stat);
11389 return -1;
11390}
11391
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011392/*[clinic input]
11393os.DirEntry.is_dir -> bool
11394 *
11395 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011396
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011397Return True if the entry is a directory; cached per entry.
11398[clinic start generated code]*/
11399
11400static int
11401os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11402/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11403{
11404 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011405}
11406
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011407/*[clinic input]
11408os.DirEntry.is_file -> bool
11409 *
11410 follow_symlinks: bool = True
11411
11412Return True if the entry is a file; cached per entry.
11413[clinic start generated code]*/
11414
11415static int
11416os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11417/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011418{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011419 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011420}
11421
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011422/*[clinic input]
11423os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011424
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011425Return inode of the entry; cached per entry.
11426[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011427
11428static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011429os_DirEntry_inode_impl(DirEntry *self)
11430/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011431{
11432#ifdef MS_WINDOWS
11433 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011434 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011435 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011436 STRUCT_STAT stat;
11437 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011438
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011439 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011440 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011441 path = PyUnicode_AsUnicode(unicode);
11442 result = LSTAT(path, &stat);
11443 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011444
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011445 if (result != 0)
11446 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011447
11448 self->win32_file_index = stat.st_ino;
11449 self->got_file_index = 1;
11450 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011451 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11452 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011453#else /* POSIX */
11454#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011455 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011456#else
11457 return PyLong_FromLong((long)self->d_ino);
11458#endif
11459#endif
11460}
11461
11462static PyObject *
11463DirEntry_repr(DirEntry *self)
11464{
11465 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11466}
11467
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011468/*[clinic input]
11469os.DirEntry.__fspath__
11470
11471Returns the path for the entry.
11472[clinic start generated code]*/
11473
Brett Cannon96881cd2016-06-10 14:37:21 -070011474static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011475os_DirEntry___fspath___impl(DirEntry *self)
11476/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011477{
11478 Py_INCREF(self->path);
11479 return self->path;
11480}
11481
Victor Stinner6036e442015-03-08 01:58:04 +010011482static PyMemberDef DirEntry_members[] = {
11483 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11484 "the entry's base filename, relative to scandir() \"path\" argument"},
11485 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11486 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11487 {NULL}
11488};
11489
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011490#include "clinic/posixmodule.c.h"
11491
Victor Stinner6036e442015-03-08 01:58:04 +010011492static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011493 OS_DIRENTRY_IS_DIR_METHODDEF
11494 OS_DIRENTRY_IS_FILE_METHODDEF
11495 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11496 OS_DIRENTRY_STAT_METHODDEF
11497 OS_DIRENTRY_INODE_METHODDEF
11498 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011499 {NULL}
11500};
11501
Benjamin Peterson5646de42015-04-12 17:56:34 -040011502static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011503 PyVarObject_HEAD_INIT(NULL, 0)
11504 MODNAME ".DirEntry", /* tp_name */
11505 sizeof(DirEntry), /* tp_basicsize */
11506 0, /* tp_itemsize */
11507 /* methods */
11508 (destructor)DirEntry_dealloc, /* tp_dealloc */
11509 0, /* tp_print */
11510 0, /* tp_getattr */
11511 0, /* tp_setattr */
11512 0, /* tp_compare */
11513 (reprfunc)DirEntry_repr, /* tp_repr */
11514 0, /* tp_as_number */
11515 0, /* tp_as_sequence */
11516 0, /* tp_as_mapping */
11517 0, /* tp_hash */
11518 0, /* tp_call */
11519 0, /* tp_str */
11520 0, /* tp_getattro */
11521 0, /* tp_setattro */
11522 0, /* tp_as_buffer */
11523 Py_TPFLAGS_DEFAULT, /* tp_flags */
11524 0, /* tp_doc */
11525 0, /* tp_traverse */
11526 0, /* tp_clear */
11527 0, /* tp_richcompare */
11528 0, /* tp_weaklistoffset */
11529 0, /* tp_iter */
11530 0, /* tp_iternext */
11531 DirEntry_methods, /* tp_methods */
11532 DirEntry_members, /* tp_members */
11533};
11534
11535#ifdef MS_WINDOWS
11536
11537static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011538join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011539{
11540 Py_ssize_t path_len;
11541 Py_ssize_t size;
11542 wchar_t *result;
11543 wchar_t ch;
11544
11545 if (!path_wide) { /* Default arg: "." */
11546 path_wide = L".";
11547 path_len = 1;
11548 }
11549 else {
11550 path_len = wcslen(path_wide);
11551 }
11552
11553 /* The +1's are for the path separator and the NUL */
11554 size = path_len + 1 + wcslen(filename) + 1;
11555 result = PyMem_New(wchar_t, size);
11556 if (!result) {
11557 PyErr_NoMemory();
11558 return NULL;
11559 }
11560 wcscpy(result, path_wide);
11561 if (path_len > 0) {
11562 ch = result[path_len - 1];
11563 if (ch != SEP && ch != ALTSEP && ch != L':')
11564 result[path_len++] = SEP;
11565 wcscpy(result + path_len, filename);
11566 }
11567 return result;
11568}
11569
11570static PyObject *
11571DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11572{
11573 DirEntry *entry;
11574 BY_HANDLE_FILE_INFORMATION file_info;
11575 ULONG reparse_tag;
11576 wchar_t *joined_path;
11577
11578 entry = PyObject_New(DirEntry, &DirEntryType);
11579 if (!entry)
11580 return NULL;
11581 entry->name = NULL;
11582 entry->path = NULL;
11583 entry->stat = NULL;
11584 entry->lstat = NULL;
11585 entry->got_file_index = 0;
11586
11587 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11588 if (!entry->name)
11589 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011590 if (path->narrow) {
11591 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11592 if (!entry->name)
11593 goto error;
11594 }
Victor Stinner6036e442015-03-08 01:58:04 +010011595
11596 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11597 if (!joined_path)
11598 goto error;
11599
11600 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11601 PyMem_Free(joined_path);
11602 if (!entry->path)
11603 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011604 if (path->narrow) {
11605 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11606 if (!entry->path)
11607 goto error;
11608 }
Victor Stinner6036e442015-03-08 01:58:04 +010011609
Steve Dowercc16be82016-09-08 10:35:16 -070011610 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011611 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11612
11613 return (PyObject *)entry;
11614
11615error:
11616 Py_DECREF(entry);
11617 return NULL;
11618}
11619
11620#else /* POSIX */
11621
11622static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011623join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011624{
11625 Py_ssize_t path_len;
11626 Py_ssize_t size;
11627 char *result;
11628
11629 if (!path_narrow) { /* Default arg: "." */
11630 path_narrow = ".";
11631 path_len = 1;
11632 }
11633 else {
11634 path_len = strlen(path_narrow);
11635 }
11636
11637 if (filename_len == -1)
11638 filename_len = strlen(filename);
11639
11640 /* The +1's are for the path separator and the NUL */
11641 size = path_len + 1 + filename_len + 1;
11642 result = PyMem_New(char, size);
11643 if (!result) {
11644 PyErr_NoMemory();
11645 return NULL;
11646 }
11647 strcpy(result, path_narrow);
11648 if (path_len > 0 && result[path_len - 1] != '/')
11649 result[path_len++] = '/';
11650 strcpy(result + path_len, filename);
11651 return result;
11652}
11653
11654static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011655DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011656 ino_t d_ino
11657#ifdef HAVE_DIRENT_D_TYPE
11658 , unsigned char d_type
11659#endif
11660 )
Victor Stinner6036e442015-03-08 01:58:04 +010011661{
11662 DirEntry *entry;
11663 char *joined_path;
11664
11665 entry = PyObject_New(DirEntry, &DirEntryType);
11666 if (!entry)
11667 return NULL;
11668 entry->name = NULL;
11669 entry->path = NULL;
11670 entry->stat = NULL;
11671 entry->lstat = NULL;
11672
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011673 if (path->fd != -1) {
11674 entry->dir_fd = path->fd;
11675 joined_path = NULL;
11676 }
11677 else {
11678 entry->dir_fd = DEFAULT_DIR_FD;
11679 joined_path = join_path_filename(path->narrow, name, name_len);
11680 if (!joined_path)
11681 goto error;
11682 }
Victor Stinner6036e442015-03-08 01:58:04 +010011683
11684 if (!path->narrow || !PyBytes_Check(path->object)) {
11685 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011686 if (joined_path)
11687 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011688 }
11689 else {
11690 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011691 if (joined_path)
11692 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011693 }
11694 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011695 if (!entry->name)
11696 goto error;
11697
11698 if (path->fd != -1) {
11699 entry->path = entry->name;
11700 Py_INCREF(entry->path);
11701 }
11702 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011703 goto error;
11704
Victor Stinner35a97c02015-03-08 02:59:09 +010011705#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011706 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011707#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011708 entry->d_ino = d_ino;
11709
11710 return (PyObject *)entry;
11711
11712error:
11713 Py_XDECREF(entry);
11714 return NULL;
11715}
11716
11717#endif
11718
11719
11720typedef struct {
11721 PyObject_HEAD
11722 path_t path;
11723#ifdef MS_WINDOWS
11724 HANDLE handle;
11725 WIN32_FIND_DATAW file_data;
11726 int first_time;
11727#else /* POSIX */
11728 DIR *dirp;
11729#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011730#ifdef HAVE_FDOPENDIR
11731 int fd;
11732#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011733} ScandirIterator;
11734
11735#ifdef MS_WINDOWS
11736
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011737static int
11738ScandirIterator_is_closed(ScandirIterator *iterator)
11739{
11740 return iterator->handle == INVALID_HANDLE_VALUE;
11741}
11742
Victor Stinner6036e442015-03-08 01:58:04 +010011743static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011744ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011745{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011746 HANDLE handle = iterator->handle;
11747
11748 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011749 return;
11750
Victor Stinner6036e442015-03-08 01:58:04 +010011751 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011752 Py_BEGIN_ALLOW_THREADS
11753 FindClose(handle);
11754 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011755}
11756
11757static PyObject *
11758ScandirIterator_iternext(ScandirIterator *iterator)
11759{
11760 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11761 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011762 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011763
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011764 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011765 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011766 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011767
11768 while (1) {
11769 if (!iterator->first_time) {
11770 Py_BEGIN_ALLOW_THREADS
11771 success = FindNextFileW(iterator->handle, file_data);
11772 Py_END_ALLOW_THREADS
11773 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011774 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011775 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011776 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011777 break;
11778 }
11779 }
11780 iterator->first_time = 0;
11781
11782 /* Skip over . and .. */
11783 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011784 wcscmp(file_data->cFileName, L"..") != 0) {
11785 entry = DirEntry_from_find_data(&iterator->path, file_data);
11786 if (!entry)
11787 break;
11788 return entry;
11789 }
Victor Stinner6036e442015-03-08 01:58:04 +010011790
11791 /* Loop till we get a non-dot directory or finish iterating */
11792 }
11793
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011794 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011795 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011796 return NULL;
11797}
11798
11799#else /* POSIX */
11800
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011801static int
11802ScandirIterator_is_closed(ScandirIterator *iterator)
11803{
11804 return !iterator->dirp;
11805}
11806
Victor Stinner6036e442015-03-08 01:58:04 +010011807static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011808ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011809{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011810 DIR *dirp = iterator->dirp;
11811
11812 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011813 return;
11814
Victor Stinner6036e442015-03-08 01:58:04 +010011815 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011816 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011817#ifdef HAVE_FDOPENDIR
11818 if (iterator->path.fd != -1)
11819 rewinddir(dirp);
11820#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011821 closedir(dirp);
11822 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011823 return;
11824}
11825
11826static PyObject *
11827ScandirIterator_iternext(ScandirIterator *iterator)
11828{
11829 struct dirent *direntp;
11830 Py_ssize_t name_len;
11831 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011832 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011833
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011834 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011835 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011836 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011837
11838 while (1) {
11839 errno = 0;
11840 Py_BEGIN_ALLOW_THREADS
11841 direntp = readdir(iterator->dirp);
11842 Py_END_ALLOW_THREADS
11843
11844 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011845 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011846 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011847 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011848 break;
11849 }
11850
11851 /* Skip over . and .. */
11852 name_len = NAMLEN(direntp);
11853 is_dot = direntp->d_name[0] == '.' &&
11854 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11855 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011856 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011857 name_len, direntp->d_ino
11858#ifdef HAVE_DIRENT_D_TYPE
11859 , direntp->d_type
11860#endif
11861 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011862 if (!entry)
11863 break;
11864 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011865 }
11866
11867 /* Loop till we get a non-dot directory or finish iterating */
11868 }
11869
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011870 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011871 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011872 return NULL;
11873}
11874
11875#endif
11876
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011877static PyObject *
11878ScandirIterator_close(ScandirIterator *self, PyObject *args)
11879{
11880 ScandirIterator_closedir(self);
11881 Py_RETURN_NONE;
11882}
11883
11884static PyObject *
11885ScandirIterator_enter(PyObject *self, PyObject *args)
11886{
11887 Py_INCREF(self);
11888 return self;
11889}
11890
11891static PyObject *
11892ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11893{
11894 ScandirIterator_closedir(self);
11895 Py_RETURN_NONE;
11896}
11897
Victor Stinner6036e442015-03-08 01:58:04 +010011898static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011899ScandirIterator_finalize(ScandirIterator *iterator)
11900{
11901 PyObject *error_type, *error_value, *error_traceback;
11902
11903 /* Save the current exception, if any. */
11904 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11905
11906 if (!ScandirIterator_is_closed(iterator)) {
11907 ScandirIterator_closedir(iterator);
11908
11909 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11910 "unclosed scandir iterator %R", iterator)) {
11911 /* Spurious errors can appear at shutdown */
11912 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11913 PyErr_WriteUnraisable((PyObject *) iterator);
11914 }
11915 }
11916 }
11917
Victor Stinner7bfa4092016-03-23 00:43:54 +010011918 path_cleanup(&iterator->path);
11919
11920 /* Restore the saved exception. */
11921 PyErr_Restore(error_type, error_value, error_traceback);
11922}
11923
11924static void
Victor Stinner6036e442015-03-08 01:58:04 +010011925ScandirIterator_dealloc(ScandirIterator *iterator)
11926{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011927 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11928 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011929
Victor Stinner6036e442015-03-08 01:58:04 +010011930 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11931}
11932
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011933static PyMethodDef ScandirIterator_methods[] = {
11934 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11935 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11936 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11937 {NULL}
11938};
11939
Benjamin Peterson5646de42015-04-12 17:56:34 -040011940static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011941 PyVarObject_HEAD_INIT(NULL, 0)
11942 MODNAME ".ScandirIterator", /* tp_name */
11943 sizeof(ScandirIterator), /* tp_basicsize */
11944 0, /* tp_itemsize */
11945 /* methods */
11946 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11947 0, /* tp_print */
11948 0, /* tp_getattr */
11949 0, /* tp_setattr */
11950 0, /* tp_compare */
11951 0, /* tp_repr */
11952 0, /* tp_as_number */
11953 0, /* tp_as_sequence */
11954 0, /* tp_as_mapping */
11955 0, /* tp_hash */
11956 0, /* tp_call */
11957 0, /* tp_str */
11958 0, /* tp_getattro */
11959 0, /* tp_setattro */
11960 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011961 Py_TPFLAGS_DEFAULT
11962 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011963 0, /* tp_doc */
11964 0, /* tp_traverse */
11965 0, /* tp_clear */
11966 0, /* tp_richcompare */
11967 0, /* tp_weaklistoffset */
11968 PyObject_SelfIter, /* tp_iter */
11969 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011970 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011971 0, /* tp_members */
11972 0, /* tp_getset */
11973 0, /* tp_base */
11974 0, /* tp_dict */
11975 0, /* tp_descr_get */
11976 0, /* tp_descr_set */
11977 0, /* tp_dictoffset */
11978 0, /* tp_init */
11979 0, /* tp_alloc */
11980 0, /* tp_new */
11981 0, /* tp_free */
11982 0, /* tp_is_gc */
11983 0, /* tp_bases */
11984 0, /* tp_mro */
11985 0, /* tp_cache */
11986 0, /* tp_subclasses */
11987 0, /* tp_weaklist */
11988 0, /* tp_del */
11989 0, /* tp_version_tag */
11990 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011991};
11992
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011993/*[clinic input]
11994os.scandir
11995
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011996 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011997
11998Return an iterator of DirEntry objects for given path.
11999
12000path can be specified as either str, bytes or path-like object. If path
12001is bytes, the names of yielded DirEntry objects will also be bytes; in
12002all other circumstances they will be str.
12003
12004If path is None, uses the path='.'.
12005[clinic start generated code]*/
12006
Victor Stinner6036e442015-03-08 01:58:04 +010012007static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012008os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012009/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012010{
12011 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012012#ifdef MS_WINDOWS
12013 wchar_t *path_strW;
12014#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012015 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012016#ifdef HAVE_FDOPENDIR
12017 int fd = -1;
12018#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012019#endif
12020
12021 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12022 if (!iterator)
12023 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012024
12025#ifdef MS_WINDOWS
12026 iterator->handle = INVALID_HANDLE_VALUE;
12027#else
12028 iterator->dirp = NULL;
12029#endif
12030
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012031 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012032 /* Move the ownership to iterator->path */
12033 path->object = NULL;
12034 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012035
12036#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012037 iterator->first_time = 1;
12038
12039 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12040 if (!path_strW)
12041 goto error;
12042
12043 Py_BEGIN_ALLOW_THREADS
12044 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12045 Py_END_ALLOW_THREADS
12046
12047 PyMem_Free(path_strW);
12048
12049 if (iterator->handle == INVALID_HANDLE_VALUE) {
12050 path_error(&iterator->path);
12051 goto error;
12052 }
12053#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012054 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012055#ifdef HAVE_FDOPENDIR
12056 if (path->fd != -1) {
12057 /* closedir() closes the FD, so we duplicate it */
12058 fd = _Py_dup(path->fd);
12059 if (fd == -1)
12060 goto error;
12061
12062 Py_BEGIN_ALLOW_THREADS
12063 iterator->dirp = fdopendir(fd);
12064 Py_END_ALLOW_THREADS
12065 }
12066 else
12067#endif
12068 {
12069 if (iterator->path.narrow)
12070 path_str = iterator->path.narrow;
12071 else
12072 path_str = ".";
12073
12074 Py_BEGIN_ALLOW_THREADS
12075 iterator->dirp = opendir(path_str);
12076 Py_END_ALLOW_THREADS
12077 }
Victor Stinner6036e442015-03-08 01:58:04 +010012078
12079 if (!iterator->dirp) {
12080 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012081#ifdef HAVE_FDOPENDIR
12082 if (fd != -1) {
12083 Py_BEGIN_ALLOW_THREADS
12084 close(fd);
12085 Py_END_ALLOW_THREADS
12086 }
12087#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012088 goto error;
12089 }
12090#endif
12091
12092 return (PyObject *)iterator;
12093
12094error:
12095 Py_DECREF(iterator);
12096 return NULL;
12097}
12098
Ethan Furman410ef8e2016-06-04 12:06:26 -070012099/*
12100 Return the file system path representation of the object.
12101
12102 If the object is str or bytes, then allow it to pass through with
12103 an incremented refcount. If the object defines __fspath__(), then
12104 return the result of that method. All other types raise a TypeError.
12105*/
12106PyObject *
12107PyOS_FSPath(PyObject *path)
12108{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012109 /* For error message reasons, this function is manually inlined in
12110 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012111 _Py_IDENTIFIER(__fspath__);
12112 PyObject *func = NULL;
12113 PyObject *path_repr = NULL;
12114
12115 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12116 Py_INCREF(path);
12117 return path;
12118 }
12119
12120 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12121 if (NULL == func) {
12122 return PyErr_Format(PyExc_TypeError,
12123 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012124 "not %.200s",
12125 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012126 }
12127
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012128 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012129 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012130 if (NULL == path_repr) {
12131 return NULL;
12132 }
12133
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012134 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12135 PyErr_Format(PyExc_TypeError,
12136 "expected %.200s.__fspath__() to return str or bytes, "
12137 "not %.200s", Py_TYPE(path)->tp_name,
12138 Py_TYPE(path_repr)->tp_name);
12139 Py_DECREF(path_repr);
12140 return NULL;
12141 }
12142
Ethan Furman410ef8e2016-06-04 12:06:26 -070012143 return path_repr;
12144}
12145
12146/*[clinic input]
12147os.fspath
12148
12149 path: object
12150
12151Return the file system path representation of the object.
12152
Brett Cannonb4f43e92016-06-09 14:32:08 -070012153If the object is str or bytes, then allow it to pass through as-is. If the
12154object defines __fspath__(), then return the result of that method. All other
12155types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012156[clinic start generated code]*/
12157
12158static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012159os_fspath_impl(PyObject *module, PyObject *path)
12160/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012161{
12162 return PyOS_FSPath(path);
12163}
Victor Stinner6036e442015-03-08 01:58:04 +010012164
Victor Stinner9b1f4742016-09-06 16:18:52 -070012165#ifdef HAVE_GETRANDOM_SYSCALL
12166/*[clinic input]
12167os.getrandom
12168
12169 size: Py_ssize_t
12170 flags: int=0
12171
12172Obtain a series of random bytes.
12173[clinic start generated code]*/
12174
12175static PyObject *
12176os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12177/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12178{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012179 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012180 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012181
12182 if (size < 0) {
12183 errno = EINVAL;
12184 return posix_error();
12185 }
12186
Victor Stinnerec2319c2016-09-20 23:00:59 +020012187 bytes = PyBytes_FromStringAndSize(NULL, size);
12188 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012189 PyErr_NoMemory();
12190 return NULL;
12191 }
12192
12193 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012194 n = syscall(SYS_getrandom,
12195 PyBytes_AS_STRING(bytes),
12196 PyBytes_GET_SIZE(bytes),
12197 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012198 if (n < 0 && errno == EINTR) {
12199 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012200 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012201 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012202
12203 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012204 continue;
12205 }
12206 break;
12207 }
12208
12209 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012210 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012211 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012212 }
12213
Victor Stinnerec2319c2016-09-20 23:00:59 +020012214 if (n != size) {
12215 _PyBytes_Resize(&bytes, n);
12216 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012217
12218 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012219
12220error:
12221 Py_DECREF(bytes);
12222 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012223}
12224#endif /* HAVE_GETRANDOM_SYSCALL */
12225
Larry Hastings31826802013-10-19 00:09:25 -070012226
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012227static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012228
12229 OS_STAT_METHODDEF
12230 OS_ACCESS_METHODDEF
12231 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012232 OS_CHDIR_METHODDEF
12233 OS_CHFLAGS_METHODDEF
12234 OS_CHMOD_METHODDEF
12235 OS_FCHMOD_METHODDEF
12236 OS_LCHMOD_METHODDEF
12237 OS_CHOWN_METHODDEF
12238 OS_FCHOWN_METHODDEF
12239 OS_LCHOWN_METHODDEF
12240 OS_LCHFLAGS_METHODDEF
12241 OS_CHROOT_METHODDEF
12242 OS_CTERMID_METHODDEF
12243 OS_GETCWD_METHODDEF
12244 OS_GETCWDB_METHODDEF
12245 OS_LINK_METHODDEF
12246 OS_LISTDIR_METHODDEF
12247 OS_LSTAT_METHODDEF
12248 OS_MKDIR_METHODDEF
12249 OS_NICE_METHODDEF
12250 OS_GETPRIORITY_METHODDEF
12251 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012252#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012253 {"readlink", (PyCFunction)posix_readlink,
12254 METH_VARARGS | METH_KEYWORDS,
12255 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012256#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012257#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012258 {"readlink", (PyCFunction)win_readlink,
12259 METH_VARARGS | METH_KEYWORDS,
12260 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012261#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012262 OS_RENAME_METHODDEF
12263 OS_REPLACE_METHODDEF
12264 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012265 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012266 OS_SYMLINK_METHODDEF
12267 OS_SYSTEM_METHODDEF
12268 OS_UMASK_METHODDEF
12269 OS_UNAME_METHODDEF
12270 OS_UNLINK_METHODDEF
12271 OS_REMOVE_METHODDEF
12272 OS_UTIME_METHODDEF
12273 OS_TIMES_METHODDEF
12274 OS__EXIT_METHODDEF
12275 OS_EXECV_METHODDEF
12276 OS_EXECVE_METHODDEF
12277 OS_SPAWNV_METHODDEF
12278 OS_SPAWNVE_METHODDEF
12279 OS_FORK1_METHODDEF
12280 OS_FORK_METHODDEF
12281 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12282 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12283 OS_SCHED_GETPARAM_METHODDEF
12284 OS_SCHED_GETSCHEDULER_METHODDEF
12285 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12286 OS_SCHED_SETPARAM_METHODDEF
12287 OS_SCHED_SETSCHEDULER_METHODDEF
12288 OS_SCHED_YIELD_METHODDEF
12289 OS_SCHED_SETAFFINITY_METHODDEF
12290 OS_SCHED_GETAFFINITY_METHODDEF
12291 OS_OPENPTY_METHODDEF
12292 OS_FORKPTY_METHODDEF
12293 OS_GETEGID_METHODDEF
12294 OS_GETEUID_METHODDEF
12295 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012296#ifdef HAVE_GETGROUPLIST
12297 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12298#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012299 OS_GETGROUPS_METHODDEF
12300 OS_GETPID_METHODDEF
12301 OS_GETPGRP_METHODDEF
12302 OS_GETPPID_METHODDEF
12303 OS_GETUID_METHODDEF
12304 OS_GETLOGIN_METHODDEF
12305 OS_KILL_METHODDEF
12306 OS_KILLPG_METHODDEF
12307 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012308#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012309 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012310#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012311 OS_SETUID_METHODDEF
12312 OS_SETEUID_METHODDEF
12313 OS_SETREUID_METHODDEF
12314 OS_SETGID_METHODDEF
12315 OS_SETEGID_METHODDEF
12316 OS_SETREGID_METHODDEF
12317 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012318#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012319 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012320#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012321 OS_GETPGID_METHODDEF
12322 OS_SETPGRP_METHODDEF
12323 OS_WAIT_METHODDEF
12324 OS_WAIT3_METHODDEF
12325 OS_WAIT4_METHODDEF
12326 OS_WAITID_METHODDEF
12327 OS_WAITPID_METHODDEF
12328 OS_GETSID_METHODDEF
12329 OS_SETSID_METHODDEF
12330 OS_SETPGID_METHODDEF
12331 OS_TCGETPGRP_METHODDEF
12332 OS_TCSETPGRP_METHODDEF
12333 OS_OPEN_METHODDEF
12334 OS_CLOSE_METHODDEF
12335 OS_CLOSERANGE_METHODDEF
12336 OS_DEVICE_ENCODING_METHODDEF
12337 OS_DUP_METHODDEF
12338 OS_DUP2_METHODDEF
12339 OS_LOCKF_METHODDEF
12340 OS_LSEEK_METHODDEF
12341 OS_READ_METHODDEF
12342 OS_READV_METHODDEF
12343 OS_PREAD_METHODDEF
12344 OS_WRITE_METHODDEF
12345 OS_WRITEV_METHODDEF
12346 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012347#ifdef HAVE_SENDFILE
12348 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12349 posix_sendfile__doc__},
12350#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012351 OS_FSTAT_METHODDEF
12352 OS_ISATTY_METHODDEF
12353 OS_PIPE_METHODDEF
12354 OS_PIPE2_METHODDEF
12355 OS_MKFIFO_METHODDEF
12356 OS_MKNOD_METHODDEF
12357 OS_MAJOR_METHODDEF
12358 OS_MINOR_METHODDEF
12359 OS_MAKEDEV_METHODDEF
12360 OS_FTRUNCATE_METHODDEF
12361 OS_TRUNCATE_METHODDEF
12362 OS_POSIX_FALLOCATE_METHODDEF
12363 OS_POSIX_FADVISE_METHODDEF
12364 OS_PUTENV_METHODDEF
12365 OS_UNSETENV_METHODDEF
12366 OS_STRERROR_METHODDEF
12367 OS_FCHDIR_METHODDEF
12368 OS_FSYNC_METHODDEF
12369 OS_SYNC_METHODDEF
12370 OS_FDATASYNC_METHODDEF
12371 OS_WCOREDUMP_METHODDEF
12372 OS_WIFCONTINUED_METHODDEF
12373 OS_WIFSTOPPED_METHODDEF
12374 OS_WIFSIGNALED_METHODDEF
12375 OS_WIFEXITED_METHODDEF
12376 OS_WEXITSTATUS_METHODDEF
12377 OS_WTERMSIG_METHODDEF
12378 OS_WSTOPSIG_METHODDEF
12379 OS_FSTATVFS_METHODDEF
12380 OS_STATVFS_METHODDEF
12381 OS_CONFSTR_METHODDEF
12382 OS_SYSCONF_METHODDEF
12383 OS_FPATHCONF_METHODDEF
12384 OS_PATHCONF_METHODDEF
12385 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012386 OS__GETFULLPATHNAME_METHODDEF
12387 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012388 OS__GETDISKUSAGE_METHODDEF
12389 OS__GETFINALPATHNAME_METHODDEF
12390 OS__GETVOLUMEPATHNAME_METHODDEF
12391 OS_GETLOADAVG_METHODDEF
12392 OS_URANDOM_METHODDEF
12393 OS_SETRESUID_METHODDEF
12394 OS_SETRESGID_METHODDEF
12395 OS_GETRESUID_METHODDEF
12396 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012397
Larry Hastings2f936352014-08-05 14:04:04 +100012398 OS_GETXATTR_METHODDEF
12399 OS_SETXATTR_METHODDEF
12400 OS_REMOVEXATTR_METHODDEF
12401 OS_LISTXATTR_METHODDEF
12402
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012403#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12404 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12405#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012406 OS_CPU_COUNT_METHODDEF
12407 OS_GET_INHERITABLE_METHODDEF
12408 OS_SET_INHERITABLE_METHODDEF
12409 OS_GET_HANDLE_INHERITABLE_METHODDEF
12410 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012411#ifndef MS_WINDOWS
12412 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12413 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12414#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012415 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012416 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012417 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012418 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012419};
12420
12421
Brian Curtin52173d42010-12-02 18:29:18 +000012422#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012423static int
Brian Curtin52173d42010-12-02 18:29:18 +000012424enable_symlink()
12425{
12426 HANDLE tok;
12427 TOKEN_PRIVILEGES tok_priv;
12428 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012429
12430 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012431 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012432
12433 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012434 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012435
12436 tok_priv.PrivilegeCount = 1;
12437 tok_priv.Privileges[0].Luid = luid;
12438 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12439
12440 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12441 sizeof(TOKEN_PRIVILEGES),
12442 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012443 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012444
Brian Curtin3b4499c2010-12-28 14:31:47 +000012445 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12446 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012447}
12448#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12449
Barry Warsaw4a342091996-12-19 23:50:02 +000012450static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012452{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012453#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012454 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012455#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012456#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012457 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012458#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012459#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012460 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012461#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012462#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012463 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012464#endif
Fred Drakec9680921999-12-13 16:37:25 +000012465#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012466 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012467#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012468#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012469 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012470#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012471#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012472 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012473#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012474#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012475 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012476#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012477#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012478 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012479#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012480#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012481 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012482#endif
12483#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012484 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012485#endif
12486#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012487 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012488#endif
12489#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012490 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012491#endif
12492#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012493 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012494#endif
12495#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012497#endif
12498#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012499 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012500#endif
12501#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012502 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012503#endif
12504#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012505 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012506#endif
12507#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012508 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012509#endif
12510#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012511 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012512#endif
12513#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012514 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012515#endif
12516#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012517 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012518#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012519#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012520 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012521#endif
12522#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012523 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012524#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012525#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012526 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012527#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012528#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012530#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012531#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012532#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012533 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012534#endif
12535#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012536 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012537#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012538#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012539#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012540 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012541#endif
12542#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012544#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012545#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012546 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012547#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012548#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012549 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012550#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012551#ifdef O_TMPFILE
12552 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12553#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012554#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012556#endif
12557#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012559#endif
12560#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012561 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012562#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012563#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012564 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012565#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012566#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012568#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012569
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012570
Jesus Cea94363612012-06-22 18:32:07 +020012571#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012573#endif
12574#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012576#endif
12577
Tim Peters5aa91602002-01-30 05:46:57 +000012578/* MS Windows */
12579#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012580 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012581 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012582#endif
12583#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012584 /* Optimize for short life (keep in memory). */
12585 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012586 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012587#endif
12588#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012589 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012591#endif
12592#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012593 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012595#endif
12596#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012597 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012599#endif
12600
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012601/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012602#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012603 /* Send a SIGIO signal whenever input or output
12604 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012606#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012607#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012608 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012609 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012610#endif
12611#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012612 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012614#endif
12615#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012616 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012618#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012619#ifdef O_NOLINKS
12620 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012622#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012623#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012624 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012626#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012627
Victor Stinner8c62be82010-05-06 00:08:46 +000012628 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012629#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012630 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012631#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012632#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012633 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012634#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012635#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012636 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012637#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012638#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012639 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012640#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012641#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012643#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012644#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012645 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012646#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012647#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012648 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012649#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012650#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012651 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012652#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012653#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012654 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012655#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012656#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012657 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012658#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012659#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012660 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012661#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012662#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012663 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012664#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012665#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012666 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012667#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012668#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012669 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012670#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012671#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012673#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012674#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012676#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012677#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012679#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012680
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012681 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012682#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012684#endif /* ST_RDONLY */
12685#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012687#endif /* ST_NOSUID */
12688
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012689 /* GNU extensions */
12690#ifdef ST_NODEV
12691 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12692#endif /* ST_NODEV */
12693#ifdef ST_NOEXEC
12694 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12695#endif /* ST_NOEXEC */
12696#ifdef ST_SYNCHRONOUS
12697 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12698#endif /* ST_SYNCHRONOUS */
12699#ifdef ST_MANDLOCK
12700 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12701#endif /* ST_MANDLOCK */
12702#ifdef ST_WRITE
12703 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12704#endif /* ST_WRITE */
12705#ifdef ST_APPEND
12706 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12707#endif /* ST_APPEND */
12708#ifdef ST_NOATIME
12709 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12710#endif /* ST_NOATIME */
12711#ifdef ST_NODIRATIME
12712 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12713#endif /* ST_NODIRATIME */
12714#ifdef ST_RELATIME
12715 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12716#endif /* ST_RELATIME */
12717
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012718 /* FreeBSD sendfile() constants */
12719#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012721#endif
12722#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012724#endif
12725#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012727#endif
12728
Ross Lagerwall7807c352011-03-17 20:20:30 +020012729 /* constants for posix_fadvise */
12730#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012732#endif
12733#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012735#endif
12736#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012738#endif
12739#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012741#endif
12742#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012744#endif
12745#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012747#endif
12748
12749 /* constants for waitid */
12750#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012751 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12752 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12753 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012754#endif
12755#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012757#endif
12758#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012760#endif
12761#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012763#endif
12764#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012766#endif
12767#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012769#endif
12770#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012772#endif
12773#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012775#endif
12776
12777 /* constants for lockf */
12778#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012780#endif
12781#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012783#endif
12784#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012786#endif
12787#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012789#endif
12790
Guido van Rossum246bc171999-02-01 23:54:31 +000012791#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012792 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12793 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12794 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12795 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12796 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012797#endif
12798
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012799#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012800#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012801 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012802#endif
12803#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012804 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012805#endif
12806#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012807 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012808#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012809#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012810 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012811#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012812#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012813 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012814#endif
12815#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012816 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012817#endif
12818#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012819 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012820#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012821#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012822 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012823#endif
12824#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012825 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012826#endif
12827#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012828 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012829#endif
12830#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012831 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012832#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012833#endif
12834
Benjamin Peterson9428d532011-09-14 11:45:52 -040012835#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012836 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12837 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12838 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012839#endif
12840
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012841#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012843#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012844#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012846#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012847#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012849#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012850#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012852#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012853#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012855#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012856#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012858#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012859#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012861#endif
12862
Victor Stinner9b1f4742016-09-06 16:18:52 -070012863#ifdef HAVE_GETRANDOM_SYSCALL
12864 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12865 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12866#endif
12867
Victor Stinner8c62be82010-05-06 00:08:46 +000012868 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012869}
12870
12871
Martin v. Löwis1a214512008-06-11 05:26:20 +000012872static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012873 PyModuleDef_HEAD_INIT,
12874 MODNAME,
12875 posix__doc__,
12876 -1,
12877 posix_methods,
12878 NULL,
12879 NULL,
12880 NULL,
12881 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012882};
12883
12884
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012885static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012886
12887#ifdef HAVE_FACCESSAT
12888 "HAVE_FACCESSAT",
12889#endif
12890
12891#ifdef HAVE_FCHDIR
12892 "HAVE_FCHDIR",
12893#endif
12894
12895#ifdef HAVE_FCHMOD
12896 "HAVE_FCHMOD",
12897#endif
12898
12899#ifdef HAVE_FCHMODAT
12900 "HAVE_FCHMODAT",
12901#endif
12902
12903#ifdef HAVE_FCHOWN
12904 "HAVE_FCHOWN",
12905#endif
12906
Larry Hastings00964ed2013-08-12 13:49:30 -040012907#ifdef HAVE_FCHOWNAT
12908 "HAVE_FCHOWNAT",
12909#endif
12910
Larry Hastings9cf065c2012-06-22 16:30:09 -070012911#ifdef HAVE_FEXECVE
12912 "HAVE_FEXECVE",
12913#endif
12914
12915#ifdef HAVE_FDOPENDIR
12916 "HAVE_FDOPENDIR",
12917#endif
12918
Georg Brandl306336b2012-06-24 12:55:33 +020012919#ifdef HAVE_FPATHCONF
12920 "HAVE_FPATHCONF",
12921#endif
12922
Larry Hastings9cf065c2012-06-22 16:30:09 -070012923#ifdef HAVE_FSTATAT
12924 "HAVE_FSTATAT",
12925#endif
12926
12927#ifdef HAVE_FSTATVFS
12928 "HAVE_FSTATVFS",
12929#endif
12930
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012931#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012932 "HAVE_FTRUNCATE",
12933#endif
12934
Larry Hastings9cf065c2012-06-22 16:30:09 -070012935#ifdef HAVE_FUTIMENS
12936 "HAVE_FUTIMENS",
12937#endif
12938
12939#ifdef HAVE_FUTIMES
12940 "HAVE_FUTIMES",
12941#endif
12942
12943#ifdef HAVE_FUTIMESAT
12944 "HAVE_FUTIMESAT",
12945#endif
12946
12947#ifdef HAVE_LINKAT
12948 "HAVE_LINKAT",
12949#endif
12950
12951#ifdef HAVE_LCHFLAGS
12952 "HAVE_LCHFLAGS",
12953#endif
12954
12955#ifdef HAVE_LCHMOD
12956 "HAVE_LCHMOD",
12957#endif
12958
12959#ifdef HAVE_LCHOWN
12960 "HAVE_LCHOWN",
12961#endif
12962
12963#ifdef HAVE_LSTAT
12964 "HAVE_LSTAT",
12965#endif
12966
12967#ifdef HAVE_LUTIMES
12968 "HAVE_LUTIMES",
12969#endif
12970
12971#ifdef HAVE_MKDIRAT
12972 "HAVE_MKDIRAT",
12973#endif
12974
12975#ifdef HAVE_MKFIFOAT
12976 "HAVE_MKFIFOAT",
12977#endif
12978
12979#ifdef HAVE_MKNODAT
12980 "HAVE_MKNODAT",
12981#endif
12982
12983#ifdef HAVE_OPENAT
12984 "HAVE_OPENAT",
12985#endif
12986
12987#ifdef HAVE_READLINKAT
12988 "HAVE_READLINKAT",
12989#endif
12990
12991#ifdef HAVE_RENAMEAT
12992 "HAVE_RENAMEAT",
12993#endif
12994
12995#ifdef HAVE_SYMLINKAT
12996 "HAVE_SYMLINKAT",
12997#endif
12998
12999#ifdef HAVE_UNLINKAT
13000 "HAVE_UNLINKAT",
13001#endif
13002
13003#ifdef HAVE_UTIMENSAT
13004 "HAVE_UTIMENSAT",
13005#endif
13006
13007#ifdef MS_WINDOWS
13008 "MS_WINDOWS",
13009#endif
13010
13011 NULL
13012};
13013
13014
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013015PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013016INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013017{
Victor Stinner8c62be82010-05-06 00:08:46 +000013018 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013019 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013020 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013021
Brian Curtin52173d42010-12-02 18:29:18 +000013022#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013023 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013024#endif
13025
Victor Stinner8c62be82010-05-06 00:08:46 +000013026 m = PyModule_Create(&posixmodule);
13027 if (m == NULL)
13028 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013029
Victor Stinner8c62be82010-05-06 00:08:46 +000013030 /* Initialize environ dictionary */
13031 v = convertenviron();
13032 Py_XINCREF(v);
13033 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13034 return NULL;
13035 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013036
Victor Stinner8c62be82010-05-06 00:08:46 +000013037 if (all_ins(m))
13038 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013039
Victor Stinner8c62be82010-05-06 00:08:46 +000013040 if (setup_confname_tables(m))
13041 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013042
Victor Stinner8c62be82010-05-06 00:08:46 +000013043 Py_INCREF(PyExc_OSError);
13044 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013045
Guido van Rossumb3d39562000-01-31 18:41:26 +000013046#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013047 if (posix_putenv_garbage == NULL)
13048 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013049#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013050
Victor Stinner8c62be82010-05-06 00:08:46 +000013051 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013052#if defined(HAVE_WAITID) && !defined(__APPLE__)
13053 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013054 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13055 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013056#endif
13057
Christian Heimes25827622013-10-12 01:27:08 +020013058 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013059 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13060 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13061 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013062 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13063 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013064 structseq_new = StatResultType.tp_new;
13065 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013066
Christian Heimes25827622013-10-12 01:27:08 +020013067 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013068 if (PyStructSequence_InitType2(&StatVFSResultType,
13069 &statvfs_result_desc) < 0)
13070 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013071#ifdef NEED_TICKS_PER_SECOND
13072# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013073 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013074# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013075 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013076# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013077 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013078# endif
13079#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013080
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013081#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013082 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013083 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13084 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013085 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013086#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013087
13088 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013089 if (PyStructSequence_InitType2(&TerminalSizeType,
13090 &TerminalSize_desc) < 0)
13091 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013092
13093 /* initialize scandir types */
13094 if (PyType_Ready(&ScandirIteratorType) < 0)
13095 return NULL;
13096 if (PyType_Ready(&DirEntryType) < 0)
13097 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013098 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013099#if defined(HAVE_WAITID) && !defined(__APPLE__)
13100 Py_INCREF((PyObject*) &WaitidResultType);
13101 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13102#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013103 Py_INCREF((PyObject*) &StatResultType);
13104 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13105 Py_INCREF((PyObject*) &StatVFSResultType);
13106 PyModule_AddObject(m, "statvfs_result",
13107 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013108
13109#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013110 Py_INCREF(&SchedParamType);
13111 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013112#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013113
Larry Hastings605a62d2012-06-24 04:33:36 -070013114 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013115 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13116 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013117 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13118
13119 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013120 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13121 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013122 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13123
Thomas Wouters477c8d52006-05-27 19:21:47 +000013124#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013125 /*
13126 * Step 2 of weak-linking support on Mac OS X.
13127 *
13128 * The code below removes functions that are not available on the
13129 * currently active platform.
13130 *
13131 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013132 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013133 * OSX 10.4.
13134 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013135#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013136 if (fstatvfs == NULL) {
13137 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13138 return NULL;
13139 }
13140 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013141#endif /* HAVE_FSTATVFS */
13142
13143#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013144 if (statvfs == NULL) {
13145 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13146 return NULL;
13147 }
13148 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013149#endif /* HAVE_STATVFS */
13150
13151# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013152 if (lchown == NULL) {
13153 if (PyObject_DelAttrString(m, "lchown") == -1) {
13154 return NULL;
13155 }
13156 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013157#endif /* HAVE_LCHOWN */
13158
13159
13160#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013161
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013162 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013163 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13164
Larry Hastings6fe20b32012-04-19 15:07:49 -070013165 billion = PyLong_FromLong(1000000000);
13166 if (!billion)
13167 return NULL;
13168
Larry Hastings9cf065c2012-06-22 16:30:09 -070013169 /* suppress "function not used" warnings */
13170 {
13171 int ignored;
13172 fd_specified("", -1);
13173 follow_symlinks_specified("", 1);
13174 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13175 dir_fd_converter(Py_None, &ignored);
13176 dir_fd_unavailable(Py_None, &ignored);
13177 }
13178
13179 /*
13180 * provide list of locally available functions
13181 * so os.py can populate support_* lists
13182 */
13183 list = PyList_New(0);
13184 if (!list)
13185 return NULL;
13186 for (trace = have_functions; *trace; trace++) {
13187 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13188 if (!unicode)
13189 return NULL;
13190 if (PyList_Append(list, unicode))
13191 return NULL;
13192 Py_DECREF(unicode);
13193 }
13194 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013195
13196 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013197 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013198
13199 initialized = 1;
13200
Victor Stinner8c62be82010-05-06 00:08:46 +000013201 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013202}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013203
13204#ifdef __cplusplus
13205}
13206#endif