blob: ae03d06fe10d072c76a1d43bd0a0a647a01d02cc [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));
Fred Drake699f3522000-06-29 21:12:41 +00001930#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001932 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001933#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001935#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001936#ifdef MS_WINDOWS
1937 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001938#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001939 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001940#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001941 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001942#if defined(MS_WINDOWS)
1943 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1944 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1945#else
1946 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1947 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1948#endif
Fred Drake699f3522000-06-29 21:12:41 +00001949#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001951 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001952#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001954#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001955
Martin v. Löwis14694662006-02-03 12:54:16 +00001956#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001957 ansec = st->st_atim.tv_nsec;
1958 mnsec = st->st_mtim.tv_nsec;
1959 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001960#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001961 ansec = st->st_atimespec.tv_nsec;
1962 mnsec = st->st_mtimespec.tv_nsec;
1963 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001964#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 ansec = st->st_atime_nsec;
1966 mnsec = st->st_mtime_nsec;
1967 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001968#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001969 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001970#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001971 fill_time(v, 7, st->st_atime, ansec);
1972 fill_time(v, 8, st->st_mtime, mnsec);
1973 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001974
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001975#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1977 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001978#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001979#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1981 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001982#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001983#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001984 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1985 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001986#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001987#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001988 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1989 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001990#endif
1991#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001992 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001993 PyObject *val;
1994 unsigned long bsec,bnsec;
1995 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001996#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01001997 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001998#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001999 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002000#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002001 if (_stat_float_times) {
2002 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2003 } else {
2004 val = PyLong_FromLong((long)bsec);
2005 }
2006 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2007 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002009#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002010#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2012 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002013#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002014#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2015 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2016 PyLong_FromUnsignedLong(st->st_file_attributes));
2017#endif
Fred Drake699f3522000-06-29 21:12:41 +00002018
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 if (PyErr_Occurred()) {
2020 Py_DECREF(v);
2021 return NULL;
2022 }
Fred Drake699f3522000-06-29 21:12:41 +00002023
Victor Stinner8c62be82010-05-06 00:08:46 +00002024 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002025}
2026
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002027/* POSIX methods */
2028
Guido van Rossum94f6f721999-01-06 18:42:14 +00002029
2030static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002031posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002032 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002033{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002034 STRUCT_STAT st;
2035 int result;
2036
2037#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2038 if (follow_symlinks_specified(function_name, follow_symlinks))
2039 return NULL;
2040#endif
2041
2042 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2043 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2044 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2045 return NULL;
2046
2047 Py_BEGIN_ALLOW_THREADS
2048 if (path->fd != -1)
2049 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002050#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002051 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002052 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002053 else
Steve Dowercc16be82016-09-08 10:35:16 -07002054 result = win32_lstat(path->wide, &st);
2055#else
2056 else
2057#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002058 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2059 result = LSTAT(path->narrow, &st);
2060 else
Steve Dowercc16be82016-09-08 10:35:16 -07002061#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002062#ifdef HAVE_FSTATAT
2063 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2064 result = fstatat(dir_fd, path->narrow, &st,
2065 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2066 else
Steve Dowercc16be82016-09-08 10:35:16 -07002067#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002068 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002069#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002070 Py_END_ALLOW_THREADS
2071
Victor Stinner292c8352012-10-30 02:17:38 +01002072 if (result != 0) {
2073 return path_error(path);
2074 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075
2076 return _pystat_fromstructstat(&st);
2077}
2078
Larry Hastings2f936352014-08-05 14:04:04 +10002079/*[python input]
2080
2081for s in """
2082
2083FACCESSAT
2084FCHMODAT
2085FCHOWNAT
2086FSTATAT
2087LINKAT
2088MKDIRAT
2089MKFIFOAT
2090MKNODAT
2091OPENAT
2092READLINKAT
2093SYMLINKAT
2094UNLINKAT
2095
2096""".strip().split():
2097 s = s.strip()
2098 print("""
2099#ifdef HAVE_{s}
2100 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002101#else
Larry Hastings2f936352014-08-05 14:04:04 +10002102 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002103#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002104""".rstrip().format(s=s))
2105
2106for s in """
2107
2108FCHDIR
2109FCHMOD
2110FCHOWN
2111FDOPENDIR
2112FEXECVE
2113FPATHCONF
2114FSTATVFS
2115FTRUNCATE
2116
2117""".strip().split():
2118 s = s.strip()
2119 print("""
2120#ifdef HAVE_{s}
2121 #define PATH_HAVE_{s} 1
2122#else
2123 #define PATH_HAVE_{s} 0
2124#endif
2125
2126""".rstrip().format(s=s))
2127[python start generated code]*/
2128
2129#ifdef HAVE_FACCESSAT
2130 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2131#else
2132 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2133#endif
2134
2135#ifdef HAVE_FCHMODAT
2136 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2137#else
2138 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2139#endif
2140
2141#ifdef HAVE_FCHOWNAT
2142 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2143#else
2144 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2145#endif
2146
2147#ifdef HAVE_FSTATAT
2148 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2149#else
2150 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2151#endif
2152
2153#ifdef HAVE_LINKAT
2154 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2155#else
2156 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2157#endif
2158
2159#ifdef HAVE_MKDIRAT
2160 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2161#else
2162 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2163#endif
2164
2165#ifdef HAVE_MKFIFOAT
2166 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2167#else
2168 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2169#endif
2170
2171#ifdef HAVE_MKNODAT
2172 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2173#else
2174 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2175#endif
2176
2177#ifdef HAVE_OPENAT
2178 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2179#else
2180 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2181#endif
2182
2183#ifdef HAVE_READLINKAT
2184 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2185#else
2186 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2187#endif
2188
2189#ifdef HAVE_SYMLINKAT
2190 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2191#else
2192 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2193#endif
2194
2195#ifdef HAVE_UNLINKAT
2196 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2197#else
2198 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2199#endif
2200
2201#ifdef HAVE_FCHDIR
2202 #define PATH_HAVE_FCHDIR 1
2203#else
2204 #define PATH_HAVE_FCHDIR 0
2205#endif
2206
2207#ifdef HAVE_FCHMOD
2208 #define PATH_HAVE_FCHMOD 1
2209#else
2210 #define PATH_HAVE_FCHMOD 0
2211#endif
2212
2213#ifdef HAVE_FCHOWN
2214 #define PATH_HAVE_FCHOWN 1
2215#else
2216 #define PATH_HAVE_FCHOWN 0
2217#endif
2218
2219#ifdef HAVE_FDOPENDIR
2220 #define PATH_HAVE_FDOPENDIR 1
2221#else
2222 #define PATH_HAVE_FDOPENDIR 0
2223#endif
2224
2225#ifdef HAVE_FEXECVE
2226 #define PATH_HAVE_FEXECVE 1
2227#else
2228 #define PATH_HAVE_FEXECVE 0
2229#endif
2230
2231#ifdef HAVE_FPATHCONF
2232 #define PATH_HAVE_FPATHCONF 1
2233#else
2234 #define PATH_HAVE_FPATHCONF 0
2235#endif
2236
2237#ifdef HAVE_FSTATVFS
2238 #define PATH_HAVE_FSTATVFS 1
2239#else
2240 #define PATH_HAVE_FSTATVFS 0
2241#endif
2242
2243#ifdef HAVE_FTRUNCATE
2244 #define PATH_HAVE_FTRUNCATE 1
2245#else
2246 #define PATH_HAVE_FTRUNCATE 0
2247#endif
2248/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002249
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002250#ifdef MS_WINDOWS
2251 #undef PATH_HAVE_FTRUNCATE
2252 #define PATH_HAVE_FTRUNCATE 1
2253#endif
Larry Hastings31826802013-10-19 00:09:25 -07002254
Larry Hastings61272b72014-01-07 12:41:53 -08002255/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002256
2257class path_t_converter(CConverter):
2258
2259 type = "path_t"
2260 impl_by_reference = True
2261 parse_by_reference = True
2262
2263 converter = 'path_converter'
2264
2265 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002266 # right now path_t doesn't support default values.
2267 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002268 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002269 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002270
Larry Hastings2f936352014-08-05 14:04:04 +10002271 if self.c_default not in (None, 'Py_None'):
2272 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002273
2274 self.nullable = nullable
2275 self.allow_fd = allow_fd
2276
Larry Hastings7726ac92014-01-31 22:03:12 -08002277 def pre_render(self):
2278 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002279 if isinstance(value, str):
2280 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002281 return str(int(bool(value)))
2282
2283 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002284 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002285 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002286 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002287 strify(self.nullable),
2288 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002289 )
2290
2291 def cleanup(self):
2292 return "path_cleanup(&" + self.name + ");\n"
2293
2294
2295class dir_fd_converter(CConverter):
2296 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002297
Larry Hastings2f936352014-08-05 14:04:04 +10002298 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002299 if self.default in (unspecified, None):
2300 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002301 if isinstance(requires, str):
2302 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2303 else:
2304 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002305
Larry Hastings2f936352014-08-05 14:04:04 +10002306class fildes_converter(CConverter):
2307 type = 'int'
2308 converter = 'fildes_converter'
2309
2310class uid_t_converter(CConverter):
2311 type = "uid_t"
2312 converter = '_Py_Uid_Converter'
2313
2314class gid_t_converter(CConverter):
2315 type = "gid_t"
2316 converter = '_Py_Gid_Converter'
2317
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002318class dev_t_converter(CConverter):
2319 type = 'dev_t'
2320 converter = '_Py_Dev_Converter'
2321
2322class dev_t_return_converter(unsigned_long_return_converter):
2323 type = 'dev_t'
2324 conversion_fn = '_PyLong_FromDev'
2325 unsigned_cast = '(dev_t)'
2326
Larry Hastings2f936352014-08-05 14:04:04 +10002327class FSConverter_converter(CConverter):
2328 type = 'PyObject *'
2329 converter = 'PyUnicode_FSConverter'
2330 def converter_init(self):
2331 if self.default is not unspecified:
2332 fail("FSConverter_converter does not support default values")
2333 self.c_default = 'NULL'
2334
2335 def cleanup(self):
2336 return "Py_XDECREF(" + self.name + ");\n"
2337
2338class pid_t_converter(CConverter):
2339 type = 'pid_t'
2340 format_unit = '" _Py_PARSE_PID "'
2341
2342class idtype_t_converter(int_converter):
2343 type = 'idtype_t'
2344
2345class id_t_converter(CConverter):
2346 type = 'id_t'
2347 format_unit = '" _Py_PARSE_PID "'
2348
Benjamin Petersonca470632016-09-06 13:47:26 -07002349class intptr_t_converter(CConverter):
2350 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002351 format_unit = '" _Py_PARSE_INTPTR "'
2352
2353class Py_off_t_converter(CConverter):
2354 type = 'Py_off_t'
2355 converter = 'Py_off_t_converter'
2356
2357class Py_off_t_return_converter(long_return_converter):
2358 type = 'Py_off_t'
2359 conversion_fn = 'PyLong_FromPy_off_t'
2360
2361class path_confname_converter(CConverter):
2362 type="int"
2363 converter="conv_path_confname"
2364
2365class confstr_confname_converter(path_confname_converter):
2366 converter='conv_confstr_confname'
2367
2368class sysconf_confname_converter(path_confname_converter):
2369 converter="conv_sysconf_confname"
2370
2371class sched_param_converter(CConverter):
2372 type = 'struct sched_param'
2373 converter = 'convert_sched_param'
2374 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002375
Larry Hastings61272b72014-01-07 12:41:53 -08002376[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002377/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002378
Larry Hastings61272b72014-01-07 12:41:53 -08002379/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002380
Larry Hastings2a727912014-01-16 11:32:01 -08002381os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002382
2383 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002384 Path to be examined; can be string, bytes, path-like object or
2385 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002386
2387 *
2388
Larry Hastings2f936352014-08-05 14:04:04 +10002389 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002390 If not None, it should be a file descriptor open to a directory,
2391 and path should be a relative string; path will then be relative to
2392 that directory.
2393
2394 follow_symlinks: bool = True
2395 If False, and the last element of the path is a symbolic link,
2396 stat will examine the symbolic link itself instead of the file
2397 the link points to.
2398
2399Perform a stat system call on the given path.
2400
2401dir_fd and follow_symlinks may not be implemented
2402 on your platform. If they are unavailable, using them will raise a
2403 NotImplementedError.
2404
2405It's an error to use dir_fd or follow_symlinks when specifying path as
2406 an open file descriptor.
2407
Larry Hastings61272b72014-01-07 12:41:53 -08002408[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002409
Larry Hastings31826802013-10-19 00:09:25 -07002410static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002411os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002412/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002413{
2414 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2415}
2416
Larry Hastings2f936352014-08-05 14:04:04 +10002417
2418/*[clinic input]
2419os.lstat
2420
2421 path : path_t
2422
2423 *
2424
2425 dir_fd : dir_fd(requires='fstatat') = None
2426
2427Perform a stat system call on the given path, without following symbolic links.
2428
2429Like stat(), but do not follow symbolic links.
2430Equivalent to stat(path, follow_symlinks=False).
2431[clinic start generated code]*/
2432
Larry Hastings2f936352014-08-05 14:04:04 +10002433static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002434os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2435/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002436{
2437 int follow_symlinks = 0;
2438 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2439}
Larry Hastings31826802013-10-19 00:09:25 -07002440
Larry Hastings2f936352014-08-05 14:04:04 +10002441
Larry Hastings61272b72014-01-07 12:41:53 -08002442/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002443os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002444
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002445 path: path_t
2446 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002447
2448 mode: int
2449 Operating-system mode bitfield. Can be F_OK to test existence,
2450 or the inclusive-OR of R_OK, W_OK, and X_OK.
2451
2452 *
2453
Larry Hastings2f936352014-08-05 14:04:04 +10002454 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002455 If not None, it should be a file descriptor open to a directory,
2456 and path should be relative; path will then be relative to that
2457 directory.
2458
2459 effective_ids: bool = False
2460 If True, access will use the effective uid/gid instead of
2461 the real uid/gid.
2462
2463 follow_symlinks: bool = True
2464 If False, and the last element of the path is a symbolic link,
2465 access will examine the symbolic link itself instead of the file
2466 the link points to.
2467
2468Use the real uid/gid to test for access to a path.
2469
2470{parameters}
2471dir_fd, effective_ids, and follow_symlinks may not be implemented
2472 on your platform. If they are unavailable, using them will raise a
2473 NotImplementedError.
2474
2475Note that most operations will use the effective uid/gid, therefore this
2476 routine can be used in a suid/sgid environment to test if the invoking user
2477 has the specified access to the path.
2478
Larry Hastings61272b72014-01-07 12:41:53 -08002479[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002480
Larry Hastings2f936352014-08-05 14:04:04 +10002481static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002482os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002483 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002484/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002485{
Larry Hastings2f936352014-08-05 14:04:04 +10002486 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002487
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002488#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002489 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002490#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002491 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002492#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002493
Larry Hastings9cf065c2012-06-22 16:30:09 -07002494#ifndef HAVE_FACCESSAT
2495 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002496 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002497
2498 if (effective_ids) {
2499 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002500 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002501 }
2502#endif
2503
2504#ifdef MS_WINDOWS
2505 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002506 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002507 Py_END_ALLOW_THREADS
2508
2509 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002510 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002511 * * we didn't get a -1, and
2512 * * write access wasn't requested,
2513 * * or the file isn't read-only,
2514 * * or it's a directory.
2515 * (Directories cannot be read-only on Windows.)
2516 */
Larry Hastings2f936352014-08-05 14:04:04 +10002517 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002518 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002519 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002520 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521#else
2522
2523 Py_BEGIN_ALLOW_THREADS
2524#ifdef HAVE_FACCESSAT
2525 if ((dir_fd != DEFAULT_DIR_FD) ||
2526 effective_ids ||
2527 !follow_symlinks) {
2528 int flags = 0;
2529 if (!follow_symlinks)
2530 flags |= AT_SYMLINK_NOFOLLOW;
2531 if (effective_ids)
2532 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002533 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002534 }
2535 else
2536#endif
Larry Hastings31826802013-10-19 00:09:25 -07002537 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002538 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002539 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002540#endif
2541
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002543}
2544
Guido van Rossumd371ff11999-01-25 16:12:23 +00002545#ifndef F_OK
2546#define F_OK 0
2547#endif
2548#ifndef R_OK
2549#define R_OK 4
2550#endif
2551#ifndef W_OK
2552#define W_OK 2
2553#endif
2554#ifndef X_OK
2555#define X_OK 1
2556#endif
2557
Larry Hastings31826802013-10-19 00:09:25 -07002558
Guido van Rossumd371ff11999-01-25 16:12:23 +00002559#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002560/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002561os.ttyname -> DecodeFSDefault
2562
2563 fd: int
2564 Integer file descriptor handle.
2565
2566 /
2567
2568Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002569[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002570
Larry Hastings31826802013-10-19 00:09:25 -07002571static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002572os_ttyname_impl(PyObject *module, int fd)
2573/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002574{
2575 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002576
Larry Hastings31826802013-10-19 00:09:25 -07002577 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002578 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002579 posix_error();
2580 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002581}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002582#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002583
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002584#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002585/*[clinic input]
2586os.ctermid
2587
2588Return the name of the controlling terminal for this process.
2589[clinic start generated code]*/
2590
Larry Hastings2f936352014-08-05 14:04:04 +10002591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002592os_ctermid_impl(PyObject *module)
2593/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002594{
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 char *ret;
2596 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002597
Greg Wardb48bc172000-03-01 21:51:56 +00002598#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002600#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002601 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002602#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 if (ret == NULL)
2604 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002605 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002606}
Larry Hastings2f936352014-08-05 14:04:04 +10002607#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002608
Larry Hastings2f936352014-08-05 14:04:04 +10002609
2610/*[clinic input]
2611os.chdir
2612
2613 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2614
2615Change the current working directory to the specified path.
2616
2617path may always be specified as a string.
2618On some platforms, path may also be specified as an open file descriptor.
2619 If this functionality is unavailable, using it raises an exception.
2620[clinic start generated code]*/
2621
Larry Hastings2f936352014-08-05 14:04:04 +10002622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002623os_chdir_impl(PyObject *module, path_t *path)
2624/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002625{
2626 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627
2628 Py_BEGIN_ALLOW_THREADS
2629#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002630 /* on unix, success = 0, on windows, success = !0 */
2631 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632#else
2633#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002634 if (path->fd != -1)
2635 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002636 else
2637#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002638 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002639#endif
2640 Py_END_ALLOW_THREADS
2641
2642 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002643 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644 }
2645
Larry Hastings2f936352014-08-05 14:04:04 +10002646 Py_RETURN_NONE;
2647}
2648
2649
2650#ifdef HAVE_FCHDIR
2651/*[clinic input]
2652os.fchdir
2653
2654 fd: fildes
2655
2656Change to the directory of the given file descriptor.
2657
2658fd must be opened on a directory, not a file.
2659Equivalent to os.chdir(fd).
2660
2661[clinic start generated code]*/
2662
Fred Drake4d1e64b2002-04-15 19:40:07 +00002663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002664os_fchdir_impl(PyObject *module, int fd)
2665/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002666{
Larry Hastings2f936352014-08-05 14:04:04 +10002667 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002668}
2669#endif /* HAVE_FCHDIR */
2670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002671
Larry Hastings2f936352014-08-05 14:04:04 +10002672/*[clinic input]
2673os.chmod
2674
2675 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2676 Path to be modified. May always be specified as a str or bytes.
2677 On some platforms, path may also be specified as an open file descriptor.
2678 If this functionality is unavailable, using it raises an exception.
2679
2680 mode: int
2681 Operating-system mode bitfield.
2682
2683 *
2684
2685 dir_fd : dir_fd(requires='fchmodat') = None
2686 If not None, it should be a file descriptor open to a directory,
2687 and path should be relative; path will then be relative to that
2688 directory.
2689
2690 follow_symlinks: bool = True
2691 If False, and the last element of the path is a symbolic link,
2692 chmod will modify the symbolic link itself instead of the file
2693 the link points to.
2694
2695Change the access permissions of a file.
2696
2697It is an error to use dir_fd or follow_symlinks when specifying path as
2698 an open file descriptor.
2699dir_fd and follow_symlinks may not be implemented on your platform.
2700 If they are unavailable, using them will raise a NotImplementedError.
2701
2702[clinic start generated code]*/
2703
Larry Hastings2f936352014-08-05 14:04:04 +10002704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002705os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002706 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002707/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002708{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002710
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002711#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002712 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002713#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002714
Larry Hastings9cf065c2012-06-22 16:30:09 -07002715#ifdef HAVE_FCHMODAT
2716 int fchmodat_nofollow_unsupported = 0;
2717#endif
2718
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2720 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002721 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002722#endif
2723
2724#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002725 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002726 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002727 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002728 result = 0;
2729 else {
2730 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002731 attr &= ~FILE_ATTRIBUTE_READONLY;
2732 else
2733 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002734 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735 }
2736 Py_END_ALLOW_THREADS
2737
2738 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002739 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740 }
2741#else /* MS_WINDOWS */
2742 Py_BEGIN_ALLOW_THREADS
2743#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002744 if (path->fd != -1)
2745 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002746 else
2747#endif
2748#ifdef HAVE_LCHMOD
2749 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002750 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002751 else
2752#endif
2753#ifdef HAVE_FCHMODAT
2754 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2755 /*
2756 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2757 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002758 * and then says it isn't implemented yet.
2759 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760 *
2761 * Once it is supported, os.chmod will automatically
2762 * support dir_fd and follow_symlinks=False. (Hopefully.)
2763 * Until then, we need to be careful what exception we raise.
2764 */
Larry Hastings2f936352014-08-05 14:04:04 +10002765 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002766 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2767 /*
2768 * But wait! We can't throw the exception without allowing threads,
2769 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2770 */
2771 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002772 result &&
2773 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2774 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002775 }
2776 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002777#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002778 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002779 Py_END_ALLOW_THREADS
2780
2781 if (result) {
2782#ifdef HAVE_FCHMODAT
2783 if (fchmodat_nofollow_unsupported) {
2784 if (dir_fd != DEFAULT_DIR_FD)
2785 dir_fd_and_follow_symlinks_invalid("chmod",
2786 dir_fd, follow_symlinks);
2787 else
2788 follow_symlinks_specified("chmod", follow_symlinks);
2789 }
2790 else
2791#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002792 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 }
2794#endif
2795
Larry Hastings2f936352014-08-05 14:04:04 +10002796 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002797}
2798
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799
Christian Heimes4e30a842007-11-30 22:12:06 +00002800#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002801/*[clinic input]
2802os.fchmod
2803
2804 fd: int
2805 mode: int
2806
2807Change the access permissions of the file given by file descriptor fd.
2808
2809Equivalent to os.chmod(fd, mode).
2810[clinic start generated code]*/
2811
Larry Hastings2f936352014-08-05 14:04:04 +10002812static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002813os_fchmod_impl(PyObject *module, int fd, int mode)
2814/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002815{
2816 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002817 int async_err = 0;
2818
2819 do {
2820 Py_BEGIN_ALLOW_THREADS
2821 res = fchmod(fd, mode);
2822 Py_END_ALLOW_THREADS
2823 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2824 if (res != 0)
2825 return (!async_err) ? posix_error() : NULL;
2826
Victor Stinner8c62be82010-05-06 00:08:46 +00002827 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002828}
2829#endif /* HAVE_FCHMOD */
2830
Larry Hastings2f936352014-08-05 14:04:04 +10002831
Christian Heimes4e30a842007-11-30 22:12:06 +00002832#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002833/*[clinic input]
2834os.lchmod
2835
2836 path: path_t
2837 mode: int
2838
2839Change the access permissions of a file, without following symbolic links.
2840
2841If path is a symlink, this affects the link itself rather than the target.
2842Equivalent to chmod(path, mode, follow_symlinks=False)."
2843[clinic start generated code]*/
2844
Larry Hastings2f936352014-08-05 14:04:04 +10002845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002846os_lchmod_impl(PyObject *module, path_t *path, int mode)
2847/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002848{
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002850 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002851 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002852 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002853 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002854 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002855 return NULL;
2856 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002858}
2859#endif /* HAVE_LCHMOD */
2860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002861
Thomas Wouterscf297e42007-02-23 15:07:44 +00002862#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002863/*[clinic input]
2864os.chflags
2865
2866 path: path_t
2867 flags: unsigned_long(bitwise=True)
2868 follow_symlinks: bool=True
2869
2870Set file flags.
2871
2872If follow_symlinks is False, and the last element of the path is a symbolic
2873 link, chflags will change flags on the symbolic link itself instead of the
2874 file the link points to.
2875follow_symlinks may not be implemented on your platform. If it is
2876unavailable, using it will raise a NotImplementedError.
2877
2878[clinic start generated code]*/
2879
Larry Hastings2f936352014-08-05 14:04:04 +10002880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002881os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002882 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002883/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002884{
2885 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886
2887#ifndef HAVE_LCHFLAGS
2888 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002889 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890#endif
2891
Victor Stinner8c62be82010-05-06 00:08:46 +00002892 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893#ifdef HAVE_LCHFLAGS
2894 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002895 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002896 else
2897#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002898 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900
Larry Hastings2f936352014-08-05 14:04:04 +10002901 if (result)
2902 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002903
Larry Hastings2f936352014-08-05 14:04:04 +10002904 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002905}
2906#endif /* HAVE_CHFLAGS */
2907
Larry Hastings2f936352014-08-05 14:04:04 +10002908
Thomas Wouterscf297e42007-02-23 15:07:44 +00002909#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002910/*[clinic input]
2911os.lchflags
2912
2913 path: path_t
2914 flags: unsigned_long(bitwise=True)
2915
2916Set file flags.
2917
2918This function will not follow symbolic links.
2919Equivalent to chflags(path, flags, follow_symlinks=False).
2920[clinic start generated code]*/
2921
Larry Hastings2f936352014-08-05 14:04:04 +10002922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002923os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2924/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002925{
Victor Stinner8c62be82010-05-06 00:08:46 +00002926 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002928 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002929 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002930 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002931 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002932 }
Victor Stinner292c8352012-10-30 02:17:38 +01002933 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002934}
2935#endif /* HAVE_LCHFLAGS */
2936
Larry Hastings2f936352014-08-05 14:04:04 +10002937
Martin v. Löwis244edc82001-10-04 22:44:26 +00002938#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002939/*[clinic input]
2940os.chroot
2941 path: path_t
2942
2943Change root directory to path.
2944
2945[clinic start generated code]*/
2946
Larry Hastings2f936352014-08-05 14:04:04 +10002947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002948os_chroot_impl(PyObject *module, path_t *path)
2949/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002950{
2951 int res;
2952 Py_BEGIN_ALLOW_THREADS
2953 res = chroot(path->narrow);
2954 Py_END_ALLOW_THREADS
2955 if (res < 0)
2956 return path_error(path);
2957 Py_RETURN_NONE;
2958}
2959#endif /* HAVE_CHROOT */
2960
Martin v. Löwis244edc82001-10-04 22:44:26 +00002961
Guido van Rossum21142a01999-01-08 21:05:37 +00002962#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002963/*[clinic input]
2964os.fsync
2965
2966 fd: fildes
2967
2968Force write of fd to disk.
2969[clinic start generated code]*/
2970
Larry Hastings2f936352014-08-05 14:04:04 +10002971static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002972os_fsync_impl(PyObject *module, int fd)
2973/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002974{
2975 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002976}
2977#endif /* HAVE_FSYNC */
2978
Larry Hastings2f936352014-08-05 14:04:04 +10002979
Ross Lagerwall7807c352011-03-17 20:20:30 +02002980#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002981/*[clinic input]
2982os.sync
2983
2984Force write of everything to disk.
2985[clinic start generated code]*/
2986
Larry Hastings2f936352014-08-05 14:04:04 +10002987static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002988os_sync_impl(PyObject *module)
2989/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002990{
2991 Py_BEGIN_ALLOW_THREADS
2992 sync();
2993 Py_END_ALLOW_THREADS
2994 Py_RETURN_NONE;
2995}
Larry Hastings2f936352014-08-05 14:04:04 +10002996#endif /* HAVE_SYNC */
2997
Ross Lagerwall7807c352011-03-17 20:20:30 +02002998
Guido van Rossum21142a01999-01-08 21:05:37 +00002999#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003000#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003001extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3002#endif
3003
Larry Hastings2f936352014-08-05 14:04:04 +10003004/*[clinic input]
3005os.fdatasync
3006
3007 fd: fildes
3008
3009Force write of fd to disk without forcing update of metadata.
3010[clinic start generated code]*/
3011
Larry Hastings2f936352014-08-05 14:04:04 +10003012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003013os_fdatasync_impl(PyObject *module, int fd)
3014/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003015{
3016 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003017}
3018#endif /* HAVE_FDATASYNC */
3019
3020
Fredrik Lundh10723342000-07-10 16:38:09 +00003021#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003022/*[clinic input]
3023os.chown
3024
3025 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3026 Path to be examined; can be string, bytes, or open-file-descriptor int.
3027
3028 uid: uid_t
3029
3030 gid: gid_t
3031
3032 *
3033
3034 dir_fd : dir_fd(requires='fchownat') = None
3035 If not None, it should be a file descriptor open to a directory,
3036 and path should be relative; path will then be relative to that
3037 directory.
3038
3039 follow_symlinks: bool = True
3040 If False, and the last element of the path is a symbolic link,
3041 stat will examine the symbolic link itself instead of the file
3042 the link points to.
3043
3044Change the owner and group id of path to the numeric uid and gid.\
3045
3046path may always be specified as a string.
3047On some platforms, path may also be specified as an open file descriptor.
3048 If this functionality is unavailable, using it raises an exception.
3049If dir_fd is not None, it should be a file descriptor open to a directory,
3050 and path should be relative; path will then be relative to that directory.
3051If follow_symlinks is False, and the last element of the path is a symbolic
3052 link, chown will modify the symbolic link itself instead of the file the
3053 link points to.
3054It is an error to use dir_fd or follow_symlinks when specifying path as
3055 an open file descriptor.
3056dir_fd and follow_symlinks may not be implemented on your platform.
3057 If they are unavailable, using them will raise a NotImplementedError.
3058
3059[clinic start generated code]*/
3060
Larry Hastings2f936352014-08-05 14:04:04 +10003061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003062os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003063 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003064/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003065{
3066 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003067
3068#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3069 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003070 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003071#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003072 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3073 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3074 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003075
3076#ifdef __APPLE__
3077 /*
3078 * This is for Mac OS X 10.3, which doesn't have lchown.
3079 * (But we still have an lchown symbol because of weak-linking.)
3080 * It doesn't have fchownat either. So there's no possibility
3081 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003082 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003083 if ((!follow_symlinks) && (lchown == NULL)) {
3084 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003085 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003086 }
3087#endif
3088
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003091 if (path->fd != -1)
3092 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003093 else
3094#endif
3095#ifdef HAVE_LCHOWN
3096 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003097 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003098 else
3099#endif
3100#ifdef HAVE_FCHOWNAT
3101 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003102 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003103 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3104 else
3105#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003106 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003107 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108
Larry Hastings2f936352014-08-05 14:04:04 +10003109 if (result)
3110 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003111
Larry Hastings2f936352014-08-05 14:04:04 +10003112 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003113}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003114#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003115
Larry Hastings2f936352014-08-05 14:04:04 +10003116
Christian Heimes4e30a842007-11-30 22:12:06 +00003117#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003118/*[clinic input]
3119os.fchown
3120
3121 fd: int
3122 uid: uid_t
3123 gid: gid_t
3124
3125Change the owner and group id of the file specified by file descriptor.
3126
3127Equivalent to os.chown(fd, uid, gid).
3128
3129[clinic start generated code]*/
3130
Larry Hastings2f936352014-08-05 14:04:04 +10003131static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003132os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3133/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003134{
Victor Stinner8c62be82010-05-06 00:08:46 +00003135 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003136 int async_err = 0;
3137
3138 do {
3139 Py_BEGIN_ALLOW_THREADS
3140 res = fchown(fd, uid, gid);
3141 Py_END_ALLOW_THREADS
3142 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3143 if (res != 0)
3144 return (!async_err) ? posix_error() : NULL;
3145
Victor Stinner8c62be82010-05-06 00:08:46 +00003146 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003147}
3148#endif /* HAVE_FCHOWN */
3149
Larry Hastings2f936352014-08-05 14:04:04 +10003150
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003151#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003152/*[clinic input]
3153os.lchown
3154
3155 path : path_t
3156 uid: uid_t
3157 gid: gid_t
3158
3159Change the owner and group id of path to the numeric uid and gid.
3160
3161This function will not follow symbolic links.
3162Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3163[clinic start generated code]*/
3164
Larry Hastings2f936352014-08-05 14:04:04 +10003165static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003166os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3167/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003168{
Victor Stinner8c62be82010-05-06 00:08:46 +00003169 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003170 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003171 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003172 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003173 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003174 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003175 }
Larry Hastings2f936352014-08-05 14:04:04 +10003176 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003177}
3178#endif /* HAVE_LCHOWN */
3179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003180
Barry Warsaw53699e91996-12-10 23:23:01 +00003181static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003182posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003183{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003184 char *buf, *tmpbuf;
3185 char *cwd;
3186 const size_t chunk = 1024;
3187 size_t buflen = 0;
3188 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003189
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003190#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003192 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 wchar_t *wbuf2 = wbuf;
3194 PyObject *resobj;
3195 DWORD len;
3196 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003197 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 /* If the buffer is large enough, len does not include the
3199 terminating \0. If the buffer is too small, len includes
3200 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003201 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003202 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003203 if (wbuf2)
3204 len = GetCurrentDirectoryW(len, wbuf2);
3205 }
3206 Py_END_ALLOW_THREADS
3207 if (!wbuf2) {
3208 PyErr_NoMemory();
3209 return NULL;
3210 }
3211 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003212 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003213 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003214 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 }
3216 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003217 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003218 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 return resobj;
3220 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003221
3222 if (win32_warn_bytes_api())
3223 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003224#endif
3225
Victor Stinner4403d7d2015-04-25 00:16:10 +02003226 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003228 do {
3229 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003230#ifdef MS_WINDOWS
3231 if (buflen > INT_MAX) {
3232 PyErr_NoMemory();
3233 break;
3234 }
3235#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003236 tmpbuf = PyMem_RawRealloc(buf, buflen);
3237 if (tmpbuf == NULL)
3238 break;
3239
3240 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003241#ifdef MS_WINDOWS
3242 cwd = getcwd(buf, (int)buflen);
3243#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003244 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003245#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003246 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003247 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003248
3249 if (cwd == NULL) {
3250 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003252 }
3253
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003255 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3256 else
3257 obj = PyUnicode_DecodeFSDefault(buf);
3258 PyMem_RawFree(buf);
3259
3260 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003261}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003262
Larry Hastings2f936352014-08-05 14:04:04 +10003263
3264/*[clinic input]
3265os.getcwd
3266
3267Return a unicode string representing the current working directory.
3268[clinic start generated code]*/
3269
Larry Hastings2f936352014-08-05 14:04:04 +10003270static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003271os_getcwd_impl(PyObject *module)
3272/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003273{
3274 return posix_getcwd(0);
3275}
3276
Larry Hastings2f936352014-08-05 14:04:04 +10003277
3278/*[clinic input]
3279os.getcwdb
3280
3281Return a bytes string representing the current working directory.
3282[clinic start generated code]*/
3283
Larry Hastings2f936352014-08-05 14:04:04 +10003284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003285os_getcwdb_impl(PyObject *module)
3286/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003287{
3288 return posix_getcwd(1);
3289}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003290
Larry Hastings2f936352014-08-05 14:04:04 +10003291
Larry Hastings9cf065c2012-06-22 16:30:09 -07003292#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3293#define HAVE_LINK 1
3294#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003295
Guido van Rossumb6775db1994-08-01 11:34:53 +00003296#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003297/*[clinic input]
3298
3299os.link
3300
3301 src : path_t
3302 dst : path_t
3303 *
3304 src_dir_fd : dir_fd = None
3305 dst_dir_fd : dir_fd = None
3306 follow_symlinks: bool = True
3307
3308Create a hard link to a file.
3309
3310If either src_dir_fd or dst_dir_fd is not None, it should be a file
3311 descriptor open to a directory, and the respective path string (src or dst)
3312 should be relative; the path will then be relative to that directory.
3313If follow_symlinks is False, and the last element of src is a symbolic
3314 link, link will create a link to the symbolic link itself instead of the
3315 file the link points to.
3316src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3317 platform. If they are unavailable, using them will raise a
3318 NotImplementedError.
3319[clinic start generated code]*/
3320
Larry Hastings2f936352014-08-05 14:04:04 +10003321static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003322os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003323 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003324/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003325{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003326#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003327 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003328#else
3329 int result;
3330#endif
3331
Larry Hastings9cf065c2012-06-22 16:30:09 -07003332#ifndef HAVE_LINKAT
3333 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3334 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003335 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336 }
3337#endif
3338
Steve Dowercc16be82016-09-08 10:35:16 -07003339#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003340 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003341 PyErr_SetString(PyExc_NotImplementedError,
3342 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003343 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 }
Steve Dowercc16be82016-09-08 10:35:16 -07003345#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003346
Brian Curtin1b9df392010-11-24 20:24:31 +00003347#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003349 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003350 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003351
Larry Hastings2f936352014-08-05 14:04:04 +10003352 if (!result)
3353 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003354#else
3355 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003356#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3358 (dst_dir_fd != DEFAULT_DIR_FD) ||
3359 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003360 result = linkat(src_dir_fd, src->narrow,
3361 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3363 else
Steve Dowercc16be82016-09-08 10:35:16 -07003364#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003365 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003366 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003367
Larry Hastings2f936352014-08-05 14:04:04 +10003368 if (result)
3369 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003370#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371
Larry Hastings2f936352014-08-05 14:04:04 +10003372 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003373}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003374#endif
3375
Brian Curtin1b9df392010-11-24 20:24:31 +00003376
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003377#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003378static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003379_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003380{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381 PyObject *v;
3382 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3383 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003384 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003386 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003387 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388
Steve Dowercc16be82016-09-08 10:35:16 -07003389 WIN32_FIND_DATAW wFileData;
3390 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003391
Steve Dowercc16be82016-09-08 10:35:16 -07003392 if (!path->wide) { /* Default arg: "." */
3393 po_wchars = L".";
3394 len = 1;
3395 } else {
3396 po_wchars = path->wide;
3397 len = wcslen(path->wide);
3398 }
3399 /* The +5 is so we can append "\\*.*\0" */
3400 wnamebuf = PyMem_New(wchar_t, len + 5);
3401 if (!wnamebuf) {
3402 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 }
Steve Dowercc16be82016-09-08 10:35:16 -07003405 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003407 wchar_t wch = wnamebuf[len-1];
3408 if (wch != SEP && wch != ALTSEP && wch != L':')
3409 wnamebuf[len++] = SEP;
3410 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 }
Steve Dowercc16be82016-09-08 10:35:16 -07003412 if ((list = PyList_New(0)) == NULL) {
3413 goto exit;
3414 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003415 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003416 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003417 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 if (hFindFile == INVALID_HANDLE_VALUE) {
3419 int error = GetLastError();
3420 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421 goto exit;
3422 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003423 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 }
3426 do {
3427 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003428 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3429 wcscmp(wFileData.cFileName, L"..") != 0) {
3430 v = PyUnicode_FromWideChar(wFileData.cFileName,
3431 wcslen(wFileData.cFileName));
3432 if (path->narrow && v) {
3433 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3434 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436 Py_DECREF(list);
3437 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003438 break;
3439 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003441 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 Py_DECREF(list);
3443 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 break;
3445 }
3446 Py_DECREF(v);
3447 }
3448 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003449 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003450 Py_END_ALLOW_THREADS
3451 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3452 it got to the end of the directory. */
3453 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003455 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003457 }
3458 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003459
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460exit:
3461 if (hFindFile != INVALID_HANDLE_VALUE) {
3462 if (FindClose(hFindFile) == FALSE) {
3463 if (list != NULL) {
3464 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003465 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466 }
3467 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003469 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003470
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003472} /* end of _listdir_windows_no_opendir */
3473
3474#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3475
3476static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003477_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003478{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003479 PyObject *v;
3480 DIR *dirp = NULL;
3481 struct dirent *ep;
3482 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003483#ifdef HAVE_FDOPENDIR
3484 int fd = -1;
3485#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003486
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003488#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003489 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003491 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003492 if (fd == -1)
3493 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494
Larry Hastingsfdaea062012-06-25 04:42:23 -07003495 return_str = 1;
3496
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 Py_BEGIN_ALLOW_THREADS
3498 dirp = fdopendir(fd);
3499 Py_END_ALLOW_THREADS
3500 }
3501 else
3502#endif
3503 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003504 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003505 if (path->narrow) {
3506 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003507 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003508 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003509 }
3510 else {
3511 name = ".";
3512 return_str = 1;
3513 }
3514
Larry Hastings9cf065c2012-06-22 16:30:09 -07003515 Py_BEGIN_ALLOW_THREADS
3516 dirp = opendir(name);
3517 Py_END_ALLOW_THREADS
3518 }
3519
3520 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003521 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003522#ifdef HAVE_FDOPENDIR
3523 if (fd != -1) {
3524 Py_BEGIN_ALLOW_THREADS
3525 close(fd);
3526 Py_END_ALLOW_THREADS
3527 }
3528#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 goto exit;
3530 }
3531 if ((list = PyList_New(0)) == NULL) {
3532 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003533 }
3534 for (;;) {
3535 errno = 0;
3536 Py_BEGIN_ALLOW_THREADS
3537 ep = readdir(dirp);
3538 Py_END_ALLOW_THREADS
3539 if (ep == NULL) {
3540 if (errno == 0) {
3541 break;
3542 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003544 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 }
3547 }
3548 if (ep->d_name[0] == '.' &&
3549 (NAMLEN(ep) == 1 ||
3550 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3551 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003552 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003553 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3554 else
3555 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 break;
3559 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 break;
3564 }
3565 Py_DECREF(v);
3566 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003567
Larry Hastings9cf065c2012-06-22 16:30:09 -07003568exit:
3569 if (dirp != NULL) {
3570 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003571#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 if (fd > -1)
3573 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003574#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 closedir(dirp);
3576 Py_END_ALLOW_THREADS
3577 }
3578
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003580} /* end of _posix_listdir */
3581#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003582
Larry Hastings2f936352014-08-05 14:04:04 +10003583
3584/*[clinic input]
3585os.listdir
3586
3587 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3588
3589Return a list containing the names of the files in the directory.
3590
3591path can be specified as either str or bytes. If path is bytes,
3592 the filenames returned will also be bytes; in all other circumstances
3593 the filenames returned will be str.
3594If path is None, uses the path='.'.
3595On some platforms, path may also be specified as an open file descriptor;\
3596 the file descriptor must refer to a directory.
3597 If this functionality is unavailable, using it raises NotImplementedError.
3598
3599The list is in arbitrary order. It does not include the special
3600entries '.' and '..' even if they are present in the directory.
3601
3602
3603[clinic start generated code]*/
3604
Larry Hastings2f936352014-08-05 14:04:04 +10003605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003606os_listdir_impl(PyObject *module, path_t *path)
3607/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003608{
3609#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3610 return _listdir_windows_no_opendir(path, NULL);
3611#else
3612 return _posix_listdir(path, NULL);
3613#endif
3614}
3615
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003616#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003617/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003618/*[clinic input]
3619os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003620
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003621 path: path_t
3622 /
3623
3624[clinic start generated code]*/
3625
3626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003627os__getfullpathname_impl(PyObject *module, path_t *path)
3628/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003629{
Steve Dowercc16be82016-09-08 10:35:16 -07003630 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3631 wchar_t *wtemp;
3632 DWORD result;
3633 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003634
Steve Dowercc16be82016-09-08 10:35:16 -07003635 result = GetFullPathNameW(path->wide,
3636 Py_ARRAY_LENGTH(woutbuf),
3637 woutbuf, &wtemp);
3638 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3639 woutbufp = PyMem_New(wchar_t, result);
3640 if (!woutbufp)
3641 return PyErr_NoMemory();
3642 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 }
Steve Dowercc16be82016-09-08 10:35:16 -07003644 if (result) {
3645 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3646 if (path->narrow)
3647 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3648 } else
3649 v = win32_error_object("GetFullPathNameW", path->object);
3650 if (woutbufp != woutbuf)
3651 PyMem_Free(woutbufp);
3652 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003653}
Brian Curtind40e6f72010-07-08 21:39:08 +00003654
Brian Curtind25aef52011-06-13 15:16:04 -05003655
Larry Hastings2f936352014-08-05 14:04:04 +10003656/*[clinic input]
3657os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003658
Larry Hastings2f936352014-08-05 14:04:04 +10003659 path: unicode
3660 /
3661
3662A helper function for samepath on windows.
3663[clinic start generated code]*/
3664
Larry Hastings2f936352014-08-05 14:04:04 +10003665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003666os__getfinalpathname_impl(PyObject *module, PyObject *path)
3667/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003668{
3669 HANDLE hFile;
3670 int buf_size;
3671 wchar_t *target_path;
3672 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003673 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003674 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003675
Larry Hastings2f936352014-08-05 14:04:04 +10003676 path_wchar = PyUnicode_AsUnicode(path);
3677 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003678 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003679
Brian Curtind40e6f72010-07-08 21:39:08 +00003680 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003681 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003682 0, /* desired access */
3683 0, /* share mode */
3684 NULL, /* security attributes */
3685 OPEN_EXISTING,
3686 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3687 FILE_FLAG_BACKUP_SEMANTICS,
3688 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003689
Victor Stinnereb5657a2011-09-30 01:44:27 +02003690 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003691 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003692
3693 /* We have a good handle to the target, use it to determine the
3694 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003695 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003696
3697 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003698 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003699
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003700 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003701 if(!target_path)
3702 return PyErr_NoMemory();
3703
Steve Dower2ea51c92015-03-20 21:49:12 -07003704 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3705 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003706 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003707 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003708
3709 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003710 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003711
3712 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003713 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003714 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003715 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003716}
Brian Curtin62857742010-09-06 17:07:27 +00003717
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003718/*[clinic input]
3719os._isdir
3720
3721 path: path_t
3722 /
3723
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003724Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003725[clinic start generated code]*/
3726
Brian Curtin9c669cc2011-06-08 18:17:18 -05003727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003728os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003729/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003730{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003731 DWORD attributes;
3732
Steve Dowerb22a6772016-07-17 20:49:38 -07003733 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003734 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003735 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003736
Brian Curtin9c669cc2011-06-08 18:17:18 -05003737 if (attributes == INVALID_FILE_ATTRIBUTES)
3738 Py_RETURN_FALSE;
3739
Brian Curtin9c669cc2011-06-08 18:17:18 -05003740 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3741 Py_RETURN_TRUE;
3742 else
3743 Py_RETURN_FALSE;
3744}
Tim Golden6b528062013-08-01 12:44:00 +01003745
Tim Golden6b528062013-08-01 12:44:00 +01003746
Larry Hastings2f936352014-08-05 14:04:04 +10003747/*[clinic input]
3748os._getvolumepathname
3749
3750 path: unicode
3751
3752A helper function for ismount on Win32.
3753[clinic start generated code]*/
3754
Larry Hastings2f936352014-08-05 14:04:04 +10003755static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003756os__getvolumepathname_impl(PyObject *module, PyObject *path)
3757/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003758{
3759 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003760 const wchar_t *path_wchar;
3761 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003762 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003763 BOOL ret;
3764
Larry Hastings2f936352014-08-05 14:04:04 +10003765 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3766 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003767 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003768 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003769
3770 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003771 buflen = Py_MAX(buflen, MAX_PATH);
3772
3773 if (buflen > DWORD_MAX) {
3774 PyErr_SetString(PyExc_OverflowError, "path too long");
3775 return NULL;
3776 }
3777
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003778 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003779 if (mountpath == NULL)
3780 return PyErr_NoMemory();
3781
3782 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003783 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003784 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003785 Py_END_ALLOW_THREADS
3786
3787 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003788 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003789 goto exit;
3790 }
3791 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3792
3793exit:
3794 PyMem_Free(mountpath);
3795 return result;
3796}
Tim Golden6b528062013-08-01 12:44:00 +01003797
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003798#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003799
Larry Hastings2f936352014-08-05 14:04:04 +10003800
3801/*[clinic input]
3802os.mkdir
3803
3804 path : path_t
3805
3806 mode: int = 0o777
3807
3808 *
3809
3810 dir_fd : dir_fd(requires='mkdirat') = None
3811
3812# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3813
3814Create a directory.
3815
3816If dir_fd is not None, it should be a file descriptor open to a directory,
3817 and path should be relative; path will then be relative to that directory.
3818dir_fd may not be implemented on your platform.
3819 If it is unavailable, using it will raise a NotImplementedError.
3820
3821The mode argument is ignored on Windows.
3822[clinic start generated code]*/
3823
Larry Hastings2f936352014-08-05 14:04:04 +10003824static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003825os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3826/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003827{
3828 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003829
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003830#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003831 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003832 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003833 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003834
Larry Hastings2f936352014-08-05 14:04:04 +10003835 if (!result)
3836 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003837#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003839#if HAVE_MKDIRAT
3840 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003841 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003842 else
3843#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003844#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003845 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003846#else
Larry Hastings2f936352014-08-05 14:04:04 +10003847 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003848#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003849 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003850 if (result < 0)
3851 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003852#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003853 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003854}
3855
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003856
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003857/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3858#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003859#include <sys/resource.h>
3860#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003861
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003862
3863#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003864/*[clinic input]
3865os.nice
3866
3867 increment: int
3868 /
3869
3870Add increment to the priority of process and return the new priority.
3871[clinic start generated code]*/
3872
Larry Hastings2f936352014-08-05 14:04:04 +10003873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003874os_nice_impl(PyObject *module, int increment)
3875/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003876{
3877 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003878
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 /* There are two flavours of 'nice': one that returns the new
3880 priority (as required by almost all standards out there) and the
3881 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3882 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003883
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 If we are of the nice family that returns the new priority, we
3885 need to clear errno before the call, and check if errno is filled
3886 before calling posix_error() on a returnvalue of -1, because the
3887 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003888
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 errno = 0;
3890 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003891#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003892 if (value == 0)
3893 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003894#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 if (value == -1 && errno != 0)
3896 /* either nice() or getpriority() returned an error */
3897 return posix_error();
3898 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003899}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003900#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003901
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003902
3903#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003904/*[clinic input]
3905os.getpriority
3906
3907 which: int
3908 who: int
3909
3910Return program scheduling priority.
3911[clinic start generated code]*/
3912
Larry Hastings2f936352014-08-05 14:04:04 +10003913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003914os_getpriority_impl(PyObject *module, int which, int who)
3915/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003916{
3917 int retval;
3918
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003919 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003920 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003921 if (errno != 0)
3922 return posix_error();
3923 return PyLong_FromLong((long)retval);
3924}
3925#endif /* HAVE_GETPRIORITY */
3926
3927
3928#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003929/*[clinic input]
3930os.setpriority
3931
3932 which: int
3933 who: int
3934 priority: int
3935
3936Set program scheduling priority.
3937[clinic start generated code]*/
3938
Larry Hastings2f936352014-08-05 14:04:04 +10003939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003940os_setpriority_impl(PyObject *module, int which, int who, int priority)
3941/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003942{
3943 int retval;
3944
3945 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003946 if (retval == -1)
3947 return posix_error();
3948 Py_RETURN_NONE;
3949}
3950#endif /* HAVE_SETPRIORITY */
3951
3952
Barry Warsaw53699e91996-12-10 23:23:01 +00003953static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003954internal_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 +00003955{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003956 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003957 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003959#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003960 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003961 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003962#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003963 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003964#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003965
Larry Hastings9cf065c2012-06-22 16:30:09 -07003966 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3967 (dst_dir_fd != DEFAULT_DIR_FD);
3968#ifndef HAVE_RENAMEAT
3969 if (dir_fd_specified) {
3970 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003971 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972 }
3973#endif
3974
Larry Hastings9cf065c2012-06-22 16:30:09 -07003975#ifdef MS_WINDOWS
3976 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003977 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003978 Py_END_ALLOW_THREADS
3979
Larry Hastings2f936352014-08-05 14:04:04 +10003980 if (!result)
3981 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003982
3983#else
Steve Dowercc16be82016-09-08 10:35:16 -07003984 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3985 PyErr_Format(PyExc_ValueError,
3986 "%s: src and dst must be the same type", function_name);
3987 return NULL;
3988 }
3989
Larry Hastings9cf065c2012-06-22 16:30:09 -07003990 Py_BEGIN_ALLOW_THREADS
3991#ifdef HAVE_RENAMEAT
3992 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10003993 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003994 else
3995#endif
Steve Dowercc16be82016-09-08 10:35:16 -07003996 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003997 Py_END_ALLOW_THREADS
3998
Larry Hastings2f936352014-08-05 14:04:04 +10003999 if (result)
4000 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004002 Py_RETURN_NONE;
4003}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004004
Larry Hastings2f936352014-08-05 14:04:04 +10004005
4006/*[clinic input]
4007os.rename
4008
4009 src : path_t
4010 dst : path_t
4011 *
4012 src_dir_fd : dir_fd = None
4013 dst_dir_fd : dir_fd = None
4014
4015Rename a file or directory.
4016
4017If either src_dir_fd or dst_dir_fd is not None, it should be a file
4018 descriptor open to a directory, and the respective path string (src or dst)
4019 should be relative; the path will then be relative to that directory.
4020src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4021 If they are unavailable, using them will raise a NotImplementedError.
4022[clinic start generated code]*/
4023
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004025os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004026 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004027/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004028{
Larry Hastings2f936352014-08-05 14:04:04 +10004029 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004030}
4031
Larry Hastings2f936352014-08-05 14:04:04 +10004032
4033/*[clinic input]
4034os.replace = os.rename
4035
4036Rename a file or directory, overwriting the destination.
4037
4038If either src_dir_fd or dst_dir_fd is not None, it should be a file
4039 descriptor open to a directory, and the respective path string (src or dst)
4040 should be relative; the path will then be relative to that directory.
4041src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4042 If they are unavailable, using them will raise a NotImplementedError."
4043[clinic start generated code]*/
4044
Larry Hastings2f936352014-08-05 14:04:04 +10004045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004046os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4047 int dst_dir_fd)
4048/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004049{
4050 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4051}
4052
4053
4054/*[clinic input]
4055os.rmdir
4056
4057 path: path_t
4058 *
4059 dir_fd: dir_fd(requires='unlinkat') = None
4060
4061Remove a directory.
4062
4063If dir_fd is not None, it should be a file descriptor open to a directory,
4064 and path should be relative; path will then be relative to that directory.
4065dir_fd may not be implemented on your platform.
4066 If it is unavailable, using it will raise a NotImplementedError.
4067[clinic start generated code]*/
4068
Larry Hastings2f936352014-08-05 14:04:04 +10004069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004070os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4071/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004072{
4073 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004074
4075 Py_BEGIN_ALLOW_THREADS
4076#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004077 /* Windows, success=1, UNIX, success=0 */
4078 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004079#else
4080#ifdef HAVE_UNLINKAT
4081 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004082 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004083 else
4084#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004085 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004086#endif
4087 Py_END_ALLOW_THREADS
4088
Larry Hastings2f936352014-08-05 14:04:04 +10004089 if (result)
4090 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004091
Larry Hastings2f936352014-08-05 14:04:04 +10004092 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004093}
4094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004095
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004096#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004097#ifdef MS_WINDOWS
4098/*[clinic input]
4099os.system -> long
4100
4101 command: Py_UNICODE
4102
4103Execute the command in a subshell.
4104[clinic start generated code]*/
4105
Larry Hastings2f936352014-08-05 14:04:04 +10004106static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004107os_system_impl(PyObject *module, Py_UNICODE *command)
4108/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004109{
4110 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004111 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004112 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004113 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004114 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004115 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004116 return result;
4117}
4118#else /* MS_WINDOWS */
4119/*[clinic input]
4120os.system -> long
4121
4122 command: FSConverter
4123
4124Execute the command in a subshell.
4125[clinic start generated code]*/
4126
Larry Hastings2f936352014-08-05 14:04:04 +10004127static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004128os_system_impl(PyObject *module, PyObject *command)
4129/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004130{
4131 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004132 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004133 Py_BEGIN_ALLOW_THREADS
4134 result = system(bytes);
4135 Py_END_ALLOW_THREADS
4136 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004137}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004138#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004139#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004141
Larry Hastings2f936352014-08-05 14:04:04 +10004142/*[clinic input]
4143os.umask
4144
4145 mask: int
4146 /
4147
4148Set the current numeric umask and return the previous umask.
4149[clinic start generated code]*/
4150
Larry Hastings2f936352014-08-05 14:04:04 +10004151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004152os_umask_impl(PyObject *module, int mask)
4153/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004154{
4155 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 if (i < 0)
4157 return posix_error();
4158 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004159}
4160
Brian Curtind40e6f72010-07-08 21:39:08 +00004161#ifdef MS_WINDOWS
4162
4163/* override the default DeleteFileW behavior so that directory
4164symlinks can be removed with this function, the same as with
4165Unix symlinks */
4166BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4167{
4168 WIN32_FILE_ATTRIBUTE_DATA info;
4169 WIN32_FIND_DATAW find_data;
4170 HANDLE find_data_handle;
4171 int is_directory = 0;
4172 int is_link = 0;
4173
4174 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4175 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004176
Brian Curtind40e6f72010-07-08 21:39:08 +00004177 /* Get WIN32_FIND_DATA structure for the path to determine if
4178 it is a symlink */
4179 if(is_directory &&
4180 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4181 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4182
4183 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004184 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4185 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4186 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4187 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004188 FindClose(find_data_handle);
4189 }
4190 }
4191 }
4192
4193 if (is_directory && is_link)
4194 return RemoveDirectoryW(lpFileName);
4195
4196 return DeleteFileW(lpFileName);
4197}
4198#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004200
Larry Hastings2f936352014-08-05 14:04:04 +10004201/*[clinic input]
4202os.unlink
4203
4204 path: path_t
4205 *
4206 dir_fd: dir_fd(requires='unlinkat')=None
4207
4208Remove a file (same as remove()).
4209
4210If dir_fd is not None, it should be a file descriptor open to a directory,
4211 and path should be relative; path will then be relative to that directory.
4212dir_fd may not be implemented on your platform.
4213 If it is unavailable, using it will raise a NotImplementedError.
4214
4215[clinic start generated code]*/
4216
Larry Hastings2f936352014-08-05 14:04:04 +10004217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004218os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4219/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004220{
4221 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004222
4223 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004224 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004225#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004226 /* Windows, success=1, UNIX, success=0 */
4227 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004228#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004229#ifdef HAVE_UNLINKAT
4230 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004231 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004232 else
4233#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004234 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004235#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004236 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004237 Py_END_ALLOW_THREADS
4238
Larry Hastings2f936352014-08-05 14:04:04 +10004239 if (result)
4240 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004241
Larry Hastings2f936352014-08-05 14:04:04 +10004242 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004243}
4244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004245
Larry Hastings2f936352014-08-05 14:04:04 +10004246/*[clinic input]
4247os.remove = os.unlink
4248
4249Remove a file (same as unlink()).
4250
4251If dir_fd is not None, it should be a file descriptor open to a directory,
4252 and path should be relative; path will then be relative to that directory.
4253dir_fd may not be implemented on your platform.
4254 If it is unavailable, using it will raise a NotImplementedError.
4255[clinic start generated code]*/
4256
Larry Hastings2f936352014-08-05 14:04:04 +10004257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004258os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4259/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004260{
4261 return os_unlink_impl(module, path, dir_fd);
4262}
4263
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004264
Larry Hastings605a62d2012-06-24 04:33:36 -07004265static PyStructSequence_Field uname_result_fields[] = {
4266 {"sysname", "operating system name"},
4267 {"nodename", "name of machine on network (implementation-defined)"},
4268 {"release", "operating system release"},
4269 {"version", "operating system version"},
4270 {"machine", "hardware identifier"},
4271 {NULL}
4272};
4273
4274PyDoc_STRVAR(uname_result__doc__,
4275"uname_result: Result from os.uname().\n\n\
4276This object may be accessed either as a tuple of\n\
4277 (sysname, nodename, release, version, machine),\n\
4278or via the attributes sysname, nodename, release, version, and machine.\n\
4279\n\
4280See os.uname for more information.");
4281
4282static PyStructSequence_Desc uname_result_desc = {
4283 "uname_result", /* name */
4284 uname_result__doc__, /* doc */
4285 uname_result_fields,
4286 5
4287};
4288
4289static PyTypeObject UnameResultType;
4290
4291
4292#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004293/*[clinic input]
4294os.uname
4295
4296Return an object identifying the current operating system.
4297
4298The object behaves like a named tuple with the following fields:
4299 (sysname, nodename, release, version, machine)
4300
4301[clinic start generated code]*/
4302
Larry Hastings2f936352014-08-05 14:04:04 +10004303static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004304os_uname_impl(PyObject *module)
4305/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004306{
Victor Stinner8c62be82010-05-06 00:08:46 +00004307 struct utsname u;
4308 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004309 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004310
Victor Stinner8c62be82010-05-06 00:08:46 +00004311 Py_BEGIN_ALLOW_THREADS
4312 res = uname(&u);
4313 Py_END_ALLOW_THREADS
4314 if (res < 0)
4315 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004316
4317 value = PyStructSequence_New(&UnameResultType);
4318 if (value == NULL)
4319 return NULL;
4320
4321#define SET(i, field) \
4322 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004323 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004324 if (!o) { \
4325 Py_DECREF(value); \
4326 return NULL; \
4327 } \
4328 PyStructSequence_SET_ITEM(value, i, o); \
4329 } \
4330
4331 SET(0, u.sysname);
4332 SET(1, u.nodename);
4333 SET(2, u.release);
4334 SET(3, u.version);
4335 SET(4, u.machine);
4336
4337#undef SET
4338
4339 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004340}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004341#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004342
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004343
Larry Hastings9cf065c2012-06-22 16:30:09 -07004344
4345typedef struct {
4346 int now;
4347 time_t atime_s;
4348 long atime_ns;
4349 time_t mtime_s;
4350 long mtime_ns;
4351} utime_t;
4352
4353/*
Victor Stinner484df002014-10-09 13:52:31 +02004354 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004355 * they also intentionally leak the declaration of a pointer named "time"
4356 */
4357#define UTIME_TO_TIMESPEC \
4358 struct timespec ts[2]; \
4359 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004360 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361 time = NULL; \
4362 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004363 ts[0].tv_sec = ut->atime_s; \
4364 ts[0].tv_nsec = ut->atime_ns; \
4365 ts[1].tv_sec = ut->mtime_s; \
4366 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004367 time = ts; \
4368 } \
4369
4370#define UTIME_TO_TIMEVAL \
4371 struct timeval tv[2]; \
4372 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004373 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374 time = NULL; \
4375 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004376 tv[0].tv_sec = ut->atime_s; \
4377 tv[0].tv_usec = ut->atime_ns / 1000; \
4378 tv[1].tv_sec = ut->mtime_s; \
4379 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004380 time = tv; \
4381 } \
4382
4383#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004384 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004385 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004386 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004387 time = NULL; \
4388 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004389 u.actime = ut->atime_s; \
4390 u.modtime = ut->mtime_s; \
4391 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392 }
4393
4394#define UTIME_TO_TIME_T \
4395 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004396 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004397 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004398 time = NULL; \
4399 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004400 timet[0] = ut->atime_s; \
4401 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004402 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403 } \
4404
4405
Victor Stinner528a9ab2015-09-03 21:30:26 +02004406#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004407
4408static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004409utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004410{
4411#ifdef HAVE_UTIMENSAT
4412 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4413 UTIME_TO_TIMESPEC;
4414 return utimensat(dir_fd, path, time, flags);
4415#elif defined(HAVE_FUTIMESAT)
4416 UTIME_TO_TIMEVAL;
4417 /*
4418 * follow_symlinks will never be false here;
4419 * we only allow !follow_symlinks and dir_fd together
4420 * if we have utimensat()
4421 */
4422 assert(follow_symlinks);
4423 return futimesat(dir_fd, path, time);
4424#endif
4425}
4426
Larry Hastings2f936352014-08-05 14:04:04 +10004427 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4428#else
4429 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004430#endif
4431
Victor Stinner528a9ab2015-09-03 21:30:26 +02004432#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004433
4434static int
Victor Stinner484df002014-10-09 13:52:31 +02004435utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004436{
4437#ifdef HAVE_FUTIMENS
4438 UTIME_TO_TIMESPEC;
4439 return futimens(fd, time);
4440#else
4441 UTIME_TO_TIMEVAL;
4442 return futimes(fd, time);
4443#endif
4444}
4445
Larry Hastings2f936352014-08-05 14:04:04 +10004446 #define PATH_UTIME_HAVE_FD 1
4447#else
4448 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004449#endif
4450
Victor Stinner5ebae872015-09-22 01:29:33 +02004451#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4452# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4453#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004454
Victor Stinner4552ced2015-09-21 22:37:15 +02004455#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456
4457static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004458utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004459{
4460#ifdef HAVE_UTIMENSAT
4461 UTIME_TO_TIMESPEC;
4462 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4463#else
4464 UTIME_TO_TIMEVAL;
4465 return lutimes(path, time);
4466#endif
4467}
4468
4469#endif
4470
4471#ifndef MS_WINDOWS
4472
4473static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004474utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475{
4476#ifdef HAVE_UTIMENSAT
4477 UTIME_TO_TIMESPEC;
4478 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4479#elif defined(HAVE_UTIMES)
4480 UTIME_TO_TIMEVAL;
4481 return utimes(path, time);
4482#elif defined(HAVE_UTIME_H)
4483 UTIME_TO_UTIMBUF;
4484 return utime(path, time);
4485#else
4486 UTIME_TO_TIME_T;
4487 return utime(path, time);
4488#endif
4489}
4490
4491#endif
4492
Larry Hastings76ad59b2012-05-03 00:30:07 -07004493static int
4494split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4495{
4496 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004497 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004498 divmod = PyNumber_Divmod(py_long, billion);
4499 if (!divmod)
4500 goto exit;
4501 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4502 if ((*s == -1) && PyErr_Occurred())
4503 goto exit;
4504 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004505 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004506 goto exit;
4507
4508 result = 1;
4509exit:
4510 Py_XDECREF(divmod);
4511 return result;
4512}
4513
Larry Hastings2f936352014-08-05 14:04:04 +10004514
4515/*[clinic input]
4516os.utime
4517
4518 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4519 times: object = NULL
4520 *
4521 ns: object = NULL
4522 dir_fd: dir_fd(requires='futimensat') = None
4523 follow_symlinks: bool=True
4524
Martin Panter0ff89092015-09-09 01:56:53 +00004525# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004526
4527Set the access and modified time of path.
4528
4529path may always be specified as a string.
4530On some platforms, path may also be specified as an open file descriptor.
4531 If this functionality is unavailable, using it raises an exception.
4532
4533If times is not None, it must be a tuple (atime, mtime);
4534 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004535If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004536 atime_ns and mtime_ns should be expressed as integer nanoseconds
4537 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004538If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004539Specifying tuples for both times and ns is an error.
4540
4541If dir_fd is not None, it should be a file descriptor open to a directory,
4542 and path should be relative; path will then be relative to that directory.
4543If follow_symlinks is False, and the last element of the path is a symbolic
4544 link, utime will modify the symbolic link itself instead of the file the
4545 link points to.
4546It is an error to use dir_fd or follow_symlinks when specifying path
4547 as an open file descriptor.
4548dir_fd and follow_symlinks may not be available on your platform.
4549 If they are unavailable, using them will raise a NotImplementedError.
4550
4551[clinic start generated code]*/
4552
Larry Hastings2f936352014-08-05 14:04:04 +10004553static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004554os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4555 int dir_fd, int follow_symlinks)
4556/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004557{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558#ifdef MS_WINDOWS
4559 HANDLE hFile;
4560 FILETIME atime, mtime;
4561#else
4562 int result;
4563#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004564
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004566 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004567
Christian Heimesb3c87242013-08-01 00:08:16 +02004568 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004569
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570 if (times && (times != Py_None) && ns) {
4571 PyErr_SetString(PyExc_ValueError,
4572 "utime: you may specify either 'times'"
4573 " or 'ns' but not both");
4574 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004575 }
4576
4577 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004578 time_t a_sec, m_sec;
4579 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004580 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581 PyErr_SetString(PyExc_TypeError,
4582 "utime: 'times' must be either"
4583 " a tuple of two ints or None");
4584 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004585 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004587 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004588 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004589 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004590 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004592 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004593 utime.atime_s = a_sec;
4594 utime.atime_ns = a_nsec;
4595 utime.mtime_s = m_sec;
4596 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004597 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004599 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600 PyErr_SetString(PyExc_TypeError,
4601 "utime: 'ns' must be a tuple of two ints");
4602 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004603 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004604 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004605 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004607 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 &utime.mtime_s, &utime.mtime_ns)) {
4609 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004610 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611 }
4612 else {
4613 /* times and ns are both None/unspecified. use "now". */
4614 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004615 }
4616
Victor Stinner4552ced2015-09-21 22:37:15 +02004617#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004618 if (follow_symlinks_specified("utime", follow_symlinks))
4619 goto exit;
4620#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004621
Larry Hastings2f936352014-08-05 14:04:04 +10004622 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4623 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4624 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004625 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004626
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627#if !defined(HAVE_UTIMENSAT)
4628 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004629 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 "utime: cannot use dir_fd and follow_symlinks "
4631 "together on this platform");
4632 goto exit;
4633 }
4634#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004635
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004636#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004638 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4639 NULL, OPEN_EXISTING,
4640 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 Py_END_ALLOW_THREADS
4642 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004643 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004644 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004645 }
4646
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004648 GetSystemTimeAsFileTime(&mtime);
4649 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004650 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004651 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004652 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4653 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004654 }
4655 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4656 /* Avoid putting the file name into the error here,
4657 as that may confuse the user into believing that
4658 something is wrong with the file, when it also
4659 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004660 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004661 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004662 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004663#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004664 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004665
Victor Stinner4552ced2015-09-21 22:37:15 +02004666#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004667 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004668 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004670#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671
Victor Stinner528a9ab2015-09-03 21:30:26 +02004672#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004674 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 else
4676#endif
4677
Victor Stinner528a9ab2015-09-03 21:30:26 +02004678#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004679 if (path->fd != -1)
4680 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004681 else
4682#endif
4683
Larry Hastings2f936352014-08-05 14:04:04 +10004684 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685
4686 Py_END_ALLOW_THREADS
4687
4688 if (result < 0) {
4689 /* see previous comment about not putting filename in error here */
4690 return_value = posix_error();
4691 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004692 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004693
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004694#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695
4696 Py_INCREF(Py_None);
4697 return_value = Py_None;
4698
4699exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700#ifdef MS_WINDOWS
4701 if (hFile != INVALID_HANDLE_VALUE)
4702 CloseHandle(hFile);
4703#endif
4704 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004705}
4706
Guido van Rossum3b066191991-06-04 19:40:25 +00004707/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004708
Larry Hastings2f936352014-08-05 14:04:04 +10004709
4710/*[clinic input]
4711os._exit
4712
4713 status: int
4714
4715Exit to the system with specified status, without normal exit processing.
4716[clinic start generated code]*/
4717
Larry Hastings2f936352014-08-05 14:04:04 +10004718static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004719os__exit_impl(PyObject *module, int status)
4720/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004721{
4722 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004723 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004724}
4725
Steve Dowercc16be82016-09-08 10:35:16 -07004726#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4727#define EXECV_CHAR wchar_t
4728#else
4729#define EXECV_CHAR char
4730#endif
4731
Martin v. Löwis114619e2002-10-07 06:44:21 +00004732#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4733static void
Steve Dowercc16be82016-09-08 10:35:16 -07004734free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004735{
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 Py_ssize_t i;
4737 for (i = 0; i < count; i++)
4738 PyMem_Free(array[i]);
4739 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004740}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004741
Berker Peksag81816462016-09-15 20:19:47 +03004742static int
4743fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004744{
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004746 PyObject *ub;
4747 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004748#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004749 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004750 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004751 *out = PyUnicode_AsWideCharString(ub, &size);
4752 if (*out)
4753 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004754#else
Berker Peksag81816462016-09-15 20:19:47 +03004755 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004756 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004757 size = PyBytes_GET_SIZE(ub);
4758 *out = PyMem_Malloc(size + 1);
4759 if (*out) {
4760 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4761 result = 1;
4762 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004763 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004764#endif
Berker Peksag81816462016-09-15 20:19:47 +03004765 Py_DECREF(ub);
4766 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004767}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004768#endif
4769
Ross Lagerwall7807c352011-03-17 20:20:30 +02004770#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004771static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004772parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4773{
Victor Stinner8c62be82010-05-06 00:08:46 +00004774 Py_ssize_t i, pos, envc;
4775 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004776 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004777 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004778
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 i = PyMapping_Size(env);
4780 if (i < 0)
4781 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004782 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004783 if (envlist == NULL) {
4784 PyErr_NoMemory();
4785 return NULL;
4786 }
4787 envc = 0;
4788 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004789 if (!keys)
4790 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004791 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004792 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 goto error;
4794 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4795 PyErr_Format(PyExc_TypeError,
4796 "env.keys() or env.values() is not a list");
4797 goto error;
4798 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004799
Victor Stinner8c62be82010-05-06 00:08:46 +00004800 for (pos = 0; pos < i; pos++) {
4801 key = PyList_GetItem(keys, pos);
4802 val = PyList_GetItem(vals, pos);
4803 if (!key || !val)
4804 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004805
Berker Peksag81816462016-09-15 20:19:47 +03004806#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4807 if (!PyUnicode_FSDecoder(key, &key2))
4808 goto error;
4809 if (!PyUnicode_FSDecoder(val, &val2)) {
4810 Py_DECREF(key2);
4811 goto error;
4812 }
4813 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4814#else
4815 if (!PyUnicode_FSConverter(key, &key2))
4816 goto error;
4817 if (!PyUnicode_FSConverter(val, &val2)) {
4818 Py_DECREF(key2);
4819 goto error;
4820 }
4821 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4822 PyBytes_AS_STRING(val2));
4823#endif
4824 Py_DECREF(key2);
4825 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004826 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004827 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004828
4829 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4830 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 goto error;
4832 }
Berker Peksag81816462016-09-15 20:19:47 +03004833
Steve Dowercc16be82016-09-08 10:35:16 -07004834 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 }
4836 Py_DECREF(vals);
4837 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004838
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 envlist[envc] = 0;
4840 *envc_ptr = envc;
4841 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004842
4843error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004844 Py_XDECREF(keys);
4845 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004846 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004848}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004849
Steve Dowercc16be82016-09-08 10:35:16 -07004850static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004851parse_arglist(PyObject* argv, Py_ssize_t *argc)
4852{
4853 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004854 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004855 if (argvlist == NULL) {
4856 PyErr_NoMemory();
4857 return NULL;
4858 }
4859 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004860 PyObject* item = PySequence_ITEM(argv, i);
4861 if (item == NULL)
4862 goto fail;
4863 if (!fsconvert_strdup(item, &argvlist[i])) {
4864 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004865 goto fail;
4866 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004867 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004868 }
4869 argvlist[*argc] = NULL;
4870 return argvlist;
4871fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004872 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004873 free_string_array(argvlist, *argc);
4874 return NULL;
4875}
Steve Dowercc16be82016-09-08 10:35:16 -07004876
Ross Lagerwall7807c352011-03-17 20:20:30 +02004877#endif
4878
Larry Hastings2f936352014-08-05 14:04:04 +10004879
Ross Lagerwall7807c352011-03-17 20:20:30 +02004880#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004881/*[clinic input]
4882os.execv
4883
Steve Dowercc16be82016-09-08 10:35:16 -07004884 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004885 Path of executable file.
4886 argv: object
4887 Tuple or list of strings.
4888 /
4889
4890Execute an executable path with arguments, replacing current process.
4891[clinic start generated code]*/
4892
Larry Hastings2f936352014-08-05 14:04:04 +10004893static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004894os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4895/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004896{
Steve Dowercc16be82016-09-08 10:35:16 -07004897 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898 Py_ssize_t argc;
4899
4900 /* execv has two arguments: (path, argv), where
4901 argv is a list or tuple of strings. */
4902
Ross Lagerwall7807c352011-03-17 20:20:30 +02004903 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4904 PyErr_SetString(PyExc_TypeError,
4905 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004906 return NULL;
4907 }
4908 argc = PySequence_Size(argv);
4909 if (argc < 1) {
4910 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004911 return NULL;
4912 }
4913
4914 argvlist = parse_arglist(argv, &argc);
4915 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004916 return NULL;
4917 }
Steve Dowerbce26262016-11-19 19:17:26 -08004918 if (!argvlist[0][0]) {
4919 PyErr_SetString(PyExc_ValueError,
4920 "execv() arg 2 first element cannot be empty");
4921 free_string_array(argvlist, argc);
4922 return NULL;
4923 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004924
Steve Dowerbce26262016-11-19 19:17:26 -08004925 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004926#ifdef HAVE_WEXECV
4927 _wexecv(path->wide, argvlist);
4928#else
4929 execv(path->narrow, argvlist);
4930#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004931 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004932
4933 /* If we get here it's definitely an error */
4934
4935 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004936 return posix_error();
4937}
4938
Larry Hastings2f936352014-08-05 14:04:04 +10004939
4940/*[clinic input]
4941os.execve
4942
4943 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4944 Path of executable file.
4945 argv: object
4946 Tuple or list of strings.
4947 env: object
4948 Dictionary of strings mapping to strings.
4949
4950Execute an executable path with arguments, replacing current process.
4951[clinic start generated code]*/
4952
Larry Hastings2f936352014-08-05 14:04:04 +10004953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004954os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4955/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004956{
Steve Dowercc16be82016-09-08 10:35:16 -07004957 EXECV_CHAR **argvlist = NULL;
4958 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004959 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004960
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 /* execve has three arguments: (path, argv, env), where
4962 argv is a list or tuple of strings and env is a dictionary
4963 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004964
Ross Lagerwall7807c352011-03-17 20:20:30 +02004965 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004967 "execve: argv must be a tuple or list");
4968 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004970 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08004971 if (argc < 1) {
4972 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
4973 return NULL;
4974 }
4975
Victor Stinner8c62be82010-05-06 00:08:46 +00004976 if (!PyMapping_Check(env)) {
4977 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978 "execve: environment must be a mapping object");
4979 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004981
Ross Lagerwall7807c352011-03-17 20:20:30 +02004982 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004983 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004984 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 }
Steve Dowerbce26262016-11-19 19:17:26 -08004986 if (!argvlist[0][0]) {
4987 PyErr_SetString(PyExc_ValueError,
4988 "execve: argv first element cannot be empty");
4989 goto fail;
4990 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004991
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 envlist = parse_envlist(env, &envc);
4993 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004994 goto fail;
4995
Steve Dowerbce26262016-11-19 19:17:26 -08004996 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004997#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10004998 if (path->fd > -1)
4999 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005000 else
5001#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005002#ifdef HAVE_WEXECV
5003 _wexecve(path->wide, argvlist, envlist);
5004#else
Larry Hastings2f936352014-08-05 14:04:04 +10005005 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005006#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005007 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005008
5009 /* If we get here it's definitely an error */
5010
Larry Hastings2f936352014-08-05 14:04:04 +10005011 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005012
Steve Dowercc16be82016-09-08 10:35:16 -07005013 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005015 if (argvlist)
5016 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005017 return NULL;
5018}
Steve Dowercc16be82016-09-08 10:35:16 -07005019
Larry Hastings9cf065c2012-06-22 16:30:09 -07005020#endif /* HAVE_EXECV */
5021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005022
Steve Dowercc16be82016-09-08 10:35:16 -07005023#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005024/*[clinic input]
5025os.spawnv
5026
5027 mode: int
5028 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005029 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005030 Path of executable file.
5031 argv: object
5032 Tuple or list of strings.
5033 /
5034
5035Execute the program specified by path in a new process.
5036[clinic start generated code]*/
5037
Larry Hastings2f936352014-08-05 14:04:04 +10005038static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005039os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5040/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005041{
Steve Dowercc16be82016-09-08 10:35:16 -07005042 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005043 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005045 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005047
Victor Stinner8c62be82010-05-06 00:08:46 +00005048 /* spawnv has three arguments: (mode, path, argv), where
5049 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005050
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 if (PyList_Check(argv)) {
5052 argc = PyList_Size(argv);
5053 getitem = PyList_GetItem;
5054 }
5055 else if (PyTuple_Check(argv)) {
5056 argc = PyTuple_Size(argv);
5057 getitem = PyTuple_GetItem;
5058 }
5059 else {
5060 PyErr_SetString(PyExc_TypeError,
5061 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005062 return NULL;
5063 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005064 if (argc == 0) {
5065 PyErr_SetString(PyExc_ValueError,
5066 "spawnv() arg 2 cannot be empty");
5067 return NULL;
5068 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005069
Steve Dowercc16be82016-09-08 10:35:16 -07005070 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 return PyErr_NoMemory();
5073 }
5074 for (i = 0; i < argc; i++) {
5075 if (!fsconvert_strdup((*getitem)(argv, i),
5076 &argvlist[i])) {
5077 free_string_array(argvlist, i);
5078 PyErr_SetString(
5079 PyExc_TypeError,
5080 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 return NULL;
5082 }
Steve Dower93ff8722016-11-19 19:03:54 -08005083 if (i == 0 && !argvlist[0][0]) {
5084 free_string_array(argvlist, i);
5085 PyErr_SetString(
5086 PyExc_ValueError,
5087 "spawnv() arg 2 first element cannot be empty");
5088 return NULL;
5089 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 }
5091 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005092
Victor Stinner8c62be82010-05-06 00:08:46 +00005093 if (mode == _OLD_P_OVERLAY)
5094 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005095
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005097 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005098#ifdef HAVE_WSPAWNV
5099 spawnval = _wspawnv(mode, path->wide, argvlist);
5100#else
5101 spawnval = _spawnv(mode, path->narrow, argvlist);
5102#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005103 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005105
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005107
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 if (spawnval == -1)
5109 return posix_error();
5110 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005111 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005112}
5113
5114
Larry Hastings2f936352014-08-05 14:04:04 +10005115/*[clinic input]
5116os.spawnve
5117
5118 mode: int
5119 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005120 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005121 Path of executable file.
5122 argv: object
5123 Tuple or list of strings.
5124 env: object
5125 Dictionary of strings mapping to strings.
5126 /
5127
5128Execute the program specified by path in a new process.
5129[clinic start generated code]*/
5130
Larry Hastings2f936352014-08-05 14:04:04 +10005131static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005132os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005133 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005134/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005135{
Steve Dowercc16be82016-09-08 10:35:16 -07005136 EXECV_CHAR **argvlist;
5137 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005139 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005140 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5142 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005143
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 /* spawnve has four arguments: (mode, path, argv, env), where
5145 argv is a list or tuple of strings and env is a dictionary
5146 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 if (PyList_Check(argv)) {
5149 argc = PyList_Size(argv);
5150 getitem = PyList_GetItem;
5151 }
5152 else if (PyTuple_Check(argv)) {
5153 argc = PyTuple_Size(argv);
5154 getitem = PyTuple_GetItem;
5155 }
5156 else {
5157 PyErr_SetString(PyExc_TypeError,
5158 "spawnve() arg 2 must be a tuple or list");
5159 goto fail_0;
5160 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005161 if (argc == 0) {
5162 PyErr_SetString(PyExc_ValueError,
5163 "spawnve() arg 2 cannot be empty");
5164 goto fail_0;
5165 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 if (!PyMapping_Check(env)) {
5167 PyErr_SetString(PyExc_TypeError,
5168 "spawnve() arg 3 must be a mapping object");
5169 goto fail_0;
5170 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005171
Steve Dowercc16be82016-09-08 10:35:16 -07005172 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 if (argvlist == NULL) {
5174 PyErr_NoMemory();
5175 goto fail_0;
5176 }
5177 for (i = 0; i < argc; i++) {
5178 if (!fsconvert_strdup((*getitem)(argv, i),
5179 &argvlist[i]))
5180 {
5181 lastarg = i;
5182 goto fail_1;
5183 }
Steve Dowerbce26262016-11-19 19:17:26 -08005184 if (i == 0 && !argvlist[0][0]) {
5185 lastarg = i;
5186 PyErr_SetString(
5187 PyExc_ValueError,
5188 "spawnv() arg 2 first element cannot be empty");
5189 goto fail_1;
5190 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005191 }
5192 lastarg = argc;
5193 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005194
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 envlist = parse_envlist(env, &envc);
5196 if (envlist == NULL)
5197 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005198
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 if (mode == _OLD_P_OVERLAY)
5200 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005201
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005203 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005204#ifdef HAVE_WSPAWNV
5205 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5206#else
5207 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5208#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005209 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005211
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 if (spawnval == -1)
5213 (void) posix_error();
5214 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005215 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005216
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 while (--envc >= 0)
5218 PyMem_DEL(envlist[envc]);
5219 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005220 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005222 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005223 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005224}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005225
Guido van Rossuma1065681999-01-25 23:20:23 +00005226#endif /* HAVE_SPAWNV */
5227
5228
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005229#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005230/*[clinic input]
5231os.fork1
5232
5233Fork a child process with a single multiplexed (i.e., not bound) thread.
5234
5235Return 0 to child process and PID of child to parent process.
5236[clinic start generated code]*/
5237
Larry Hastings2f936352014-08-05 14:04:04 +10005238static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005239os_fork1_impl(PyObject *module)
5240/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005241{
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 pid_t pid;
5243 int result = 0;
5244 _PyImport_AcquireLock();
5245 pid = fork1();
5246 if (pid == 0) {
5247 /* child: this clobbers and resets the import lock. */
5248 PyOS_AfterFork();
5249 } else {
5250 /* parent: release the import lock. */
5251 result = _PyImport_ReleaseLock();
5252 }
5253 if (pid == -1)
5254 return posix_error();
5255 if (result < 0) {
5256 /* Don't clobber the OSError if the fork failed. */
5257 PyErr_SetString(PyExc_RuntimeError,
5258 "not holding the import lock");
5259 return NULL;
5260 }
5261 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005262}
Larry Hastings2f936352014-08-05 14:04:04 +10005263#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005264
5265
Guido van Rossumad0ee831995-03-01 10:34:45 +00005266#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005267/*[clinic input]
5268os.fork
5269
5270Fork a child process.
5271
5272Return 0 to child process and PID of child to parent process.
5273[clinic start generated code]*/
5274
Larry Hastings2f936352014-08-05 14:04:04 +10005275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005276os_fork_impl(PyObject *module)
5277/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005278{
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 pid_t pid;
5280 int result = 0;
5281 _PyImport_AcquireLock();
5282 pid = fork();
5283 if (pid == 0) {
5284 /* child: this clobbers and resets the import lock. */
5285 PyOS_AfterFork();
5286 } else {
5287 /* parent: release the import lock. */
5288 result = _PyImport_ReleaseLock();
5289 }
5290 if (pid == -1)
5291 return posix_error();
5292 if (result < 0) {
5293 /* Don't clobber the OSError if the fork failed. */
5294 PyErr_SetString(PyExc_RuntimeError,
5295 "not holding the import lock");
5296 return NULL;
5297 }
5298 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005299}
Larry Hastings2f936352014-08-05 14:04:04 +10005300#endif /* HAVE_FORK */
5301
Guido van Rossum85e3b011991-06-03 12:42:10 +00005302
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005303#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005304#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005305/*[clinic input]
5306os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005307
Larry Hastings2f936352014-08-05 14:04:04 +10005308 policy: int
5309
5310Get the maximum scheduling priority for policy.
5311[clinic start generated code]*/
5312
Larry Hastings2f936352014-08-05 14:04:04 +10005313static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005314os_sched_get_priority_max_impl(PyObject *module, int policy)
5315/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005316{
5317 int max;
5318
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005319 max = sched_get_priority_max(policy);
5320 if (max < 0)
5321 return posix_error();
5322 return PyLong_FromLong(max);
5323}
5324
Larry Hastings2f936352014-08-05 14:04:04 +10005325
5326/*[clinic input]
5327os.sched_get_priority_min
5328
5329 policy: int
5330
5331Get the minimum scheduling priority for policy.
5332[clinic start generated code]*/
5333
Larry Hastings2f936352014-08-05 14:04:04 +10005334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005335os_sched_get_priority_min_impl(PyObject *module, int policy)
5336/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005337{
5338 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005339 if (min < 0)
5340 return posix_error();
5341 return PyLong_FromLong(min);
5342}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005343#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5344
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005345
Larry Hastings2f936352014-08-05 14:04:04 +10005346#ifdef HAVE_SCHED_SETSCHEDULER
5347/*[clinic input]
5348os.sched_getscheduler
5349 pid: pid_t
5350 /
5351
5352Get the scheduling policy for the process identifiedy by pid.
5353
5354Passing 0 for pid returns the scheduling policy for the calling process.
5355[clinic start generated code]*/
5356
Larry Hastings2f936352014-08-05 14:04:04 +10005357static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005358os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5359/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005360{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005361 int policy;
5362
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005363 policy = sched_getscheduler(pid);
5364 if (policy < 0)
5365 return posix_error();
5366 return PyLong_FromLong(policy);
5367}
Larry Hastings2f936352014-08-05 14:04:04 +10005368#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005369
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005370
5371#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005372/*[clinic input]
5373class os.sched_param "PyObject *" "&SchedParamType"
5374
5375@classmethod
5376os.sched_param.__new__
5377
5378 sched_priority: object
5379 A scheduling parameter.
5380
5381Current has only one field: sched_priority");
5382[clinic start generated code]*/
5383
Larry Hastings2f936352014-08-05 14:04:04 +10005384static PyObject *
5385os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005386/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005387{
5388 PyObject *res;
5389
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005390 res = PyStructSequence_New(type);
5391 if (!res)
5392 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005393 Py_INCREF(sched_priority);
5394 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005395 return res;
5396}
5397
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005398
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005399PyDoc_VAR(os_sched_param__doc__);
5400
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005401static PyStructSequence_Field sched_param_fields[] = {
5402 {"sched_priority", "the scheduling priority"},
5403 {0}
5404};
5405
5406static PyStructSequence_Desc sched_param_desc = {
5407 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005408 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005409 sched_param_fields,
5410 1
5411};
5412
5413static int
5414convert_sched_param(PyObject *param, struct sched_param *res)
5415{
5416 long priority;
5417
5418 if (Py_TYPE(param) != &SchedParamType) {
5419 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5420 return 0;
5421 }
5422 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5423 if (priority == -1 && PyErr_Occurred())
5424 return 0;
5425 if (priority > INT_MAX || priority < INT_MIN) {
5426 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5427 return 0;
5428 }
5429 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5430 return 1;
5431}
Larry Hastings2f936352014-08-05 14:04:04 +10005432#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005433
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005434
5435#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005436/*[clinic input]
5437os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005438
Larry Hastings2f936352014-08-05 14:04:04 +10005439 pid: pid_t
5440 policy: int
5441 param: sched_param
5442 /
5443
5444Set the scheduling policy for the process identified by pid.
5445
5446If pid is 0, the calling process is changed.
5447param is an instance of sched_param.
5448[clinic start generated code]*/
5449
Larry Hastings2f936352014-08-05 14:04:04 +10005450static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005451os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005452 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005453/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005454{
Jesus Cea9c822272011-09-10 01:40:52 +02005455 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005456 ** sched_setscheduler() returns 0 in Linux, but the previous
5457 ** scheduling policy under Solaris/Illumos, and others.
5458 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005459 */
Larry Hastings2f936352014-08-05 14:04:04 +10005460 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005461 return posix_error();
5462 Py_RETURN_NONE;
5463}
Larry Hastings2f936352014-08-05 14:04:04 +10005464#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005465
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005466
5467#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005468/*[clinic input]
5469os.sched_getparam
5470 pid: pid_t
5471 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005472
Larry Hastings2f936352014-08-05 14:04:04 +10005473Returns scheduling parameters for the process identified by pid.
5474
5475If pid is 0, returns parameters for the calling process.
5476Return value is an instance of sched_param.
5477[clinic start generated code]*/
5478
Larry Hastings2f936352014-08-05 14:04:04 +10005479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005480os_sched_getparam_impl(PyObject *module, pid_t pid)
5481/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005482{
5483 struct sched_param param;
5484 PyObject *result;
5485 PyObject *priority;
5486
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005487 if (sched_getparam(pid, &param))
5488 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005489 result = PyStructSequence_New(&SchedParamType);
5490 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005491 return NULL;
5492 priority = PyLong_FromLong(param.sched_priority);
5493 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005494 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005495 return NULL;
5496 }
Larry Hastings2f936352014-08-05 14:04:04 +10005497 PyStructSequence_SET_ITEM(result, 0, priority);
5498 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005499}
5500
Larry Hastings2f936352014-08-05 14:04:04 +10005501
5502/*[clinic input]
5503os.sched_setparam
5504 pid: pid_t
5505 param: sched_param
5506 /
5507
5508Set scheduling parameters for the process identified by pid.
5509
5510If pid is 0, sets parameters for the calling process.
5511param should be an instance of sched_param.
5512[clinic start generated code]*/
5513
Larry Hastings2f936352014-08-05 14:04:04 +10005514static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005515os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005516 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005517/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005518{
5519 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005520 return posix_error();
5521 Py_RETURN_NONE;
5522}
Larry Hastings2f936352014-08-05 14:04:04 +10005523#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005524
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005525
5526#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005527/*[clinic input]
5528os.sched_rr_get_interval -> double
5529 pid: pid_t
5530 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005531
Larry Hastings2f936352014-08-05 14:04:04 +10005532Return the round-robin quantum for the process identified by pid, in seconds.
5533
5534Value returned is a float.
5535[clinic start generated code]*/
5536
Larry Hastings2f936352014-08-05 14:04:04 +10005537static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005538os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5539/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005540{
5541 struct timespec interval;
5542 if (sched_rr_get_interval(pid, &interval)) {
5543 posix_error();
5544 return -1.0;
5545 }
5546 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5547}
5548#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005549
Larry Hastings2f936352014-08-05 14:04:04 +10005550
5551/*[clinic input]
5552os.sched_yield
5553
5554Voluntarily relinquish the CPU.
5555[clinic start generated code]*/
5556
Larry Hastings2f936352014-08-05 14:04:04 +10005557static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005558os_sched_yield_impl(PyObject *module)
5559/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005560{
5561 if (sched_yield())
5562 return posix_error();
5563 Py_RETURN_NONE;
5564}
5565
Benjamin Peterson2740af82011-08-02 17:41:34 -05005566#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005567/* The minimum number of CPUs allocated in a cpu_set_t */
5568static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005569
Larry Hastings2f936352014-08-05 14:04:04 +10005570/*[clinic input]
5571os.sched_setaffinity
5572 pid: pid_t
5573 mask : object
5574 /
5575
5576Set the CPU affinity of the process identified by pid to mask.
5577
5578mask should be an iterable of integers identifying CPUs.
5579[clinic start generated code]*/
5580
Larry Hastings2f936352014-08-05 14:04:04 +10005581static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005582os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5583/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005584{
Antoine Pitrou84869872012-08-04 16:16:35 +02005585 int ncpus;
5586 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005587 cpu_set_t *cpu_set = NULL;
5588 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005589
Larry Hastings2f936352014-08-05 14:04:04 +10005590 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005591 if (iterator == NULL)
5592 return NULL;
5593
5594 ncpus = NCPUS_START;
5595 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005596 cpu_set = CPU_ALLOC(ncpus);
5597 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005598 PyErr_NoMemory();
5599 goto error;
5600 }
Larry Hastings2f936352014-08-05 14:04:04 +10005601 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005602
5603 while ((item = PyIter_Next(iterator))) {
5604 long cpu;
5605 if (!PyLong_Check(item)) {
5606 PyErr_Format(PyExc_TypeError,
5607 "expected an iterator of ints, "
5608 "but iterator yielded %R",
5609 Py_TYPE(item));
5610 Py_DECREF(item);
5611 goto error;
5612 }
5613 cpu = PyLong_AsLong(item);
5614 Py_DECREF(item);
5615 if (cpu < 0) {
5616 if (!PyErr_Occurred())
5617 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5618 goto error;
5619 }
5620 if (cpu > INT_MAX - 1) {
5621 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5622 goto error;
5623 }
5624 if (cpu >= ncpus) {
5625 /* Grow CPU mask to fit the CPU number */
5626 int newncpus = ncpus;
5627 cpu_set_t *newmask;
5628 size_t newsetsize;
5629 while (newncpus <= cpu) {
5630 if (newncpus > INT_MAX / 2)
5631 newncpus = cpu + 1;
5632 else
5633 newncpus = newncpus * 2;
5634 }
5635 newmask = CPU_ALLOC(newncpus);
5636 if (newmask == NULL) {
5637 PyErr_NoMemory();
5638 goto error;
5639 }
5640 newsetsize = CPU_ALLOC_SIZE(newncpus);
5641 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005642 memcpy(newmask, cpu_set, setsize);
5643 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005644 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005645 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005646 ncpus = newncpus;
5647 }
Larry Hastings2f936352014-08-05 14:04:04 +10005648 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005649 }
5650 Py_CLEAR(iterator);
5651
Larry Hastings2f936352014-08-05 14:04:04 +10005652 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005653 posix_error();
5654 goto error;
5655 }
Larry Hastings2f936352014-08-05 14:04:04 +10005656 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005657 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005658
5659error:
Larry Hastings2f936352014-08-05 14:04:04 +10005660 if (cpu_set)
5661 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005662 Py_XDECREF(iterator);
5663 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005664}
5665
Larry Hastings2f936352014-08-05 14:04:04 +10005666
5667/*[clinic input]
5668os.sched_getaffinity
5669 pid: pid_t
5670 /
5671
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005672Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005673
5674The affinity is returned as a set of CPU identifiers.
5675[clinic start generated code]*/
5676
Larry Hastings2f936352014-08-05 14:04:04 +10005677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005678os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005679/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005680{
Antoine Pitrou84869872012-08-04 16:16:35 +02005681 int cpu, ncpus, count;
5682 size_t setsize;
5683 cpu_set_t *mask = NULL;
5684 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005685
Antoine Pitrou84869872012-08-04 16:16:35 +02005686 ncpus = NCPUS_START;
5687 while (1) {
5688 setsize = CPU_ALLOC_SIZE(ncpus);
5689 mask = CPU_ALLOC(ncpus);
5690 if (mask == NULL)
5691 return PyErr_NoMemory();
5692 if (sched_getaffinity(pid, setsize, mask) == 0)
5693 break;
5694 CPU_FREE(mask);
5695 if (errno != EINVAL)
5696 return posix_error();
5697 if (ncpus > INT_MAX / 2) {
5698 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5699 "a large enough CPU set");
5700 return NULL;
5701 }
5702 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005703 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005704
5705 res = PySet_New(NULL);
5706 if (res == NULL)
5707 goto error;
5708 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5709 if (CPU_ISSET_S(cpu, setsize, mask)) {
5710 PyObject *cpu_num = PyLong_FromLong(cpu);
5711 --count;
5712 if (cpu_num == NULL)
5713 goto error;
5714 if (PySet_Add(res, cpu_num)) {
5715 Py_DECREF(cpu_num);
5716 goto error;
5717 }
5718 Py_DECREF(cpu_num);
5719 }
5720 }
5721 CPU_FREE(mask);
5722 return res;
5723
5724error:
5725 if (mask)
5726 CPU_FREE(mask);
5727 Py_XDECREF(res);
5728 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005729}
5730
Benjamin Peterson2740af82011-08-02 17:41:34 -05005731#endif /* HAVE_SCHED_SETAFFINITY */
5732
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005733#endif /* HAVE_SCHED_H */
5734
Larry Hastings2f936352014-08-05 14:04:04 +10005735
Neal Norwitzb59798b2003-03-21 01:43:31 +00005736/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005737/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5738#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005739#define DEV_PTY_FILE "/dev/ptc"
5740#define HAVE_DEV_PTMX
5741#else
5742#define DEV_PTY_FILE "/dev/ptmx"
5743#endif
5744
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005745#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005746#ifdef HAVE_PTY_H
5747#include <pty.h>
5748#else
5749#ifdef HAVE_LIBUTIL_H
5750#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005751#else
5752#ifdef HAVE_UTIL_H
5753#include <util.h>
5754#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005755#endif /* HAVE_LIBUTIL_H */
5756#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005757#ifdef HAVE_STROPTS_H
5758#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005759#endif
5760#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005761
Larry Hastings2f936352014-08-05 14:04:04 +10005762
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005763#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005764/*[clinic input]
5765os.openpty
5766
5767Open a pseudo-terminal.
5768
5769Return a tuple of (master_fd, slave_fd) containing open file descriptors
5770for both the master and slave ends.
5771[clinic start generated code]*/
5772
Larry Hastings2f936352014-08-05 14:04:04 +10005773static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005774os_openpty_impl(PyObject *module)
5775/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005776{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005777 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005778#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005779 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005780#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005781#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005782 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005783#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005784 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005785#endif
5786#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005787
Thomas Wouters70c21a12000-07-14 14:28:33 +00005788#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005790 goto posix_error;
5791
5792 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5793 goto error;
5794 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5795 goto error;
5796
Neal Norwitzb59798b2003-03-21 01:43:31 +00005797#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005798 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5799 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005800 goto posix_error;
5801 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5802 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005803
Victor Stinnerdaf45552013-08-28 00:53:59 +02005804 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005806 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005807
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005808#else
Victor Stinner000de532013-11-25 23:19:58 +01005809 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005810 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005811 goto posix_error;
5812
Victor Stinner8c62be82010-05-06 00:08:46 +00005813 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005814
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 /* change permission of slave */
5816 if (grantpt(master_fd) < 0) {
5817 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005818 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005819 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005820
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 /* unlock slave */
5822 if (unlockpt(master_fd) < 0) {
5823 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005824 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005825 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005826
Victor Stinner8c62be82010-05-06 00:08:46 +00005827 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005828
Victor Stinner8c62be82010-05-06 00:08:46 +00005829 slave_name = ptsname(master_fd); /* get name of slave */
5830 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005831 goto posix_error;
5832
5833 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005834 if (slave_fd == -1)
5835 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005836
5837 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5838 goto posix_error;
5839
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005840#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005841 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5842 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005843#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005844 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005845#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005846#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005847#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005848
Victor Stinner8c62be82010-05-06 00:08:46 +00005849 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005850
Victor Stinnerdaf45552013-08-28 00:53:59 +02005851posix_error:
5852 posix_error();
5853error:
5854 if (master_fd != -1)
5855 close(master_fd);
5856 if (slave_fd != -1)
5857 close(slave_fd);
5858 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005859}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005860#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005861
Larry Hastings2f936352014-08-05 14:04:04 +10005862
Fred Drake8cef4cf2000-06-28 16:40:38 +00005863#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005864/*[clinic input]
5865os.forkpty
5866
5867Fork a new process with a new pseudo-terminal as controlling tty.
5868
5869Returns a tuple of (pid, master_fd).
5870Like fork(), return pid of 0 to the child process,
5871and pid of child to the parent process.
5872To both, return fd of newly opened pseudo-terminal.
5873[clinic start generated code]*/
5874
Larry Hastings2f936352014-08-05 14:04:04 +10005875static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005876os_forkpty_impl(PyObject *module)
5877/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005878{
Victor Stinner8c62be82010-05-06 00:08:46 +00005879 int master_fd = -1, result = 0;
5880 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005881
Victor Stinner8c62be82010-05-06 00:08:46 +00005882 _PyImport_AcquireLock();
5883 pid = forkpty(&master_fd, NULL, NULL, NULL);
5884 if (pid == 0) {
5885 /* child: this clobbers and resets the import lock. */
5886 PyOS_AfterFork();
5887 } else {
5888 /* parent: release the import lock. */
5889 result = _PyImport_ReleaseLock();
5890 }
5891 if (pid == -1)
5892 return posix_error();
5893 if (result < 0) {
5894 /* Don't clobber the OSError if the fork failed. */
5895 PyErr_SetString(PyExc_RuntimeError,
5896 "not holding the import lock");
5897 return NULL;
5898 }
5899 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005900}
Larry Hastings2f936352014-08-05 14:04:04 +10005901#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005902
Ross Lagerwall7807c352011-03-17 20:20:30 +02005903
Guido van Rossumad0ee831995-03-01 10:34:45 +00005904#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005905/*[clinic input]
5906os.getegid
5907
5908Return the current process's effective group id.
5909[clinic start generated code]*/
5910
Larry Hastings2f936352014-08-05 14:04:04 +10005911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005912os_getegid_impl(PyObject *module)
5913/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005914{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005915 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005916}
Larry Hastings2f936352014-08-05 14:04:04 +10005917#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005918
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005919
Guido van Rossumad0ee831995-03-01 10:34:45 +00005920#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005921/*[clinic input]
5922os.geteuid
5923
5924Return the current process's effective user id.
5925[clinic start generated code]*/
5926
Larry Hastings2f936352014-08-05 14:04:04 +10005927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005928os_geteuid_impl(PyObject *module)
5929/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005930{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005931 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005932}
Larry Hastings2f936352014-08-05 14:04:04 +10005933#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005934
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005935
Guido van Rossumad0ee831995-03-01 10:34:45 +00005936#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005937/*[clinic input]
5938os.getgid
5939
5940Return the current process's group id.
5941[clinic start generated code]*/
5942
Larry Hastings2f936352014-08-05 14:04:04 +10005943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005944os_getgid_impl(PyObject *module)
5945/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005946{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005947 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005948}
Larry Hastings2f936352014-08-05 14:04:04 +10005949#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005951
Berker Peksag39404992016-09-15 20:45:16 +03005952#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10005953/*[clinic input]
5954os.getpid
5955
5956Return the current process id.
5957[clinic start generated code]*/
5958
Larry Hastings2f936352014-08-05 14:04:04 +10005959static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005960os_getpid_impl(PyObject *module)
5961/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005962{
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005964}
Berker Peksag39404992016-09-15 20:45:16 +03005965#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005966
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005967#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005968
5969/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005970PyDoc_STRVAR(posix_getgrouplist__doc__,
5971"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5972Returns a list of groups to which a user belongs.\n\n\
5973 user: username to lookup\n\
5974 group: base group id of the user");
5975
5976static PyObject *
5977posix_getgrouplist(PyObject *self, PyObject *args)
5978{
5979#ifdef NGROUPS_MAX
5980#define MAX_GROUPS NGROUPS_MAX
5981#else
5982 /* defined to be 16 on Solaris7, so this should be a small number */
5983#define MAX_GROUPS 64
5984#endif
5985
5986 const char *user;
5987 int i, ngroups;
5988 PyObject *list;
5989#ifdef __APPLE__
5990 int *groups, basegid;
5991#else
5992 gid_t *groups, basegid;
5993#endif
5994 ngroups = MAX_GROUPS;
5995
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005996#ifdef __APPLE__
5997 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005998 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005999#else
6000 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6001 _Py_Gid_Converter, &basegid))
6002 return NULL;
6003#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006004
6005#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006006 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006007#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006008 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006009#endif
6010 if (groups == NULL)
6011 return PyErr_NoMemory();
6012
6013 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6014 PyMem_Del(groups);
6015 return posix_error();
6016 }
6017
6018 list = PyList_New(ngroups);
6019 if (list == NULL) {
6020 PyMem_Del(groups);
6021 return NULL;
6022 }
6023
6024 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006025#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006026 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006027#else
6028 PyObject *o = _PyLong_FromGid(groups[i]);
6029#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006030 if (o == NULL) {
6031 Py_DECREF(list);
6032 PyMem_Del(groups);
6033 return NULL;
6034 }
6035 PyList_SET_ITEM(list, i, o);
6036 }
6037
6038 PyMem_Del(groups);
6039
6040 return list;
6041}
Larry Hastings2f936352014-08-05 14:04:04 +10006042#endif /* HAVE_GETGROUPLIST */
6043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006044
Fred Drakec9680921999-12-13 16:37:25 +00006045#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006046/*[clinic input]
6047os.getgroups
6048
6049Return list of supplemental group IDs for the process.
6050[clinic start generated code]*/
6051
Larry Hastings2f936352014-08-05 14:04:04 +10006052static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006053os_getgroups_impl(PyObject *module)
6054/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006055{
6056 PyObject *result = NULL;
6057
Fred Drakec9680921999-12-13 16:37:25 +00006058#ifdef NGROUPS_MAX
6059#define MAX_GROUPS NGROUPS_MAX
6060#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006062#define MAX_GROUPS 64
6063#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006065
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006066 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006067 * This is a helper variable to store the intermediate result when
6068 * that happens.
6069 *
6070 * To keep the code readable the OSX behaviour is unconditional,
6071 * according to the POSIX spec this should be safe on all unix-y
6072 * systems.
6073 */
6074 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006076
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006077#ifdef __APPLE__
6078 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6079 * there are more groups than can fit in grouplist. Therefore, on OS X
6080 * always first call getgroups with length 0 to get the actual number
6081 * of groups.
6082 */
6083 n = getgroups(0, NULL);
6084 if (n < 0) {
6085 return posix_error();
6086 } else if (n <= MAX_GROUPS) {
6087 /* groups will fit in existing array */
6088 alt_grouplist = grouplist;
6089 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006090 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006091 if (alt_grouplist == NULL) {
6092 errno = EINVAL;
6093 return posix_error();
6094 }
6095 }
6096
6097 n = getgroups(n, alt_grouplist);
6098 if (n == -1) {
6099 if (alt_grouplist != grouplist) {
6100 PyMem_Free(alt_grouplist);
6101 }
6102 return posix_error();
6103 }
6104#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006106 if (n < 0) {
6107 if (errno == EINVAL) {
6108 n = getgroups(0, NULL);
6109 if (n == -1) {
6110 return posix_error();
6111 }
6112 if (n == 0) {
6113 /* Avoid malloc(0) */
6114 alt_grouplist = grouplist;
6115 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006116 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006117 if (alt_grouplist == NULL) {
6118 errno = EINVAL;
6119 return posix_error();
6120 }
6121 n = getgroups(n, alt_grouplist);
6122 if (n == -1) {
6123 PyMem_Free(alt_grouplist);
6124 return posix_error();
6125 }
6126 }
6127 } else {
6128 return posix_error();
6129 }
6130 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006131#endif
6132
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006133 result = PyList_New(n);
6134 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006135 int i;
6136 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006137 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006138 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006139 Py_DECREF(result);
6140 result = NULL;
6141 break;
Fred Drakec9680921999-12-13 16:37:25 +00006142 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006144 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006145 }
6146
6147 if (alt_grouplist != grouplist) {
6148 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006150
Fred Drakec9680921999-12-13 16:37:25 +00006151 return result;
6152}
Larry Hastings2f936352014-08-05 14:04:04 +10006153#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006154
Antoine Pitroub7572f02009-12-02 20:46:48 +00006155#ifdef HAVE_INITGROUPS
6156PyDoc_STRVAR(posix_initgroups__doc__,
6157"initgroups(username, gid) -> None\n\n\
6158Call the system initgroups() to initialize the group access list with all of\n\
6159the groups of which the specified username is a member, plus the specified\n\
6160group id.");
6161
Larry Hastings2f936352014-08-05 14:04:04 +10006162/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006163static PyObject *
6164posix_initgroups(PyObject *self, PyObject *args)
6165{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006166 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006167 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006168 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006169#ifdef __APPLE__
6170 int gid;
6171#else
6172 gid_t gid;
6173#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006174
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006175#ifdef __APPLE__
6176 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6177 PyUnicode_FSConverter, &oname,
6178 &gid))
6179#else
6180 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6181 PyUnicode_FSConverter, &oname,
6182 _Py_Gid_Converter, &gid))
6183#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006184 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006185 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006186
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006187 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006188 Py_DECREF(oname);
6189 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006190 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006191
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006192 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006193}
Larry Hastings2f936352014-08-05 14:04:04 +10006194#endif /* HAVE_INITGROUPS */
6195
Antoine Pitroub7572f02009-12-02 20:46:48 +00006196
Martin v. Löwis606edc12002-06-13 21:09:11 +00006197#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006198/*[clinic input]
6199os.getpgid
6200
6201 pid: pid_t
6202
6203Call the system call getpgid(), and return the result.
6204[clinic start generated code]*/
6205
Larry Hastings2f936352014-08-05 14:04:04 +10006206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006207os_getpgid_impl(PyObject *module, pid_t pid)
6208/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006209{
6210 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 if (pgid < 0)
6212 return posix_error();
6213 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006214}
6215#endif /* HAVE_GETPGID */
6216
6217
Guido van Rossumb6775db1994-08-01 11:34:53 +00006218#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006219/*[clinic input]
6220os.getpgrp
6221
6222Return the current process group id.
6223[clinic start generated code]*/
6224
Larry Hastings2f936352014-08-05 14:04:04 +10006225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006226os_getpgrp_impl(PyObject *module)
6227/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006228{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006229#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006230 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006231#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006233#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006234}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006235#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006236
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006237
Guido van Rossumb6775db1994-08-01 11:34:53 +00006238#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006239/*[clinic input]
6240os.setpgrp
6241
6242Make the current process the leader of its process group.
6243[clinic start generated code]*/
6244
Larry Hastings2f936352014-08-05 14:04:04 +10006245static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006246os_setpgrp_impl(PyObject *module)
6247/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006248{
Guido van Rossum64933891994-10-20 21:56:42 +00006249#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006251#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006253#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006255 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006256}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006257#endif /* HAVE_SETPGRP */
6258
Guido van Rossumad0ee831995-03-01 10:34:45 +00006259#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006260
6261#ifdef MS_WINDOWS
6262#include <tlhelp32.h>
6263
6264static PyObject*
6265win32_getppid()
6266{
6267 HANDLE snapshot;
6268 pid_t mypid;
6269 PyObject* result = NULL;
6270 BOOL have_record;
6271 PROCESSENTRY32 pe;
6272
6273 mypid = getpid(); /* This function never fails */
6274
6275 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6276 if (snapshot == INVALID_HANDLE_VALUE)
6277 return PyErr_SetFromWindowsErr(GetLastError());
6278
6279 pe.dwSize = sizeof(pe);
6280 have_record = Process32First(snapshot, &pe);
6281 while (have_record) {
6282 if (mypid == (pid_t)pe.th32ProcessID) {
6283 /* We could cache the ulong value in a static variable. */
6284 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6285 break;
6286 }
6287
6288 have_record = Process32Next(snapshot, &pe);
6289 }
6290
6291 /* If our loop exits and our pid was not found (result will be NULL)
6292 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6293 * error anyway, so let's raise it. */
6294 if (!result)
6295 result = PyErr_SetFromWindowsErr(GetLastError());
6296
6297 CloseHandle(snapshot);
6298
6299 return result;
6300}
6301#endif /*MS_WINDOWS*/
6302
Larry Hastings2f936352014-08-05 14:04:04 +10006303
6304/*[clinic input]
6305os.getppid
6306
6307Return the parent's process id.
6308
6309If the parent process has already exited, Windows machines will still
6310return its id; others systems will return the id of the 'init' process (1).
6311[clinic start generated code]*/
6312
Larry Hastings2f936352014-08-05 14:04:04 +10006313static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006314os_getppid_impl(PyObject *module)
6315/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006316{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006317#ifdef MS_WINDOWS
6318 return win32_getppid();
6319#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006321#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006322}
6323#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006325
Fred Drake12c6e2d1999-12-14 21:25:03 +00006326#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006327/*[clinic input]
6328os.getlogin
6329
6330Return the actual login name.
6331[clinic start generated code]*/
6332
Larry Hastings2f936352014-08-05 14:04:04 +10006333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006334os_getlogin_impl(PyObject *module)
6335/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006336{
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006338#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006339 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006340 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006341
6342 if (GetUserNameW(user_name, &num_chars)) {
6343 /* num_chars is the number of unicode chars plus null terminator */
6344 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006345 }
6346 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006347 result = PyErr_SetFromWindowsErr(GetLastError());
6348#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 char *name;
6350 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006351
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 errno = 0;
6353 name = getlogin();
6354 if (name == NULL) {
6355 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006356 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006357 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006358 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 }
6360 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006361 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006363#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006364 return result;
6365}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006366#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006367
Larry Hastings2f936352014-08-05 14:04:04 +10006368
Guido van Rossumad0ee831995-03-01 10:34:45 +00006369#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006370/*[clinic input]
6371os.getuid
6372
6373Return the current process's user id.
6374[clinic start generated code]*/
6375
Larry Hastings2f936352014-08-05 14:04:04 +10006376static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006377os_getuid_impl(PyObject *module)
6378/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006379{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006380 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006381}
Larry Hastings2f936352014-08-05 14:04:04 +10006382#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006384
Brian Curtineb24d742010-04-12 17:16:38 +00006385#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006386#define HAVE_KILL
6387#endif /* MS_WINDOWS */
6388
6389#ifdef HAVE_KILL
6390/*[clinic input]
6391os.kill
6392
6393 pid: pid_t
6394 signal: Py_ssize_t
6395 /
6396
6397Kill a process with a signal.
6398[clinic start generated code]*/
6399
Larry Hastings2f936352014-08-05 14:04:04 +10006400static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006401os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6402/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006403#ifndef MS_WINDOWS
6404{
6405 if (kill(pid, (int)signal) == -1)
6406 return posix_error();
6407 Py_RETURN_NONE;
6408}
6409#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006410{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006411 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006412 DWORD sig = (DWORD)signal;
6413 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006414 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006415
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 /* Console processes which share a common console can be sent CTRL+C or
6417 CTRL+BREAK events, provided they handle said events. */
6418 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006419 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 err = GetLastError();
6421 PyErr_SetFromWindowsErr(err);
6422 }
6423 else
6424 Py_RETURN_NONE;
6425 }
Brian Curtineb24d742010-04-12 17:16:38 +00006426
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6428 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006429 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 if (handle == NULL) {
6431 err = GetLastError();
6432 return PyErr_SetFromWindowsErr(err);
6433 }
Brian Curtineb24d742010-04-12 17:16:38 +00006434
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 if (TerminateProcess(handle, sig) == 0) {
6436 err = GetLastError();
6437 result = PyErr_SetFromWindowsErr(err);
6438 } else {
6439 Py_INCREF(Py_None);
6440 result = Py_None;
6441 }
Brian Curtineb24d742010-04-12 17:16:38 +00006442
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 CloseHandle(handle);
6444 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006445}
Larry Hastings2f936352014-08-05 14:04:04 +10006446#endif /* !MS_WINDOWS */
6447#endif /* HAVE_KILL */
6448
6449
6450#ifdef HAVE_KILLPG
6451/*[clinic input]
6452os.killpg
6453
6454 pgid: pid_t
6455 signal: int
6456 /
6457
6458Kill a process group with a signal.
6459[clinic start generated code]*/
6460
Larry Hastings2f936352014-08-05 14:04:04 +10006461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006462os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6463/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006464{
6465 /* XXX some man pages make the `pgid` parameter an int, others
6466 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6467 take the same type. Moreover, pid_t is always at least as wide as
6468 int (else compilation of this module fails), which is safe. */
6469 if (killpg(pgid, signal) == -1)
6470 return posix_error();
6471 Py_RETURN_NONE;
6472}
6473#endif /* HAVE_KILLPG */
6474
Brian Curtineb24d742010-04-12 17:16:38 +00006475
Guido van Rossumc0125471996-06-28 18:55:32 +00006476#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006477#ifdef HAVE_SYS_LOCK_H
6478#include <sys/lock.h>
6479#endif
6480
Larry Hastings2f936352014-08-05 14:04:04 +10006481/*[clinic input]
6482os.plock
6483 op: int
6484 /
6485
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006486Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006487[clinic start generated code]*/
6488
Larry Hastings2f936352014-08-05 14:04:04 +10006489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006490os_plock_impl(PyObject *module, int op)
6491/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006492{
Victor Stinner8c62be82010-05-06 00:08:46 +00006493 if (plock(op) == -1)
6494 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006495 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006496}
Larry Hastings2f936352014-08-05 14:04:04 +10006497#endif /* HAVE_PLOCK */
6498
Guido van Rossumc0125471996-06-28 18:55:32 +00006499
Guido van Rossumb6775db1994-08-01 11:34:53 +00006500#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006501/*[clinic input]
6502os.setuid
6503
6504 uid: uid_t
6505 /
6506
6507Set the current process's user id.
6508[clinic start generated code]*/
6509
Larry Hastings2f936352014-08-05 14:04:04 +10006510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006511os_setuid_impl(PyObject *module, uid_t uid)
6512/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006513{
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 if (setuid(uid) < 0)
6515 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006516 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006517}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006518#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006520
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006521#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006522/*[clinic input]
6523os.seteuid
6524
6525 euid: uid_t
6526 /
6527
6528Set the current process's effective user id.
6529[clinic start generated code]*/
6530
Larry Hastings2f936352014-08-05 14:04:04 +10006531static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006532os_seteuid_impl(PyObject *module, uid_t euid)
6533/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006534{
6535 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006537 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006538}
6539#endif /* HAVE_SETEUID */
6540
Larry Hastings2f936352014-08-05 14:04:04 +10006541
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006542#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006543/*[clinic input]
6544os.setegid
6545
6546 egid: gid_t
6547 /
6548
6549Set the current process's effective group id.
6550[clinic start generated code]*/
6551
Larry Hastings2f936352014-08-05 14:04:04 +10006552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006553os_setegid_impl(PyObject *module, gid_t egid)
6554/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006555{
6556 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006558 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006559}
6560#endif /* HAVE_SETEGID */
6561
Larry Hastings2f936352014-08-05 14:04:04 +10006562
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006563#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006564/*[clinic input]
6565os.setreuid
6566
6567 ruid: uid_t
6568 euid: uid_t
6569 /
6570
6571Set the current process's real and effective user ids.
6572[clinic start generated code]*/
6573
Larry Hastings2f936352014-08-05 14:04:04 +10006574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006575os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6576/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006577{
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 if (setreuid(ruid, euid) < 0) {
6579 return posix_error();
6580 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006581 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006583}
6584#endif /* HAVE_SETREUID */
6585
Larry Hastings2f936352014-08-05 14:04:04 +10006586
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006587#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006588/*[clinic input]
6589os.setregid
6590
6591 rgid: gid_t
6592 egid: gid_t
6593 /
6594
6595Set the current process's real and effective group ids.
6596[clinic start generated code]*/
6597
Larry Hastings2f936352014-08-05 14:04:04 +10006598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006599os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6600/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006601{
6602 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006603 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006604 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006605}
6606#endif /* HAVE_SETREGID */
6607
Larry Hastings2f936352014-08-05 14:04:04 +10006608
Guido van Rossumb6775db1994-08-01 11:34:53 +00006609#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006610/*[clinic input]
6611os.setgid
6612 gid: gid_t
6613 /
6614
6615Set the current process's group id.
6616[clinic start generated code]*/
6617
Larry Hastings2f936352014-08-05 14:04:04 +10006618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006619os_setgid_impl(PyObject *module, gid_t gid)
6620/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006621{
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 if (setgid(gid) < 0)
6623 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006624 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006625}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006626#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006627
Larry Hastings2f936352014-08-05 14:04:04 +10006628
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006629#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006630/*[clinic input]
6631os.setgroups
6632
6633 groups: object
6634 /
6635
6636Set the groups of the current process to list.
6637[clinic start generated code]*/
6638
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006640os_setgroups(PyObject *module, PyObject *groups)
6641/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006642{
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 int i, len;
6644 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006645
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 if (!PySequence_Check(groups)) {
6647 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6648 return NULL;
6649 }
6650 len = PySequence_Size(groups);
6651 if (len > MAX_GROUPS) {
6652 PyErr_SetString(PyExc_ValueError, "too many groups");
6653 return NULL;
6654 }
6655 for(i = 0; i < len; i++) {
6656 PyObject *elem;
6657 elem = PySequence_GetItem(groups, i);
6658 if (!elem)
6659 return NULL;
6660 if (!PyLong_Check(elem)) {
6661 PyErr_SetString(PyExc_TypeError,
6662 "groups must be integers");
6663 Py_DECREF(elem);
6664 return NULL;
6665 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006666 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 Py_DECREF(elem);
6668 return NULL;
6669 }
6670 }
6671 Py_DECREF(elem);
6672 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006673
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 if (setgroups(len, grouplist) < 0)
6675 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006676 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006677}
6678#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006679
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006680#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6681static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006682wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006683{
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 PyObject *result;
6685 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006686 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006687
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 if (pid == -1)
6689 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006690
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 if (struct_rusage == NULL) {
6692 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6693 if (m == NULL)
6694 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006695 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 Py_DECREF(m);
6697 if (struct_rusage == NULL)
6698 return NULL;
6699 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006700
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6702 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6703 if (!result)
6704 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006705
6706#ifndef doubletime
6707#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6708#endif
6709
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006711 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006713 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006714#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6716 SET_INT(result, 2, ru->ru_maxrss);
6717 SET_INT(result, 3, ru->ru_ixrss);
6718 SET_INT(result, 4, ru->ru_idrss);
6719 SET_INT(result, 5, ru->ru_isrss);
6720 SET_INT(result, 6, ru->ru_minflt);
6721 SET_INT(result, 7, ru->ru_majflt);
6722 SET_INT(result, 8, ru->ru_nswap);
6723 SET_INT(result, 9, ru->ru_inblock);
6724 SET_INT(result, 10, ru->ru_oublock);
6725 SET_INT(result, 11, ru->ru_msgsnd);
6726 SET_INT(result, 12, ru->ru_msgrcv);
6727 SET_INT(result, 13, ru->ru_nsignals);
6728 SET_INT(result, 14, ru->ru_nvcsw);
6729 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006730#undef SET_INT
6731
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 if (PyErr_Occurred()) {
6733 Py_DECREF(result);
6734 return NULL;
6735 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006736
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006738}
6739#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6740
Larry Hastings2f936352014-08-05 14:04:04 +10006741
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006742#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006743/*[clinic input]
6744os.wait3
6745
6746 options: int
6747Wait for completion of a child process.
6748
6749Returns a tuple of information about the child process:
6750 (pid, status, rusage)
6751[clinic start generated code]*/
6752
Larry Hastings2f936352014-08-05 14:04:04 +10006753static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006754os_wait3_impl(PyObject *module, int options)
6755/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006756{
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006759 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 WAIT_TYPE status;
6761 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006762
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006763 do {
6764 Py_BEGIN_ALLOW_THREADS
6765 pid = wait3(&status, options, &ru);
6766 Py_END_ALLOW_THREADS
6767 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6768 if (pid < 0)
6769 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006770
Victor Stinner4195b5c2012-02-08 23:03:19 +01006771 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006772}
6773#endif /* HAVE_WAIT3 */
6774
Larry Hastings2f936352014-08-05 14:04:04 +10006775
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006777/*[clinic input]
6778
6779os.wait4
6780
6781 pid: pid_t
6782 options: int
6783
6784Wait for completion of a specific child process.
6785
6786Returns a tuple of information about the child process:
6787 (pid, status, rusage)
6788[clinic start generated code]*/
6789
Larry Hastings2f936352014-08-05 14:04:04 +10006790static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006791os_wait4_impl(PyObject *module, pid_t pid, int options)
6792/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006793{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006794 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006796 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 WAIT_TYPE status;
6798 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006799
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006800 do {
6801 Py_BEGIN_ALLOW_THREADS
6802 res = wait4(pid, &status, options, &ru);
6803 Py_END_ALLOW_THREADS
6804 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6805 if (res < 0)
6806 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006807
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006808 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006809}
6810#endif /* HAVE_WAIT4 */
6811
Larry Hastings2f936352014-08-05 14:04:04 +10006812
Ross Lagerwall7807c352011-03-17 20:20:30 +02006813#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006814/*[clinic input]
6815os.waitid
6816
6817 idtype: idtype_t
6818 Must be one of be P_PID, P_PGID or P_ALL.
6819 id: id_t
6820 The id to wait on.
6821 options: int
6822 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6823 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6824 /
6825
6826Returns the result of waiting for a process or processes.
6827
6828Returns either waitid_result or None if WNOHANG is specified and there are
6829no children in a waitable state.
6830[clinic start generated code]*/
6831
Larry Hastings2f936352014-08-05 14:04:04 +10006832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006833os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6834/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006835{
6836 PyObject *result;
6837 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006838 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006839 siginfo_t si;
6840 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006841
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006842 do {
6843 Py_BEGIN_ALLOW_THREADS
6844 res = waitid(idtype, id, &si, options);
6845 Py_END_ALLOW_THREADS
6846 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6847 if (res < 0)
6848 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006849
6850 if (si.si_pid == 0)
6851 Py_RETURN_NONE;
6852
6853 result = PyStructSequence_New(&WaitidResultType);
6854 if (!result)
6855 return NULL;
6856
6857 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006858 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006859 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6860 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6861 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6862 if (PyErr_Occurred()) {
6863 Py_DECREF(result);
6864 return NULL;
6865 }
6866
6867 return result;
6868}
Larry Hastings2f936352014-08-05 14:04:04 +10006869#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006870
Larry Hastings2f936352014-08-05 14:04:04 +10006871
6872#if defined(HAVE_WAITPID)
6873/*[clinic input]
6874os.waitpid
6875 pid: pid_t
6876 options: int
6877 /
6878
6879Wait for completion of a given child process.
6880
6881Returns a tuple of information regarding the child process:
6882 (pid, status)
6883
6884The options argument is ignored on Windows.
6885[clinic start generated code]*/
6886
Larry Hastings2f936352014-08-05 14:04:04 +10006887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006888os_waitpid_impl(PyObject *module, pid_t pid, int options)
6889/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006890{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006891 pid_t res;
6892 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 WAIT_TYPE status;
6894 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006895
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006896 do {
6897 Py_BEGIN_ALLOW_THREADS
6898 res = waitpid(pid, &status, options);
6899 Py_END_ALLOW_THREADS
6900 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6901 if (res < 0)
6902 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006903
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006904 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006905}
Tim Petersab034fa2002-02-01 11:27:43 +00006906#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006907/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006908/*[clinic input]
6909os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006910 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006911 options: int
6912 /
6913
6914Wait for completion of a given process.
6915
6916Returns a tuple of information regarding the process:
6917 (pid, status << 8)
6918
6919The options argument is ignored on Windows.
6920[clinic start generated code]*/
6921
Larry Hastings2f936352014-08-05 14:04:04 +10006922static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006923os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006924/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006925{
6926 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006927 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006928 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006929
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006930 do {
6931 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08006932 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006933 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08006934 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 Py_END_ALLOW_THREADS
6936 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006937 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006938 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006939
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006941 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006942}
Larry Hastings2f936352014-08-05 14:04:04 +10006943#endif
6944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006945
Guido van Rossumad0ee831995-03-01 10:34:45 +00006946#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006947/*[clinic input]
6948os.wait
6949
6950Wait for completion of a child process.
6951
6952Returns a tuple of information about the child process:
6953 (pid, status)
6954[clinic start generated code]*/
6955
Larry Hastings2f936352014-08-05 14:04:04 +10006956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006957os_wait_impl(PyObject *module)
6958/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006959{
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006961 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 WAIT_TYPE status;
6963 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006964
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006965 do {
6966 Py_BEGIN_ALLOW_THREADS
6967 pid = wait(&status);
6968 Py_END_ALLOW_THREADS
6969 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6970 if (pid < 0)
6971 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006972
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006974}
Larry Hastings2f936352014-08-05 14:04:04 +10006975#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006977
Larry Hastings9cf065c2012-06-22 16:30:09 -07006978#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6979PyDoc_STRVAR(readlink__doc__,
6980"readlink(path, *, dir_fd=None) -> path\n\n\
6981Return a string representing the path to which the symbolic link points.\n\
6982\n\
6983If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6984 and path should be relative; path will then be relative to that directory.\n\
6985dir_fd may not be implemented on your platform.\n\
6986 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006987#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006988
Guido van Rossumb6775db1994-08-01 11:34:53 +00006989#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006990
Larry Hastings2f936352014-08-05 14:04:04 +10006991/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006992static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006993posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006994{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006995 path_t path;
6996 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02006997 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07006998 ssize_t length;
6999 PyObject *return_value = NULL;
7000 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007001
Larry Hastings9cf065c2012-06-22 16:30:09 -07007002 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007003 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007004 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7005 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007006 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007008
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007010#ifdef HAVE_READLINKAT
7011 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007012 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007013 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007014#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007015 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007016 Py_END_ALLOW_THREADS
7017
7018 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007019 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007020 goto exit;
7021 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007022 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007023
7024 if (PyUnicode_Check(path.object))
7025 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7026 else
7027 return_value = PyBytes_FromStringAndSize(buffer, length);
7028exit:
7029 path_cleanup(&path);
7030 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007031}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007032
Guido van Rossumb6775db1994-08-01 11:34:53 +00007033#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007034
Larry Hastings2f936352014-08-05 14:04:04 +10007035#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7036
7037static PyObject *
7038win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7039{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007040 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007041 DWORD n_bytes_returned;
7042 DWORD io_result;
7043 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007044 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007045 HANDLE reparse_point_handle;
7046
Martin Panter70214ad2016-08-04 02:38:59 +00007047 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7048 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007049 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007050
7051 static char *keywords[] = {"path", "dir_fd", NULL};
7052
7053 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7054 &po,
7055 dir_fd_unavailable, &dir_fd
7056 ))
7057 return NULL;
7058
7059 path = PyUnicode_AsUnicode(po);
7060 if (path == NULL)
7061 return NULL;
7062
7063 /* First get a handle to the reparse point */
7064 Py_BEGIN_ALLOW_THREADS
7065 reparse_point_handle = CreateFileW(
7066 path,
7067 0,
7068 0,
7069 0,
7070 OPEN_EXISTING,
7071 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7072 0);
7073 Py_END_ALLOW_THREADS
7074
7075 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7076 return win32_error_object("readlink", po);
7077
7078 Py_BEGIN_ALLOW_THREADS
7079 /* New call DeviceIoControl to read the reparse point */
7080 io_result = DeviceIoControl(
7081 reparse_point_handle,
7082 FSCTL_GET_REPARSE_POINT,
7083 0, 0, /* in buffer */
7084 target_buffer, sizeof(target_buffer),
7085 &n_bytes_returned,
7086 0 /* we're not using OVERLAPPED_IO */
7087 );
7088 CloseHandle(reparse_point_handle);
7089 Py_END_ALLOW_THREADS
7090
7091 if (io_result==0)
7092 return win32_error_object("readlink", po);
7093
7094 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7095 {
7096 PyErr_SetString(PyExc_ValueError,
7097 "not a symbolic link");
7098 return NULL;
7099 }
7100 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7101 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7102
7103 result = PyUnicode_FromWideChar(print_name,
7104 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7105 return result;
7106}
7107
7108#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7109
7110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007111
Larry Hastings9cf065c2012-06-22 16:30:09 -07007112#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113
7114#if defined(MS_WINDOWS)
7115
7116/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007117static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007118
Larry Hastings9cf065c2012-06-22 16:30:09 -07007119static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007120check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121{
7122 HINSTANCE hKernel32;
7123 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007124 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125 return 1;
7126 hKernel32 = GetModuleHandleW(L"KERNEL32");
7127 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7128 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007129 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130}
7131
Victor Stinner31b3b922013-06-05 01:49:17 +02007132/* Remove the last portion of the path */
7133static void
7134_dirnameW(WCHAR *path)
7135{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007136 WCHAR *ptr;
7137
7138 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007139 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007140 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007141 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007142 }
7143 *ptr = 0;
7144}
7145
Victor Stinner31b3b922013-06-05 01:49:17 +02007146/* Is this path absolute? */
7147static int
7148_is_absW(const WCHAR *path)
7149{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007150 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7151
7152}
7153
Victor Stinner31b3b922013-06-05 01:49:17 +02007154/* join root and rest with a backslash */
7155static void
7156_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7157{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007158 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007159
Victor Stinner31b3b922013-06-05 01:49:17 +02007160 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007161 wcscpy(dest_path, rest);
7162 return;
7163 }
7164
7165 root_len = wcslen(root);
7166
7167 wcscpy(dest_path, root);
7168 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007169 dest_path[root_len] = L'\\';
7170 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007171 }
7172 wcscpy(dest_path+root_len, rest);
7173}
7174
Victor Stinner31b3b922013-06-05 01:49:17 +02007175/* Return True if the path at src relative to dest is a directory */
7176static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007177_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007178{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007179 WIN32_FILE_ATTRIBUTE_DATA src_info;
7180 WCHAR dest_parent[MAX_PATH];
7181 WCHAR src_resolved[MAX_PATH] = L"";
7182
7183 /* dest_parent = os.path.dirname(dest) */
7184 wcscpy(dest_parent, dest);
7185 _dirnameW(dest_parent);
7186 /* src_resolved = os.path.join(dest_parent, src) */
7187 _joinW(src_resolved, dest_parent, src);
7188 return (
7189 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7190 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7191 );
7192}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007193#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007194
Larry Hastings2f936352014-08-05 14:04:04 +10007195
7196/*[clinic input]
7197os.symlink
7198 src: path_t
7199 dst: path_t
7200 target_is_directory: bool = False
7201 *
7202 dir_fd: dir_fd(requires='symlinkat')=None
7203
7204# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7205
7206Create a symbolic link pointing to src named dst.
7207
7208target_is_directory is required on Windows if the target is to be
7209 interpreted as a directory. (On Windows, symlink requires
7210 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7211 target_is_directory is ignored on non-Windows platforms.
7212
7213If dir_fd is not None, it should be a file descriptor open to a directory,
7214 and path should be relative; path will then be relative to that directory.
7215dir_fd may not be implemented on your platform.
7216 If it is unavailable, using it will raise a NotImplementedError.
7217
7218[clinic start generated code]*/
7219
Larry Hastings2f936352014-08-05 14:04:04 +10007220static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007221os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007222 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007223/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007224{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007225#ifdef MS_WINDOWS
7226 DWORD result;
7227#else
7228 int result;
7229#endif
7230
Larry Hastings9cf065c2012-06-22 16:30:09 -07007231#ifdef MS_WINDOWS
7232 if (!check_CreateSymbolicLink()) {
7233 PyErr_SetString(PyExc_NotImplementedError,
7234 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007235 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007236 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007237 if (!win32_can_symlink) {
7238 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007239 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007240 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007241#endif
7242
Larry Hastings2f936352014-08-05 14:04:04 +10007243 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007244 PyErr_SetString(PyExc_ValueError,
7245 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007246 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007247 }
7248
7249#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007250
Larry Hastings9cf065c2012-06-22 16:30:09 -07007251 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007252 /* if src is a directory, ensure target_is_directory==1 */
7253 target_is_directory |= _check_dirW(src->wide, dst->wide);
7254 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7255 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007256 Py_END_ALLOW_THREADS
7257
Larry Hastings2f936352014-08-05 14:04:04 +10007258 if (!result)
7259 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007260
7261#else
7262
7263 Py_BEGIN_ALLOW_THREADS
7264#if HAVE_SYMLINKAT
7265 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007266 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007267 else
7268#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007269 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007270 Py_END_ALLOW_THREADS
7271
Larry Hastings2f936352014-08-05 14:04:04 +10007272 if (result)
7273 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007274#endif
7275
Larry Hastings2f936352014-08-05 14:04:04 +10007276 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007277}
7278#endif /* HAVE_SYMLINK */
7279
Larry Hastings9cf065c2012-06-22 16:30:09 -07007280
Brian Curtind40e6f72010-07-08 21:39:08 +00007281
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007282
Larry Hastings605a62d2012-06-24 04:33:36 -07007283static PyStructSequence_Field times_result_fields[] = {
7284 {"user", "user time"},
7285 {"system", "system time"},
7286 {"children_user", "user time of children"},
7287 {"children_system", "system time of children"},
7288 {"elapsed", "elapsed time since an arbitrary point in the past"},
7289 {NULL}
7290};
7291
7292PyDoc_STRVAR(times_result__doc__,
7293"times_result: Result from os.times().\n\n\
7294This object may be accessed either as a tuple of\n\
7295 (user, system, children_user, children_system, elapsed),\n\
7296or via the attributes user, system, children_user, children_system,\n\
7297and elapsed.\n\
7298\n\
7299See os.times for more information.");
7300
7301static PyStructSequence_Desc times_result_desc = {
7302 "times_result", /* name */
7303 times_result__doc__, /* doc */
7304 times_result_fields,
7305 5
7306};
7307
7308static PyTypeObject TimesResultType;
7309
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007310#ifdef MS_WINDOWS
7311#define HAVE_TIMES /* mandatory, for the method table */
7312#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007313
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007314#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007315
7316static PyObject *
7317build_times_result(double user, double system,
7318 double children_user, double children_system,
7319 double elapsed)
7320{
7321 PyObject *value = PyStructSequence_New(&TimesResultType);
7322 if (value == NULL)
7323 return NULL;
7324
7325#define SET(i, field) \
7326 { \
7327 PyObject *o = PyFloat_FromDouble(field); \
7328 if (!o) { \
7329 Py_DECREF(value); \
7330 return NULL; \
7331 } \
7332 PyStructSequence_SET_ITEM(value, i, o); \
7333 } \
7334
7335 SET(0, user);
7336 SET(1, system);
7337 SET(2, children_user);
7338 SET(3, children_system);
7339 SET(4, elapsed);
7340
7341#undef SET
7342
7343 return value;
7344}
7345
Larry Hastings605a62d2012-06-24 04:33:36 -07007346
Larry Hastings2f936352014-08-05 14:04:04 +10007347#ifndef MS_WINDOWS
7348#define NEED_TICKS_PER_SECOND
7349static long ticks_per_second = -1;
7350#endif /* MS_WINDOWS */
7351
7352/*[clinic input]
7353os.times
7354
7355Return a collection containing process timing information.
7356
7357The object returned behaves like a named tuple with these fields:
7358 (utime, stime, cutime, cstime, elapsed_time)
7359All fields are floating point numbers.
7360[clinic start generated code]*/
7361
Larry Hastings2f936352014-08-05 14:04:04 +10007362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007363os_times_impl(PyObject *module)
7364/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007365#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007366{
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 FILETIME create, exit, kernel, user;
7368 HANDLE hProc;
7369 hProc = GetCurrentProcess();
7370 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7371 /* The fields of a FILETIME structure are the hi and lo part
7372 of a 64-bit value expressed in 100 nanosecond units.
7373 1e7 is one second in such units; 1e-7 the inverse.
7374 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7375 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007376 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007377 (double)(user.dwHighDateTime*429.4967296 +
7378 user.dwLowDateTime*1e-7),
7379 (double)(kernel.dwHighDateTime*429.4967296 +
7380 kernel.dwLowDateTime*1e-7),
7381 (double)0,
7382 (double)0,
7383 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007384}
Larry Hastings2f936352014-08-05 14:04:04 +10007385#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007386{
Larry Hastings2f936352014-08-05 14:04:04 +10007387
7388
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007389 struct tms t;
7390 clock_t c;
7391 errno = 0;
7392 c = times(&t);
7393 if (c == (clock_t) -1)
7394 return posix_error();
7395 return build_times_result(
7396 (double)t.tms_utime / ticks_per_second,
7397 (double)t.tms_stime / ticks_per_second,
7398 (double)t.tms_cutime / ticks_per_second,
7399 (double)t.tms_cstime / ticks_per_second,
7400 (double)c / ticks_per_second);
7401}
Larry Hastings2f936352014-08-05 14:04:04 +10007402#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007403#endif /* HAVE_TIMES */
7404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007405
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007406#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007407/*[clinic input]
7408os.getsid
7409
7410 pid: pid_t
7411 /
7412
7413Call the system call getsid(pid) and return the result.
7414[clinic start generated code]*/
7415
Larry Hastings2f936352014-08-05 14:04:04 +10007416static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007417os_getsid_impl(PyObject *module, pid_t pid)
7418/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007419{
Victor Stinner8c62be82010-05-06 00:08:46 +00007420 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007421 sid = getsid(pid);
7422 if (sid < 0)
7423 return posix_error();
7424 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007425}
7426#endif /* HAVE_GETSID */
7427
7428
Guido van Rossumb6775db1994-08-01 11:34:53 +00007429#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007430/*[clinic input]
7431os.setsid
7432
7433Call the system call setsid().
7434[clinic start generated code]*/
7435
Larry Hastings2f936352014-08-05 14:04:04 +10007436static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007437os_setsid_impl(PyObject *module)
7438/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007439{
Victor Stinner8c62be82010-05-06 00:08:46 +00007440 if (setsid() < 0)
7441 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007442 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007443}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007444#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007445
Larry Hastings2f936352014-08-05 14:04:04 +10007446
Guido van Rossumb6775db1994-08-01 11:34:53 +00007447#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007448/*[clinic input]
7449os.setpgid
7450
7451 pid: pid_t
7452 pgrp: pid_t
7453 /
7454
7455Call the system call setpgid(pid, pgrp).
7456[clinic start generated code]*/
7457
Larry Hastings2f936352014-08-05 14:04:04 +10007458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007459os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7460/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007461{
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 if (setpgid(pid, pgrp) < 0)
7463 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007464 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007465}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007466#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007468
Guido van Rossumb6775db1994-08-01 11:34:53 +00007469#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007470/*[clinic input]
7471os.tcgetpgrp
7472
7473 fd: int
7474 /
7475
7476Return the process group associated with the terminal specified by fd.
7477[clinic start generated code]*/
7478
Larry Hastings2f936352014-08-05 14:04:04 +10007479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007480os_tcgetpgrp_impl(PyObject *module, int fd)
7481/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007482{
7483 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007484 if (pgid < 0)
7485 return posix_error();
7486 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007487}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007488#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007490
Guido van Rossumb6775db1994-08-01 11:34:53 +00007491#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007492/*[clinic input]
7493os.tcsetpgrp
7494
7495 fd: int
7496 pgid: pid_t
7497 /
7498
7499Set the process group associated with the terminal specified by fd.
7500[clinic start generated code]*/
7501
Larry Hastings2f936352014-08-05 14:04:04 +10007502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007503os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7504/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007505{
Victor Stinner8c62be82010-05-06 00:08:46 +00007506 if (tcsetpgrp(fd, pgid) < 0)
7507 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007508 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007509}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007510#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007511
Guido van Rossum687dd131993-05-17 08:34:16 +00007512/* Functions acting on file descriptors */
7513
Victor Stinnerdaf45552013-08-28 00:53:59 +02007514#ifdef O_CLOEXEC
7515extern int _Py_open_cloexec_works;
7516#endif
7517
Larry Hastings2f936352014-08-05 14:04:04 +10007518
7519/*[clinic input]
7520os.open -> int
7521 path: path_t
7522 flags: int
7523 mode: int = 0o777
7524 *
7525 dir_fd: dir_fd(requires='openat') = None
7526
7527# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7528
7529Open a file for low level IO. Returns a file descriptor (integer).
7530
7531If dir_fd is not None, it should be a file descriptor open to a directory,
7532 and path should be relative; path will then be relative to that directory.
7533dir_fd may not be implemented on your platform.
7534 If it is unavailable, using it will raise a NotImplementedError.
7535[clinic start generated code]*/
7536
Larry Hastings2f936352014-08-05 14:04:04 +10007537static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007538os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7539/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007540{
7541 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007542 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007543
Victor Stinnerdaf45552013-08-28 00:53:59 +02007544#ifdef O_CLOEXEC
7545 int *atomic_flag_works = &_Py_open_cloexec_works;
7546#elif !defined(MS_WINDOWS)
7547 int *atomic_flag_works = NULL;
7548#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007549
Victor Stinnerdaf45552013-08-28 00:53:59 +02007550#ifdef MS_WINDOWS
7551 flags |= O_NOINHERIT;
7552#elif defined(O_CLOEXEC)
7553 flags |= O_CLOEXEC;
7554#endif
7555
Steve Dower8fc89802015-04-12 00:26:27 -04007556 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007557 do {
7558 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007559#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007560 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007561#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007562#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007563 if (dir_fd != DEFAULT_DIR_FD)
7564 fd = openat(dir_fd, path->narrow, flags, mode);
7565 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007566#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007567 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007568#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007569 Py_END_ALLOW_THREADS
7570 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007571 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007572
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007573 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007574 if (!async_err)
7575 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007576 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007577 }
7578
Victor Stinnerdaf45552013-08-28 00:53:59 +02007579#ifndef MS_WINDOWS
7580 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7581 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007582 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007583 }
7584#endif
7585
Larry Hastings2f936352014-08-05 14:04:04 +10007586 return fd;
7587}
7588
7589
7590/*[clinic input]
7591os.close
7592
7593 fd: int
7594
7595Close a file descriptor.
7596[clinic start generated code]*/
7597
Barry Warsaw53699e91996-12-10 23:23:01 +00007598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007599os_close_impl(PyObject *module, int fd)
7600/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007601{
Larry Hastings2f936352014-08-05 14:04:04 +10007602 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007603 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7604 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7605 * for more details.
7606 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007607 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007608 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007610 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 Py_END_ALLOW_THREADS
7612 if (res < 0)
7613 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007614 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007615}
7616
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007617
Larry Hastings2f936352014-08-05 14:04:04 +10007618/*[clinic input]
7619os.closerange
7620
7621 fd_low: int
7622 fd_high: int
7623 /
7624
7625Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7626[clinic start generated code]*/
7627
Larry Hastings2f936352014-08-05 14:04:04 +10007628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007629os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7630/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007631{
7632 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007634 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007635 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007636 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007637 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 Py_END_ALLOW_THREADS
7639 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007640}
7641
7642
Larry Hastings2f936352014-08-05 14:04:04 +10007643/*[clinic input]
7644os.dup -> int
7645
7646 fd: int
7647 /
7648
7649Return a duplicate of a file descriptor.
7650[clinic start generated code]*/
7651
Larry Hastings2f936352014-08-05 14:04:04 +10007652static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007653os_dup_impl(PyObject *module, int fd)
7654/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007655{
7656 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007657}
7658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007659
Larry Hastings2f936352014-08-05 14:04:04 +10007660/*[clinic input]
7661os.dup2
7662 fd: int
7663 fd2: int
7664 inheritable: bool=True
7665
7666Duplicate file descriptor.
7667[clinic start generated code]*/
7668
Larry Hastings2f936352014-08-05 14:04:04 +10007669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007670os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7671/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007672{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007673 int res;
7674#if defined(HAVE_DUP3) && \
7675 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7676 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7677 int dup3_works = -1;
7678#endif
7679
Steve Dower940f33a2016-09-08 11:21:54 -07007680 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007681 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007682
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007683 /* dup2() can fail with EINTR if the target FD is already open, because it
7684 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7685 * upon close(), and therefore below.
7686 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007687#ifdef MS_WINDOWS
7688 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007689 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007691 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007692 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 if (res < 0)
7694 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007695
7696 /* Character files like console cannot be make non-inheritable */
7697 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7698 close(fd2);
7699 return NULL;
7700 }
7701
7702#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7703 Py_BEGIN_ALLOW_THREADS
7704 if (!inheritable)
7705 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7706 else
7707 res = dup2(fd, fd2);
7708 Py_END_ALLOW_THREADS
7709 if (res < 0)
7710 return posix_error();
7711
7712#else
7713
7714#ifdef HAVE_DUP3
7715 if (!inheritable && dup3_works != 0) {
7716 Py_BEGIN_ALLOW_THREADS
7717 res = dup3(fd, fd2, O_CLOEXEC);
7718 Py_END_ALLOW_THREADS
7719 if (res < 0) {
7720 if (dup3_works == -1)
7721 dup3_works = (errno != ENOSYS);
7722 if (dup3_works)
7723 return posix_error();
7724 }
7725 }
7726
7727 if (inheritable || dup3_works == 0)
7728 {
7729#endif
7730 Py_BEGIN_ALLOW_THREADS
7731 res = dup2(fd, fd2);
7732 Py_END_ALLOW_THREADS
7733 if (res < 0)
7734 return posix_error();
7735
7736 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7737 close(fd2);
7738 return NULL;
7739 }
7740#ifdef HAVE_DUP3
7741 }
7742#endif
7743
7744#endif
7745
Larry Hastings2f936352014-08-05 14:04:04 +10007746 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007747}
7748
Larry Hastings2f936352014-08-05 14:04:04 +10007749
Ross Lagerwall7807c352011-03-17 20:20:30 +02007750#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007751/*[clinic input]
7752os.lockf
7753
7754 fd: int
7755 An open file descriptor.
7756 command: int
7757 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7758 length: Py_off_t
7759 The number of bytes to lock, starting at the current position.
7760 /
7761
7762Apply, test or remove a POSIX lock on an open file descriptor.
7763
7764[clinic start generated code]*/
7765
Larry Hastings2f936352014-08-05 14:04:04 +10007766static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007767os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7768/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007769{
7770 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007771
7772 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007773 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007774 Py_END_ALLOW_THREADS
7775
7776 if (res < 0)
7777 return posix_error();
7778
7779 Py_RETURN_NONE;
7780}
Larry Hastings2f936352014-08-05 14:04:04 +10007781#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007783
Larry Hastings2f936352014-08-05 14:04:04 +10007784/*[clinic input]
7785os.lseek -> Py_off_t
7786
7787 fd: int
7788 position: Py_off_t
7789 how: int
7790 /
7791
7792Set the position of a file descriptor. Return the new position.
7793
7794Return the new cursor position in number of bytes
7795relative to the beginning of the file.
7796[clinic start generated code]*/
7797
Larry Hastings2f936352014-08-05 14:04:04 +10007798static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007799os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7800/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007801{
7802 Py_off_t result;
7803
Guido van Rossum687dd131993-05-17 08:34:16 +00007804#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7806 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007807 case 0: how = SEEK_SET; break;
7808 case 1: how = SEEK_CUR; break;
7809 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007811#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007812
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007814 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007815
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007817 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007818#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007819 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007820#else
Larry Hastings2f936352014-08-05 14:04:04 +10007821 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007822#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007823 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007825 if (result < 0)
7826 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007827
Larry Hastings2f936352014-08-05 14:04:04 +10007828 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007829}
7830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007831
Larry Hastings2f936352014-08-05 14:04:04 +10007832/*[clinic input]
7833os.read
7834 fd: int
7835 length: Py_ssize_t
7836 /
7837
7838Read from a file descriptor. Returns a bytes object.
7839[clinic start generated code]*/
7840
Larry Hastings2f936352014-08-05 14:04:04 +10007841static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007842os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7843/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007844{
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 Py_ssize_t n;
7846 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007847
7848 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 errno = EINVAL;
7850 return posix_error();
7851 }
Larry Hastings2f936352014-08-05 14:04:04 +10007852
7853#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007854 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007855 if (length > INT_MAX)
7856 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007857#endif
7858
7859 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 if (buffer == NULL)
7861 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007862
Victor Stinner66aab0c2015-03-19 22:53:20 +01007863 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7864 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007866 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 }
Larry Hastings2f936352014-08-05 14:04:04 +10007868
7869 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007871
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007873}
7874
Ross Lagerwall7807c352011-03-17 20:20:30 +02007875#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7876 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007877static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007878iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7879{
7880 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007881 Py_ssize_t blen, total = 0;
7882
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007883 *iov = PyMem_New(struct iovec, cnt);
7884 if (*iov == NULL) {
7885 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007886 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007887 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007888
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007889 *buf = PyMem_New(Py_buffer, cnt);
7890 if (*buf == NULL) {
7891 PyMem_Del(*iov);
7892 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007893 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007894 }
7895
7896 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007897 PyObject *item = PySequence_GetItem(seq, i);
7898 if (item == NULL)
7899 goto fail;
7900 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7901 Py_DECREF(item);
7902 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007903 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007904 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007905 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007906 blen = (*buf)[i].len;
7907 (*iov)[i].iov_len = blen;
7908 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007909 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007910 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007911
7912fail:
7913 PyMem_Del(*iov);
7914 for (j = 0; j < i; j++) {
7915 PyBuffer_Release(&(*buf)[j]);
7916 }
7917 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007918 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007919}
7920
7921static void
7922iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7923{
7924 int i;
7925 PyMem_Del(iov);
7926 for (i = 0; i < cnt; i++) {
7927 PyBuffer_Release(&buf[i]);
7928 }
7929 PyMem_Del(buf);
7930}
7931#endif
7932
Larry Hastings2f936352014-08-05 14:04:04 +10007933
Ross Lagerwall7807c352011-03-17 20:20:30 +02007934#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007935/*[clinic input]
7936os.readv -> Py_ssize_t
7937
7938 fd: int
7939 buffers: object
7940 /
7941
7942Read from a file descriptor fd into an iterable of buffers.
7943
7944The buffers should be mutable buffers accepting bytes.
7945readv will transfer data into each buffer until it is full
7946and then move on to the next buffer in the sequence to hold
7947the rest of the data.
7948
7949readv returns the total number of bytes read,
7950which may be less than the total capacity of all the buffers.
7951[clinic start generated code]*/
7952
Larry Hastings2f936352014-08-05 14:04:04 +10007953static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007954os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7955/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007956{
7957 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007958 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007959 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007960 struct iovec *iov;
7961 Py_buffer *buf;
7962
Larry Hastings2f936352014-08-05 14:04:04 +10007963 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007964 PyErr_SetString(PyExc_TypeError,
7965 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007966 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007967 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007968
Larry Hastings2f936352014-08-05 14:04:04 +10007969 cnt = PySequence_Size(buffers);
7970
7971 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7972 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007973
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007974 do {
7975 Py_BEGIN_ALLOW_THREADS
7976 n = readv(fd, iov, cnt);
7977 Py_END_ALLOW_THREADS
7978 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007979
7980 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007981 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007982 if (!async_err)
7983 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007984 return -1;
7985 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007986
Larry Hastings2f936352014-08-05 14:04:04 +10007987 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007988}
Larry Hastings2f936352014-08-05 14:04:04 +10007989#endif /* HAVE_READV */
7990
Ross Lagerwall7807c352011-03-17 20:20:30 +02007991
7992#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007993/*[clinic input]
7994# TODO length should be size_t! but Python doesn't support parsing size_t yet.
7995os.pread
7996
7997 fd: int
7998 length: int
7999 offset: Py_off_t
8000 /
8001
8002Read a number of bytes from a file descriptor starting at a particular offset.
8003
8004Read length bytes from file descriptor fd, starting at offset bytes from
8005the beginning of the file. The file offset remains unchanged.
8006[clinic start generated code]*/
8007
Larry Hastings2f936352014-08-05 14:04:04 +10008008static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008009os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8010/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008011{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008012 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008013 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008014 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008015
Larry Hastings2f936352014-08-05 14:04:04 +10008016 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008017 errno = EINVAL;
8018 return posix_error();
8019 }
Larry Hastings2f936352014-08-05 14:04:04 +10008020 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008021 if (buffer == NULL)
8022 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008023
8024 do {
8025 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008026 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008027 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008028 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008029 Py_END_ALLOW_THREADS
8030 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8031
Ross Lagerwall7807c352011-03-17 20:20:30 +02008032 if (n < 0) {
8033 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008034 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008035 }
Larry Hastings2f936352014-08-05 14:04:04 +10008036 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008037 _PyBytes_Resize(&buffer, n);
8038 return buffer;
8039}
Larry Hastings2f936352014-08-05 14:04:04 +10008040#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008041
Larry Hastings2f936352014-08-05 14:04:04 +10008042
8043/*[clinic input]
8044os.write -> Py_ssize_t
8045
8046 fd: int
8047 data: Py_buffer
8048 /
8049
8050Write a bytes object to a file descriptor.
8051[clinic start generated code]*/
8052
Larry Hastings2f936352014-08-05 14:04:04 +10008053static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008054os_write_impl(PyObject *module, int fd, Py_buffer *data)
8055/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008056{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008057 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008058}
8059
8060#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008062"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008063sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008065Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066
Larry Hastings2f936352014-08-05 14:04:04 +10008067/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068static PyObject *
8069posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8070{
8071 int in, out;
8072 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008073 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074 off_t offset;
8075
8076#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8077#ifndef __APPLE__
8078 Py_ssize_t len;
8079#endif
8080 PyObject *headers = NULL, *trailers = NULL;
8081 Py_buffer *hbuf, *tbuf;
8082 off_t sbytes;
8083 struct sf_hdtr sf;
8084 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008085 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008086 static char *keywords[] = {"out", "in",
8087 "offset", "count",
8088 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008089
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008090 sf.headers = NULL;
8091 sf.trailers = NULL;
8092
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008093#ifdef __APPLE__
8094 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008095 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008096#else
8097 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008098 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008099#endif
8100 &headers, &trailers, &flags))
8101 return NULL;
8102 if (headers != NULL) {
8103 if (!PySequence_Check(headers)) {
8104 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008105 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106 return NULL;
8107 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008108 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008109 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008110 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008111 (i = iov_setup(&(sf.headers), &hbuf,
8112 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008113 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008114#ifdef __APPLE__
8115 sbytes += i;
8116#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008117 }
8118 }
8119 if (trailers != NULL) {
8120 if (!PySequence_Check(trailers)) {
8121 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008122 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008123 return NULL;
8124 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008125 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008126 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008127 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008128 (i = iov_setup(&(sf.trailers), &tbuf,
8129 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008130 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008131#ifdef __APPLE__
8132 sbytes += i;
8133#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008134 }
8135 }
8136
Steve Dower8fc89802015-04-12 00:26:27 -04008137 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008138 do {
8139 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008140#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008141 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008142#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008143 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008144#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008145 Py_END_ALLOW_THREADS
8146 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008147 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008148
8149 if (sf.headers != NULL)
8150 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8151 if (sf.trailers != NULL)
8152 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8153
8154 if (ret < 0) {
8155 if ((errno == EAGAIN) || (errno == EBUSY)) {
8156 if (sbytes != 0) {
8157 // some data has been sent
8158 goto done;
8159 }
8160 else {
8161 // no data has been sent; upper application is supposed
8162 // to retry on EAGAIN or EBUSY
8163 return posix_error();
8164 }
8165 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008166 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008167 }
8168 goto done;
8169
8170done:
8171 #if !defined(HAVE_LARGEFILE_SUPPORT)
8172 return Py_BuildValue("l", sbytes);
8173 #else
8174 return Py_BuildValue("L", sbytes);
8175 #endif
8176
8177#else
8178 Py_ssize_t count;
8179 PyObject *offobj;
8180 static char *keywords[] = {"out", "in",
8181 "offset", "count", NULL};
8182 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8183 keywords, &out, &in, &offobj, &count))
8184 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008185#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008186 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008187 do {
8188 Py_BEGIN_ALLOW_THREADS
8189 ret = sendfile(out, in, NULL, count);
8190 Py_END_ALLOW_THREADS
8191 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008192 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008193 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008194 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008195 }
8196#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008197 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008198 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008199
8200 do {
8201 Py_BEGIN_ALLOW_THREADS
8202 ret = sendfile(out, in, &offset, count);
8203 Py_END_ALLOW_THREADS
8204 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008205 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008206 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008207 return Py_BuildValue("n", ret);
8208#endif
8209}
Larry Hastings2f936352014-08-05 14:04:04 +10008210#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008211
Larry Hastings2f936352014-08-05 14:04:04 +10008212
8213/*[clinic input]
8214os.fstat
8215
8216 fd : int
8217
8218Perform a stat system call on the given file descriptor.
8219
8220Like stat(), but for an open file descriptor.
8221Equivalent to os.stat(fd).
8222[clinic start generated code]*/
8223
Larry Hastings2f936352014-08-05 14:04:04 +10008224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008225os_fstat_impl(PyObject *module, int fd)
8226/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008227{
Victor Stinner8c62be82010-05-06 00:08:46 +00008228 STRUCT_STAT st;
8229 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008230 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008231
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008232 do {
8233 Py_BEGIN_ALLOW_THREADS
8234 res = FSTAT(fd, &st);
8235 Py_END_ALLOW_THREADS
8236 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008238#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008239 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008240#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008241 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008242#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008243 }
Tim Peters5aa91602002-01-30 05:46:57 +00008244
Victor Stinner4195b5c2012-02-08 23:03:19 +01008245 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008246}
8247
Larry Hastings2f936352014-08-05 14:04:04 +10008248
8249/*[clinic input]
8250os.isatty -> bool
8251 fd: int
8252 /
8253
8254Return True if the fd is connected to a terminal.
8255
8256Return True if the file descriptor is an open file descriptor
8257connected to the slave end of a terminal.
8258[clinic start generated code]*/
8259
Larry Hastings2f936352014-08-05 14:04:04 +10008260static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008261os_isatty_impl(PyObject *module, int fd)
8262/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008263{
Steve Dower8fc89802015-04-12 00:26:27 -04008264 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008265 _Py_BEGIN_SUPPRESS_IPH
8266 return_value = isatty(fd);
8267 _Py_END_SUPPRESS_IPH
8268 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008269}
8270
8271
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008272#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008273/*[clinic input]
8274os.pipe
8275
8276Create a pipe.
8277
8278Returns a tuple of two file descriptors:
8279 (read_fd, write_fd)
8280[clinic start generated code]*/
8281
Larry Hastings2f936352014-08-05 14:04:04 +10008282static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008283os_pipe_impl(PyObject *module)
8284/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008285{
Victor Stinner8c62be82010-05-06 00:08:46 +00008286 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008287#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008288 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008289 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008291#else
8292 int res;
8293#endif
8294
8295#ifdef MS_WINDOWS
8296 attr.nLength = sizeof(attr);
8297 attr.lpSecurityDescriptor = NULL;
8298 attr.bInheritHandle = FALSE;
8299
8300 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008301 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008302 ok = CreatePipe(&read, &write, &attr, 0);
8303 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008304 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8305 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008306 if (fds[0] == -1 || fds[1] == -1) {
8307 CloseHandle(read);
8308 CloseHandle(write);
8309 ok = 0;
8310 }
8311 }
Steve Dowerc3630612016-11-19 18:41:16 -08008312 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008313 Py_END_ALLOW_THREADS
8314
Victor Stinner8c62be82010-05-06 00:08:46 +00008315 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008316 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008317#else
8318
8319#ifdef HAVE_PIPE2
8320 Py_BEGIN_ALLOW_THREADS
8321 res = pipe2(fds, O_CLOEXEC);
8322 Py_END_ALLOW_THREADS
8323
8324 if (res != 0 && errno == ENOSYS)
8325 {
8326#endif
8327 Py_BEGIN_ALLOW_THREADS
8328 res = pipe(fds);
8329 Py_END_ALLOW_THREADS
8330
8331 if (res == 0) {
8332 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8333 close(fds[0]);
8334 close(fds[1]);
8335 return NULL;
8336 }
8337 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8338 close(fds[0]);
8339 close(fds[1]);
8340 return NULL;
8341 }
8342 }
8343#ifdef HAVE_PIPE2
8344 }
8345#endif
8346
8347 if (res != 0)
8348 return PyErr_SetFromErrno(PyExc_OSError);
8349#endif /* !MS_WINDOWS */
8350 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008351}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008352#endif /* HAVE_PIPE */
8353
Larry Hastings2f936352014-08-05 14:04:04 +10008354
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008355#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008356/*[clinic input]
8357os.pipe2
8358
8359 flags: int
8360 /
8361
8362Create a pipe with flags set atomically.
8363
8364Returns a tuple of two file descriptors:
8365 (read_fd, write_fd)
8366
8367flags can be constructed by ORing together one or more of these values:
8368O_NONBLOCK, O_CLOEXEC.
8369[clinic start generated code]*/
8370
Larry Hastings2f936352014-08-05 14:04:04 +10008371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008372os_pipe2_impl(PyObject *module, int flags)
8373/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008374{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008375 int fds[2];
8376 int res;
8377
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008378 res = pipe2(fds, flags);
8379 if (res != 0)
8380 return posix_error();
8381 return Py_BuildValue("(ii)", fds[0], fds[1]);
8382}
8383#endif /* HAVE_PIPE2 */
8384
Larry Hastings2f936352014-08-05 14:04:04 +10008385
Ross Lagerwall7807c352011-03-17 20:20:30 +02008386#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008387/*[clinic input]
8388os.writev -> Py_ssize_t
8389 fd: int
8390 buffers: object
8391 /
8392
8393Iterate over buffers, and write the contents of each to a file descriptor.
8394
8395Returns the total number of bytes written.
8396buffers must be a sequence of bytes-like objects.
8397[clinic start generated code]*/
8398
Larry Hastings2f936352014-08-05 14:04:04 +10008399static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008400os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8401/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008402{
8403 int cnt;
8404 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008405 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008406 struct iovec *iov;
8407 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008408
8409 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008410 PyErr_SetString(PyExc_TypeError,
8411 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008412 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008413 }
Larry Hastings2f936352014-08-05 14:04:04 +10008414 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008415
Larry Hastings2f936352014-08-05 14:04:04 +10008416 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8417 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008418 }
8419
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008420 do {
8421 Py_BEGIN_ALLOW_THREADS
8422 result = writev(fd, iov, cnt);
8423 Py_END_ALLOW_THREADS
8424 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008425
8426 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008427 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008428 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008429
Georg Brandl306336b2012-06-24 12:55:33 +02008430 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008431}
Larry Hastings2f936352014-08-05 14:04:04 +10008432#endif /* HAVE_WRITEV */
8433
8434
8435#ifdef HAVE_PWRITE
8436/*[clinic input]
8437os.pwrite -> Py_ssize_t
8438
8439 fd: int
8440 buffer: Py_buffer
8441 offset: Py_off_t
8442 /
8443
8444Write bytes to a file descriptor starting at a particular offset.
8445
8446Write buffer to fd, starting at offset bytes from the beginning of
8447the file. Returns the number of bytes writte. Does not change the
8448current file offset.
8449[clinic start generated code]*/
8450
Larry Hastings2f936352014-08-05 14:04:04 +10008451static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008452os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8453/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008454{
8455 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008456 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008457
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008458 do {
8459 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008460 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008461 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008462 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008463 Py_END_ALLOW_THREADS
8464 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008465
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008466 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008467 posix_error();
8468 return size;
8469}
8470#endif /* HAVE_PWRITE */
8471
8472
8473#ifdef HAVE_MKFIFO
8474/*[clinic input]
8475os.mkfifo
8476
8477 path: path_t
8478 mode: int=0o666
8479 *
8480 dir_fd: dir_fd(requires='mkfifoat')=None
8481
8482Create a "fifo" (a POSIX named pipe).
8483
8484If dir_fd is not None, it should be a file descriptor open to a directory,
8485 and path should be relative; path will then be relative to that directory.
8486dir_fd may not be implemented on your platform.
8487 If it is unavailable, using it will raise a NotImplementedError.
8488[clinic start generated code]*/
8489
Larry Hastings2f936352014-08-05 14:04:04 +10008490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008491os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8492/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008493{
8494 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008495 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008496
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008497 do {
8498 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008499#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008500 if (dir_fd != DEFAULT_DIR_FD)
8501 result = mkfifoat(dir_fd, path->narrow, mode);
8502 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008503#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008504 result = mkfifo(path->narrow, mode);
8505 Py_END_ALLOW_THREADS
8506 } while (result != 0 && errno == EINTR &&
8507 !(async_err = PyErr_CheckSignals()));
8508 if (result != 0)
8509 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008510
8511 Py_RETURN_NONE;
8512}
8513#endif /* HAVE_MKFIFO */
8514
8515
8516#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8517/*[clinic input]
8518os.mknod
8519
8520 path: path_t
8521 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008522 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008523 *
8524 dir_fd: dir_fd(requires='mknodat')=None
8525
8526Create a node in the file system.
8527
8528Create a node in the file system (file, device special file or named pipe)
8529at path. mode specifies both the permissions to use and the
8530type of node to be created, being combined (bitwise OR) with one of
8531S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8532device defines the newly created device special file (probably using
8533os.makedev()). Otherwise device is ignored.
8534
8535If dir_fd is not None, it should be a file descriptor open to a directory,
8536 and path should be relative; path will then be relative to that directory.
8537dir_fd may not be implemented on your platform.
8538 If it is unavailable, using it will raise a NotImplementedError.
8539[clinic start generated code]*/
8540
Larry Hastings2f936352014-08-05 14:04:04 +10008541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008542os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008543 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008544/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008545{
8546 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008547 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008548
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008549 do {
8550 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008551#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008552 if (dir_fd != DEFAULT_DIR_FD)
8553 result = mknodat(dir_fd, path->narrow, mode, device);
8554 else
Larry Hastings2f936352014-08-05 14:04:04 +10008555#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008556 result = mknod(path->narrow, mode, device);
8557 Py_END_ALLOW_THREADS
8558 } while (result != 0 && errno == EINTR &&
8559 !(async_err = PyErr_CheckSignals()));
8560 if (result != 0)
8561 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008562
8563 Py_RETURN_NONE;
8564}
8565#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8566
8567
8568#ifdef HAVE_DEVICE_MACROS
8569/*[clinic input]
8570os.major -> unsigned_int
8571
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008572 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008573 /
8574
8575Extracts a device major number from a raw device number.
8576[clinic start generated code]*/
8577
Larry Hastings2f936352014-08-05 14:04:04 +10008578static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008579os_major_impl(PyObject *module, dev_t device)
8580/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008581{
8582 return major(device);
8583}
8584
8585
8586/*[clinic input]
8587os.minor -> unsigned_int
8588
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008589 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008590 /
8591
8592Extracts a device minor number from a raw device number.
8593[clinic start generated code]*/
8594
Larry Hastings2f936352014-08-05 14:04:04 +10008595static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008596os_minor_impl(PyObject *module, dev_t device)
8597/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008598{
8599 return minor(device);
8600}
8601
8602
8603/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008604os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008605
8606 major: int
8607 minor: int
8608 /
8609
8610Composes a raw device number from the major and minor device numbers.
8611[clinic start generated code]*/
8612
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008613static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008614os_makedev_impl(PyObject *module, int major, int minor)
8615/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008616{
8617 return makedev(major, minor);
8618}
8619#endif /* HAVE_DEVICE_MACROS */
8620
8621
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008622#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008623/*[clinic input]
8624os.ftruncate
8625
8626 fd: int
8627 length: Py_off_t
8628 /
8629
8630Truncate a file, specified by file descriptor, to a specific length.
8631[clinic start generated code]*/
8632
Larry Hastings2f936352014-08-05 14:04:04 +10008633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008634os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8635/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008636{
8637 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008638 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008639
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 do {
8641 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008642 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008643#ifdef MS_WINDOWS
8644 result = _chsize_s(fd, length);
8645#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008646 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008647#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008648 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008649 Py_END_ALLOW_THREADS
8650 } while (result != 0 && errno == EINTR &&
8651 !(async_err = PyErr_CheckSignals()));
8652 if (result != 0)
8653 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008654 Py_RETURN_NONE;
8655}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008656#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008657
8658
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008659#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008660/*[clinic input]
8661os.truncate
8662 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8663 length: Py_off_t
8664
8665Truncate a file, specified by path, to a specific length.
8666
8667On some platforms, path may also be specified as an open file descriptor.
8668 If this functionality is unavailable, using it raises an exception.
8669[clinic start generated code]*/
8670
Larry Hastings2f936352014-08-05 14:04:04 +10008671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008672os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8673/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008674{
8675 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008676#ifdef MS_WINDOWS
8677 int fd;
8678#endif
8679
8680 if (path->fd != -1)
8681 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008682
8683 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008684 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008685#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008686 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008687 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008688 result = -1;
8689 else {
8690 result = _chsize_s(fd, length);
8691 close(fd);
8692 if (result < 0)
8693 errno = result;
8694 }
8695#else
8696 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008697#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008698 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008699 Py_END_ALLOW_THREADS
8700 if (result < 0)
8701 return path_error(path);
8702
8703 Py_RETURN_NONE;
8704}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008705#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008706
Ross Lagerwall7807c352011-03-17 20:20:30 +02008707
Victor Stinnerd6b17692014-09-30 12:20:05 +02008708/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8709 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8710 defined, which is the case in Python on AIX. AIX bug report:
8711 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8712#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8713# define POSIX_FADVISE_AIX_BUG
8714#endif
8715
Victor Stinnerec39e262014-09-30 12:35:58 +02008716
Victor Stinnerd6b17692014-09-30 12:20:05 +02008717#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008718/*[clinic input]
8719os.posix_fallocate
8720
8721 fd: int
8722 offset: Py_off_t
8723 length: Py_off_t
8724 /
8725
8726Ensure a file has allocated at least a particular number of bytes on disk.
8727
8728Ensure that the file specified by fd encompasses a range of bytes
8729starting at offset bytes from the beginning and continuing for length bytes.
8730[clinic start generated code]*/
8731
Larry Hastings2f936352014-08-05 14:04:04 +10008732static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008733os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008734 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008735/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008736{
8737 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008738 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008739
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008740 do {
8741 Py_BEGIN_ALLOW_THREADS
8742 result = posix_fallocate(fd, offset, length);
8743 Py_END_ALLOW_THREADS
8744 } while (result != 0 && errno == EINTR &&
8745 !(async_err = PyErr_CheckSignals()));
8746 if (result != 0)
8747 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008748 Py_RETURN_NONE;
8749}
Victor Stinnerec39e262014-09-30 12:35:58 +02008750#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008751
Ross Lagerwall7807c352011-03-17 20:20:30 +02008752
Victor Stinnerd6b17692014-09-30 12:20:05 +02008753#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008754/*[clinic input]
8755os.posix_fadvise
8756
8757 fd: int
8758 offset: Py_off_t
8759 length: Py_off_t
8760 advice: int
8761 /
8762
8763Announce an intention to access data in a specific pattern.
8764
8765Announce an intention to access data in a specific pattern, thus allowing
8766the kernel to make optimizations.
8767The advice applies to the region of the file specified by fd starting at
8768offset and continuing for length bytes.
8769advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8770POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8771POSIX_FADV_DONTNEED.
8772[clinic start generated code]*/
8773
Larry Hastings2f936352014-08-05 14:04:04 +10008774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008775os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008776 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008777/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008778{
8779 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008780 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008781
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008782 do {
8783 Py_BEGIN_ALLOW_THREADS
8784 result = posix_fadvise(fd, offset, length, advice);
8785 Py_END_ALLOW_THREADS
8786 } while (result != 0 && errno == EINTR &&
8787 !(async_err = PyErr_CheckSignals()));
8788 if (result != 0)
8789 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008790 Py_RETURN_NONE;
8791}
Victor Stinnerec39e262014-09-30 12:35:58 +02008792#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008793
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008794#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008795
Fred Drake762e2061999-08-26 17:23:54 +00008796/* Save putenv() parameters as values here, so we can collect them when they
8797 * get re-set with another call for the same key. */
8798static PyObject *posix_putenv_garbage;
8799
Larry Hastings2f936352014-08-05 14:04:04 +10008800static void
8801posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008802{
Larry Hastings2f936352014-08-05 14:04:04 +10008803 /* Install the first arg and newstr in posix_putenv_garbage;
8804 * this will cause previous value to be collected. This has to
8805 * happen after the real putenv() call because the old value
8806 * was still accessible until then. */
8807 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8808 /* really not much we can do; just leak */
8809 PyErr_Clear();
8810 else
8811 Py_DECREF(value);
8812}
8813
8814
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008815#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008816/*[clinic input]
8817os.putenv
8818
8819 name: unicode
8820 value: unicode
8821 /
8822
8823Change or add an environment variable.
8824[clinic start generated code]*/
8825
Larry Hastings2f936352014-08-05 14:04:04 +10008826static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008827os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8828/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008829{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008830 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008831
8832 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8833 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008834 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008835 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008836 }
Larry Hastings2f936352014-08-05 14:04:04 +10008837 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008838 PyErr_Format(PyExc_ValueError,
8839 "the environment variable is longer than %u characters",
8840 _MAX_ENV);
8841 goto error;
8842 }
8843
Larry Hastings2f936352014-08-05 14:04:04 +10008844 env = PyUnicode_AsUnicode(unicode);
8845 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008846 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008847 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008849 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008851
Larry Hastings2f936352014-08-05 14:04:04 +10008852 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008853 Py_RETURN_NONE;
8854
8855error:
Larry Hastings2f936352014-08-05 14:04:04 +10008856 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008857 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008858}
Larry Hastings2f936352014-08-05 14:04:04 +10008859#else /* MS_WINDOWS */
8860/*[clinic input]
8861os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008862
Larry Hastings2f936352014-08-05 14:04:04 +10008863 name: FSConverter
8864 value: FSConverter
8865 /
8866
8867Change or add an environment variable.
8868[clinic start generated code]*/
8869
Larry Hastings2f936352014-08-05 14:04:04 +10008870static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008871os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8872/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008873{
8874 PyObject *bytes = NULL;
8875 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008876 const char *name_string = PyBytes_AsString(name);
8877 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008878
8879 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8880 if (bytes == NULL) {
8881 PyErr_NoMemory();
8882 return NULL;
8883 }
8884
8885 env = PyBytes_AS_STRING(bytes);
8886 if (putenv(env)) {
8887 Py_DECREF(bytes);
8888 return posix_error();
8889 }
8890
8891 posix_putenv_garbage_setitem(name, bytes);
8892 Py_RETURN_NONE;
8893}
8894#endif /* MS_WINDOWS */
8895#endif /* HAVE_PUTENV */
8896
8897
8898#ifdef HAVE_UNSETENV
8899/*[clinic input]
8900os.unsetenv
8901 name: FSConverter
8902 /
8903
8904Delete an environment variable.
8905[clinic start generated code]*/
8906
Larry Hastings2f936352014-08-05 14:04:04 +10008907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008908os_unsetenv_impl(PyObject *module, PyObject *name)
8909/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008910{
Victor Stinner984890f2011-11-24 13:53:38 +01008911#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008912 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008913#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008914
Victor Stinner984890f2011-11-24 13:53:38 +01008915#ifdef HAVE_BROKEN_UNSETENV
8916 unsetenv(PyBytes_AS_STRING(name));
8917#else
Victor Stinner65170952011-11-22 22:16:17 +01008918 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008919 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008920 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008921#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008922
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 /* Remove the key from posix_putenv_garbage;
8924 * this will cause it to be collected. This has to
8925 * happen after the real unsetenv() call because the
8926 * old value was still accessible until then.
8927 */
Victor Stinner65170952011-11-22 22:16:17 +01008928 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 /* really not much we can do; just leak */
8930 PyErr_Clear();
8931 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008932 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008933}
Larry Hastings2f936352014-08-05 14:04:04 +10008934#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008935
Larry Hastings2f936352014-08-05 14:04:04 +10008936
8937/*[clinic input]
8938os.strerror
8939
8940 code: int
8941 /
8942
8943Translate an error code to a message string.
8944[clinic start generated code]*/
8945
Larry Hastings2f936352014-08-05 14:04:04 +10008946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008947os_strerror_impl(PyObject *module, int code)
8948/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008949{
8950 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 if (message == NULL) {
8952 PyErr_SetString(PyExc_ValueError,
8953 "strerror() argument out of range");
8954 return NULL;
8955 }
Victor Stinner1b579672011-12-17 05:47:23 +01008956 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008957}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008958
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008959
Guido van Rossumc9641791998-08-04 15:26:23 +00008960#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008961#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008962/*[clinic input]
8963os.WCOREDUMP -> bool
8964
8965 status: int
8966 /
8967
8968Return True if the process returning status was dumped to a core file.
8969[clinic start generated code]*/
8970
Larry Hastings2f936352014-08-05 14:04:04 +10008971static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008972os_WCOREDUMP_impl(PyObject *module, int status)
8973/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008974{
8975 WAIT_TYPE wait_status;
8976 WAIT_STATUS_INT(wait_status) = status;
8977 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008978}
8979#endif /* WCOREDUMP */
8980
Larry Hastings2f936352014-08-05 14:04:04 +10008981
Fred Drake106c1a02002-04-23 15:58:02 +00008982#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008983/*[clinic input]
8984os.WIFCONTINUED -> bool
8985
8986 status: int
8987
8988Return True if a particular process was continued from a job control stop.
8989
8990Return True if the process returning status was continued from a
8991job control stop.
8992[clinic start generated code]*/
8993
Larry Hastings2f936352014-08-05 14:04:04 +10008994static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008995os_WIFCONTINUED_impl(PyObject *module, int status)
8996/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008997{
8998 WAIT_TYPE wait_status;
8999 WAIT_STATUS_INT(wait_status) = status;
9000 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009001}
9002#endif /* WIFCONTINUED */
9003
Larry Hastings2f936352014-08-05 14:04:04 +10009004
Guido van Rossumc9641791998-08-04 15:26:23 +00009005#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009006/*[clinic input]
9007os.WIFSTOPPED -> bool
9008
9009 status: int
9010
9011Return True if the process returning status was stopped.
9012[clinic start generated code]*/
9013
Larry Hastings2f936352014-08-05 14:04:04 +10009014static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009015os_WIFSTOPPED_impl(PyObject *module, int status)
9016/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009017{
9018 WAIT_TYPE wait_status;
9019 WAIT_STATUS_INT(wait_status) = status;
9020 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009021}
9022#endif /* WIFSTOPPED */
9023
Larry Hastings2f936352014-08-05 14:04:04 +10009024
Guido van Rossumc9641791998-08-04 15:26:23 +00009025#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009026/*[clinic input]
9027os.WIFSIGNALED -> bool
9028
9029 status: int
9030
9031Return True if the process returning status was terminated by a signal.
9032[clinic start generated code]*/
9033
Larry Hastings2f936352014-08-05 14:04:04 +10009034static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009035os_WIFSIGNALED_impl(PyObject *module, int status)
9036/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009037{
9038 WAIT_TYPE wait_status;
9039 WAIT_STATUS_INT(wait_status) = status;
9040 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009041}
9042#endif /* WIFSIGNALED */
9043
Larry Hastings2f936352014-08-05 14:04:04 +10009044
Guido van Rossumc9641791998-08-04 15:26:23 +00009045#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009046/*[clinic input]
9047os.WIFEXITED -> bool
9048
9049 status: int
9050
9051Return True if the process returning status exited via the exit() system call.
9052[clinic start generated code]*/
9053
Larry Hastings2f936352014-08-05 14:04:04 +10009054static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009055os_WIFEXITED_impl(PyObject *module, int status)
9056/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009057{
9058 WAIT_TYPE wait_status;
9059 WAIT_STATUS_INT(wait_status) = status;
9060 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009061}
9062#endif /* WIFEXITED */
9063
Larry Hastings2f936352014-08-05 14:04:04 +10009064
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009065#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009066/*[clinic input]
9067os.WEXITSTATUS -> int
9068
9069 status: int
9070
9071Return the process return code from status.
9072[clinic start generated code]*/
9073
Larry Hastings2f936352014-08-05 14:04:04 +10009074static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009075os_WEXITSTATUS_impl(PyObject *module, int status)
9076/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009077{
9078 WAIT_TYPE wait_status;
9079 WAIT_STATUS_INT(wait_status) = status;
9080 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009081}
9082#endif /* WEXITSTATUS */
9083
Larry Hastings2f936352014-08-05 14:04:04 +10009084
Guido van Rossumc9641791998-08-04 15:26:23 +00009085#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009086/*[clinic input]
9087os.WTERMSIG -> int
9088
9089 status: int
9090
9091Return the signal that terminated the process that provided the status value.
9092[clinic start generated code]*/
9093
Larry Hastings2f936352014-08-05 14:04:04 +10009094static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009095os_WTERMSIG_impl(PyObject *module, int status)
9096/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009097{
9098 WAIT_TYPE wait_status;
9099 WAIT_STATUS_INT(wait_status) = status;
9100 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009101}
9102#endif /* WTERMSIG */
9103
Larry Hastings2f936352014-08-05 14:04:04 +10009104
Guido van Rossumc9641791998-08-04 15:26:23 +00009105#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009106/*[clinic input]
9107os.WSTOPSIG -> int
9108
9109 status: int
9110
9111Return the signal that stopped the process that provided the status value.
9112[clinic start generated code]*/
9113
Larry Hastings2f936352014-08-05 14:04:04 +10009114static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009115os_WSTOPSIG_impl(PyObject *module, int status)
9116/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009117{
9118 WAIT_TYPE wait_status;
9119 WAIT_STATUS_INT(wait_status) = status;
9120 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009121}
9122#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009123#endif /* HAVE_SYS_WAIT_H */
9124
9125
Thomas Wouters477c8d52006-05-27 19:21:47 +00009126#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009127#ifdef _SCO_DS
9128/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9129 needed definitions in sys/statvfs.h */
9130#define _SVID3
9131#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009132#include <sys/statvfs.h>
9133
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009134static PyObject*
9135_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9137 if (v == NULL)
9138 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009139
9140#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9142 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9143 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9144 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9145 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9146 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9147 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9148 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9149 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9150 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009151#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9153 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9154 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009155 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009157 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009159 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009161 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009163 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009165 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9167 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009168#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009169 if (PyErr_Occurred()) {
9170 Py_DECREF(v);
9171 return NULL;
9172 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009173
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009175}
9176
Larry Hastings2f936352014-08-05 14:04:04 +10009177
9178/*[clinic input]
9179os.fstatvfs
9180 fd: int
9181 /
9182
9183Perform an fstatvfs system call on the given fd.
9184
9185Equivalent to statvfs(fd).
9186[clinic start generated code]*/
9187
Larry Hastings2f936352014-08-05 14:04:04 +10009188static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009189os_fstatvfs_impl(PyObject *module, int fd)
9190/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009191{
9192 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009193 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009195
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009196 do {
9197 Py_BEGIN_ALLOW_THREADS
9198 result = fstatvfs(fd, &st);
9199 Py_END_ALLOW_THREADS
9200 } while (result != 0 && errno == EINTR &&
9201 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009202 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009203 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009204
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009206}
Larry Hastings2f936352014-08-05 14:04:04 +10009207#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009208
9209
Thomas Wouters477c8d52006-05-27 19:21:47 +00009210#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009211#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009212/*[clinic input]
9213os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009214
Larry Hastings2f936352014-08-05 14:04:04 +10009215 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9216
9217Perform a statvfs system call on the given path.
9218
9219path may always be specified as a string.
9220On some platforms, path may also be specified as an open file descriptor.
9221 If this functionality is unavailable, using it raises an exception.
9222[clinic start generated code]*/
9223
Larry Hastings2f936352014-08-05 14:04:04 +10009224static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009225os_statvfs_impl(PyObject *module, path_t *path)
9226/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009227{
9228 int result;
9229 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009230
9231 Py_BEGIN_ALLOW_THREADS
9232#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009233 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009234#ifdef __APPLE__
9235 /* handle weak-linking on Mac OS X 10.3 */
9236 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009237 fd_specified("statvfs", path->fd);
9238 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009239 }
9240#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009241 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009242 }
9243 else
9244#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009245 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009246 Py_END_ALLOW_THREADS
9247
9248 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009249 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009250 }
9251
Larry Hastings2f936352014-08-05 14:04:04 +10009252 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009253}
Larry Hastings2f936352014-08-05 14:04:04 +10009254#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9255
Guido van Rossum94f6f721999-01-06 18:42:14 +00009256
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009257#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009258/*[clinic input]
9259os._getdiskusage
9260
9261 path: Py_UNICODE
9262
9263Return disk usage statistics about the given path as a (total, free) tuple.
9264[clinic start generated code]*/
9265
Larry Hastings2f936352014-08-05 14:04:04 +10009266static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009267os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9268/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009269{
9270 BOOL retval;
9271 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009272
9273 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009274 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009275 Py_END_ALLOW_THREADS
9276 if (retval == 0)
9277 return PyErr_SetFromWindowsErr(0);
9278
9279 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9280}
Larry Hastings2f936352014-08-05 14:04:04 +10009281#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009282
9283
Fred Drakec9680921999-12-13 16:37:25 +00009284/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9285 * It maps strings representing configuration variable names to
9286 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009287 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009288 * rarely-used constants. There are three separate tables that use
9289 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009290 *
9291 * This code is always included, even if none of the interfaces that
9292 * need it are included. The #if hackery needed to avoid it would be
9293 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009294 */
9295struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009296 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009297 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009298};
9299
Fred Drake12c6e2d1999-12-14 21:25:03 +00009300static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009301conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009302 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009303{
Christian Heimes217cfd12007-12-02 14:31:20 +00009304 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009305 int value = _PyLong_AsInt(arg);
9306 if (value == -1 && PyErr_Occurred())
9307 return 0;
9308 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009309 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009310 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009311 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009312 /* look up the value in the table using a binary search */
9313 size_t lo = 0;
9314 size_t mid;
9315 size_t hi = tablesize;
9316 int cmp;
9317 const char *confname;
9318 if (!PyUnicode_Check(arg)) {
9319 PyErr_SetString(PyExc_TypeError,
9320 "configuration names must be strings or integers");
9321 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009323 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009324 if (confname == NULL)
9325 return 0;
9326 while (lo < hi) {
9327 mid = (lo + hi) / 2;
9328 cmp = strcmp(confname, table[mid].name);
9329 if (cmp < 0)
9330 hi = mid;
9331 else if (cmp > 0)
9332 lo = mid + 1;
9333 else {
9334 *valuep = table[mid].value;
9335 return 1;
9336 }
9337 }
9338 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9339 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009341}
9342
9343
9344#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9345static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009346#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009348#endif
9349#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009351#endif
Fred Drakec9680921999-12-13 16:37:25 +00009352#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009397#ifdef _PC_ACL_ENABLED
9398 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9399#endif
9400#ifdef _PC_MIN_HOLE_SIZE
9401 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9402#endif
9403#ifdef _PC_ALLOC_SIZE_MIN
9404 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9405#endif
9406#ifdef _PC_REC_INCR_XFER_SIZE
9407 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9408#endif
9409#ifdef _PC_REC_MAX_XFER_SIZE
9410 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9411#endif
9412#ifdef _PC_REC_MIN_XFER_SIZE
9413 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9414#endif
9415#ifdef _PC_REC_XFER_ALIGN
9416 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9417#endif
9418#ifdef _PC_SYMLINK_MAX
9419 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9420#endif
9421#ifdef _PC_XATTR_ENABLED
9422 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9423#endif
9424#ifdef _PC_XATTR_EXISTS
9425 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9426#endif
9427#ifdef _PC_TIMESTAMP_RESOLUTION
9428 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9429#endif
Fred Drakec9680921999-12-13 16:37:25 +00009430};
9431
Fred Drakec9680921999-12-13 16:37:25 +00009432static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009433conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009434{
9435 return conv_confname(arg, valuep, posix_constants_pathconf,
9436 sizeof(posix_constants_pathconf)
9437 / sizeof(struct constdef));
9438}
9439#endif
9440
Larry Hastings2f936352014-08-05 14:04:04 +10009441
Fred Drakec9680921999-12-13 16:37:25 +00009442#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009443/*[clinic input]
9444os.fpathconf -> long
9445
9446 fd: int
9447 name: path_confname
9448 /
9449
9450Return the configuration limit name for the file descriptor fd.
9451
9452If there is no limit, return -1.
9453[clinic start generated code]*/
9454
Larry Hastings2f936352014-08-05 14:04:04 +10009455static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009456os_fpathconf_impl(PyObject *module, int fd, int name)
9457/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009458{
9459 long limit;
9460
9461 errno = 0;
9462 limit = fpathconf(fd, name);
9463 if (limit == -1 && errno != 0)
9464 posix_error();
9465
9466 return limit;
9467}
9468#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009469
9470
9471#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009472/*[clinic input]
9473os.pathconf -> long
9474 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9475 name: path_confname
9476
9477Return the configuration limit name for the file or directory path.
9478
9479If there is no limit, return -1.
9480On some platforms, path may also be specified as an open file descriptor.
9481 If this functionality is unavailable, using it raises an exception.
9482[clinic start generated code]*/
9483
Larry Hastings2f936352014-08-05 14:04:04 +10009484static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009485os_pathconf_impl(PyObject *module, path_t *path, int name)
9486/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009487{
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009489
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009491#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009492 if (path->fd != -1)
9493 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009494 else
9495#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009496 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 if (limit == -1 && errno != 0) {
9498 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009499 /* could be a path or name problem */
9500 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009501 else
Larry Hastings2f936352014-08-05 14:04:04 +10009502 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 }
Larry Hastings2f936352014-08-05 14:04:04 +10009504
9505 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009506}
Larry Hastings2f936352014-08-05 14:04:04 +10009507#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009508
9509#ifdef HAVE_CONFSTR
9510static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009511#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009513#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009514#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009516#endif
9517#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009519#endif
Fred Draked86ed291999-12-15 15:34:33 +00009520#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009522#endif
9523#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009525#endif
9526#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009528#endif
9529#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009531#endif
Fred Drakec9680921999-12-13 16:37:25 +00009532#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009534#endif
9535#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009537#endif
9538#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009540#endif
9541#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
Fred Draked86ed291999-12-15 15:34:33 +00009556#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009558#endif
Fred Drakec9680921999-12-13 16:37:25 +00009559#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
Fred Draked86ed291999-12-15 15:34:33 +00009562#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009564#endif
9565#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009567#endif
9568#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009570#endif
9571#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009573#endif
Fred Drakec9680921999-12-13 16:37:25 +00009574#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
9589#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
9601#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
9604#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
9610#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009612#endif
9613#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009615#endif
9616#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
9619#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009621#endif
Fred Draked86ed291999-12-15 15:34:33 +00009622#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009624#endif
9625#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009627#endif
9628#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009630#endif
9631#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009633#endif
9634#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009636#endif
9637#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009639#endif
9640#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009642#endif
9643#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009645#endif
9646#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009648#endif
9649#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009651#endif
9652#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009654#endif
9655#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009657#endif
9658#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009660#endif
Fred Drakec9680921999-12-13 16:37:25 +00009661};
9662
9663static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009664conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009665{
9666 return conv_confname(arg, valuep, posix_constants_confstr,
9667 sizeof(posix_constants_confstr)
9668 / sizeof(struct constdef));
9669}
9670
Larry Hastings2f936352014-08-05 14:04:04 +10009671
9672/*[clinic input]
9673os.confstr
9674
9675 name: confstr_confname
9676 /
9677
9678Return a string-valued system configuration variable.
9679[clinic start generated code]*/
9680
Larry Hastings2f936352014-08-05 14:04:04 +10009681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009682os_confstr_impl(PyObject *module, int name)
9683/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009684{
9685 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009686 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009687 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009688
Victor Stinnercb043522010-09-10 23:49:04 +00009689 errno = 0;
9690 len = confstr(name, buffer, sizeof(buffer));
9691 if (len == 0) {
9692 if (errno) {
9693 posix_error();
9694 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009695 }
9696 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009697 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009698 }
9699 }
Victor Stinnercb043522010-09-10 23:49:04 +00009700
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009701 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009702 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009703 char *buf = PyMem_Malloc(len);
9704 if (buf == NULL)
9705 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009706 len2 = confstr(name, buf, len);
9707 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009708 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009709 PyMem_Free(buf);
9710 }
9711 else
9712 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009713 return result;
9714}
Larry Hastings2f936352014-08-05 14:04:04 +10009715#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009716
9717
9718#ifdef HAVE_SYSCONF
9719static struct constdef posix_constants_sysconf[] = {
9720#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
Fred Draked86ed291999-12-15 15:34:33 +00009750#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009752#endif
9753#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009755#endif
Fred Drakec9680921999-12-13 16:37:25 +00009756#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
Fred Drakec9680921999-12-13 16:37:25 +00009759#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
Fred Draked86ed291999-12-15 15:34:33 +00009774#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009776#endif
Fred Drakec9680921999-12-13 16:37:25 +00009777#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
Fred Draked86ed291999-12-15 15:34:33 +00009792#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009794#endif
Fred Drakec9680921999-12-13 16:37:25 +00009795#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
Fred Draked86ed291999-12-15 15:34:33 +00009864#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009866#endif
Fred Drakec9680921999-12-13 16:37:25 +00009867#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
Fred Draked86ed291999-12-15 15:34:33 +00009876#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009878#endif
Fred Drakec9680921999-12-13 16:37:25 +00009879#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
Fred Draked86ed291999-12-15 15:34:33 +00009882#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009884#endif
9885#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009887#endif
Fred Drakec9680921999-12-13 16:37:25 +00009888#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
Fred Draked86ed291999-12-15 15:34:33 +00009900#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009902#endif
Fred Drakec9680921999-12-13 16:37:25 +00009903#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
Fred Draked86ed291999-12-15 15:34:33 +00009924#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009926#endif
Fred Drakec9680921999-12-13 16:37:25 +00009927#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
Fred Draked86ed291999-12-15 15:34:33 +00009933#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009935#endif
Fred Drakec9680921999-12-13 16:37:25 +00009936#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
Fred Draked86ed291999-12-15 15:34:33 +00009963#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009965#endif
9966#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009968#endif
Fred Drakec9680921999-12-13 16:37:25 +00009969#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
Fred Draked86ed291999-12-15 15:34:33 +000010074#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010076#endif
Fred Drakec9680921999-12-13 16:37:25 +000010077#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212};
10213
10214static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010215conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010216{
10217 return conv_confname(arg, valuep, posix_constants_sysconf,
10218 sizeof(posix_constants_sysconf)
10219 / sizeof(struct constdef));
10220}
10221
Larry Hastings2f936352014-08-05 14:04:04 +100010222
10223/*[clinic input]
10224os.sysconf -> long
10225 name: sysconf_confname
10226 /
10227
10228Return an integer-valued system configuration variable.
10229[clinic start generated code]*/
10230
Larry Hastings2f936352014-08-05 14:04:04 +100010231static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010232os_sysconf_impl(PyObject *module, int name)
10233/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010234{
10235 long value;
10236
10237 errno = 0;
10238 value = sysconf(name);
10239 if (value == -1 && errno != 0)
10240 posix_error();
10241 return value;
10242}
10243#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010244
10245
Fred Drakebec628d1999-12-15 18:31:10 +000010246/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010247 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010248 * the exported dictionaries that are used to publish information about the
10249 * names available on the host platform.
10250 *
10251 * Sorting the table at runtime ensures that the table is properly ordered
10252 * when used, even for platforms we're not able to test on. It also makes
10253 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010254 */
Fred Drakebec628d1999-12-15 18:31:10 +000010255
10256static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010257cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010258{
10259 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010261 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010263
10264 return strcmp(c1->name, c2->name);
10265}
10266
10267static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010268setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010269 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010270{
Fred Drakebec628d1999-12-15 18:31:10 +000010271 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010272 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010273
10274 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10275 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010276 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010278
Barry Warsaw3155db32000-04-13 15:20:40 +000010279 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 PyObject *o = PyLong_FromLong(table[i].value);
10281 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10282 Py_XDECREF(o);
10283 Py_DECREF(d);
10284 return -1;
10285 }
10286 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010287 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010288 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010289}
10290
Fred Drakebec628d1999-12-15 18:31:10 +000010291/* Return -1 on failure, 0 on success. */
10292static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010293setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010294{
10295#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010296 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010297 sizeof(posix_constants_pathconf)
10298 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010299 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010300 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010301#endif
10302#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010303 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010304 sizeof(posix_constants_confstr)
10305 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010306 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010307 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010308#endif
10309#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010310 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010311 sizeof(posix_constants_sysconf)
10312 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010313 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010314 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010315#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010316 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010317}
Fred Draked86ed291999-12-15 15:34:33 +000010318
10319
Larry Hastings2f936352014-08-05 14:04:04 +100010320/*[clinic input]
10321os.abort
10322
10323Abort the interpreter immediately.
10324
10325This function 'dumps core' or otherwise fails in the hardest way possible
10326on the hosting operating system. This function never returns.
10327[clinic start generated code]*/
10328
Larry Hastings2f936352014-08-05 14:04:04 +100010329static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010330os_abort_impl(PyObject *module)
10331/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010332{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010333 abort();
10334 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010335#ifndef __clang__
10336 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10337 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10338 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010339 Py_FatalError("abort() called from Python code didn't abort!");
10340 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010341#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010342}
Fred Drakebec628d1999-12-15 18:31:10 +000010343
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010344#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010345/* Grab ShellExecute dynamically from shell32 */
10346static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010347static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10348 LPCWSTR, INT);
10349static int
10350check_ShellExecute()
10351{
10352 HINSTANCE hShell32;
10353
10354 /* only recheck */
10355 if (-1 == has_ShellExecute) {
10356 Py_BEGIN_ALLOW_THREADS
10357 hShell32 = LoadLibraryW(L"SHELL32");
10358 Py_END_ALLOW_THREADS
10359 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010360 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10361 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010362 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010363 } else {
10364 has_ShellExecute = 0;
10365 }
10366 }
10367 return has_ShellExecute;
10368}
10369
10370
Steve Dowercc16be82016-09-08 10:35:16 -070010371/*[clinic input]
10372os.startfile
10373 filepath: path_t
10374 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010375
Steve Dowercc16be82016-09-08 10:35:16 -070010376startfile(filepath [, operation])
10377
10378Start a file with its associated application.
10379
10380When "operation" is not specified or "open", this acts like
10381double-clicking the file in Explorer, or giving the file name as an
10382argument to the DOS "start" command: the file is opened with whatever
10383application (if any) its extension is associated.
10384When another "operation" is given, it specifies what should be done with
10385the file. A typical operation is "print".
10386
10387startfile returns as soon as the associated application is launched.
10388There is no option to wait for the application to close, and no way
10389to retrieve the application's exit status.
10390
10391The filepath is relative to the current directory. If you want to use
10392an absolute path, make sure the first character is not a slash ("/");
10393the underlying Win32 ShellExecute function doesn't work if it is.
10394[clinic start generated code]*/
10395
10396static PyObject *
10397os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10398/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10399{
10400 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010401
10402 if(!check_ShellExecute()) {
10403 /* If the OS doesn't have ShellExecute, return a
10404 NotImplementedError. */
10405 return PyErr_Format(PyExc_NotImplementedError,
10406 "startfile not available on this platform");
10407 }
10408
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010410 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010411 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 Py_END_ALLOW_THREADS
10413
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010415 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010416 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 }
Steve Dowercc16be82016-09-08 10:35:16 -070010418 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010419}
Larry Hastings2f936352014-08-05 14:04:04 +100010420#endif /* MS_WINDOWS */
10421
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010422
Martin v. Löwis438b5342002-12-27 10:16:42 +000010423#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010424/*[clinic input]
10425os.getloadavg
10426
10427Return average recent system load information.
10428
10429Return the number of processes in the system run queue averaged over
10430the last 1, 5, and 15 minutes as a tuple of three floats.
10431Raises OSError if the load average was unobtainable.
10432[clinic start generated code]*/
10433
Larry Hastings2f936352014-08-05 14:04:04 +100010434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010435os_getloadavg_impl(PyObject *module)
10436/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010437{
10438 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010439 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010440 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10441 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010442 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010443 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010444}
Larry Hastings2f936352014-08-05 14:04:04 +100010445#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010446
Larry Hastings2f936352014-08-05 14:04:04 +100010447
10448/*[clinic input]
10449os.device_encoding
10450 fd: int
10451
10452Return a string describing the encoding of a terminal's file descriptor.
10453
10454The file descriptor must be attached to a terminal.
10455If the device is not a terminal, return None.
10456[clinic start generated code]*/
10457
Larry Hastings2f936352014-08-05 14:04:04 +100010458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010459os_device_encoding_impl(PyObject *module, int fd)
10460/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010461{
Brett Cannonefb00c02012-02-29 18:31:31 -050010462 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010463}
10464
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010465
Larry Hastings2f936352014-08-05 14:04:04 +100010466#ifdef HAVE_SETRESUID
10467/*[clinic input]
10468os.setresuid
10469
10470 ruid: uid_t
10471 euid: uid_t
10472 suid: uid_t
10473 /
10474
10475Set the current process's real, effective, and saved user ids.
10476[clinic start generated code]*/
10477
Larry Hastings2f936352014-08-05 14:04:04 +100010478static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010479os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10480/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010481{
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 if (setresuid(ruid, euid, suid) < 0)
10483 return posix_error();
10484 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010485}
Larry Hastings2f936352014-08-05 14:04:04 +100010486#endif /* HAVE_SETRESUID */
10487
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010488
10489#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010490/*[clinic input]
10491os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010492
Larry Hastings2f936352014-08-05 14:04:04 +100010493 rgid: gid_t
10494 egid: gid_t
10495 sgid: gid_t
10496 /
10497
10498Set the current process's real, effective, and saved group ids.
10499[clinic start generated code]*/
10500
Larry Hastings2f936352014-08-05 14:04:04 +100010501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010502os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10503/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010504{
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 if (setresgid(rgid, egid, sgid) < 0)
10506 return posix_error();
10507 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010508}
Larry Hastings2f936352014-08-05 14:04:04 +100010509#endif /* HAVE_SETRESGID */
10510
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010511
10512#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010513/*[clinic input]
10514os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010515
Larry Hastings2f936352014-08-05 14:04:04 +100010516Return a tuple of the current process's real, effective, and saved user ids.
10517[clinic start generated code]*/
10518
Larry Hastings2f936352014-08-05 14:04:04 +100010519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010520os_getresuid_impl(PyObject *module)
10521/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010522{
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 if (getresuid(&ruid, &euid, &suid) < 0)
10525 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010526 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10527 _PyLong_FromUid(euid),
10528 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010529}
Larry Hastings2f936352014-08-05 14:04:04 +100010530#endif /* HAVE_GETRESUID */
10531
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010532
10533#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010534/*[clinic input]
10535os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010536
Larry Hastings2f936352014-08-05 14:04:04 +100010537Return a tuple of the current process's real, effective, and saved group ids.
10538[clinic start generated code]*/
10539
Larry Hastings2f936352014-08-05 14:04:04 +100010540static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010541os_getresgid_impl(PyObject *module)
10542/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010543{
10544 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 if (getresgid(&rgid, &egid, &sgid) < 0)
10546 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010547 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10548 _PyLong_FromGid(egid),
10549 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010550}
Larry Hastings2f936352014-08-05 14:04:04 +100010551#endif /* HAVE_GETRESGID */
10552
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010553
Benjamin Peterson9428d532011-09-14 11:45:52 -040010554#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010555/*[clinic input]
10556os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010557
Larry Hastings2f936352014-08-05 14:04:04 +100010558 path: path_t(allow_fd=True)
10559 attribute: path_t
10560 *
10561 follow_symlinks: bool = True
10562
10563Return the value of extended attribute attribute on path.
10564
10565path may be either a string or an open file descriptor.
10566If follow_symlinks is False, and the last element of the path is a symbolic
10567 link, getxattr will examine the symbolic link itself instead of the file
10568 the link points to.
10569
10570[clinic start generated code]*/
10571
Larry Hastings2f936352014-08-05 14:04:04 +100010572static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010573os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010574 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010575/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010576{
10577 Py_ssize_t i;
10578 PyObject *buffer = NULL;
10579
10580 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10581 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582
Larry Hastings9cf065c2012-06-22 16:30:09 -070010583 for (i = 0; ; i++) {
10584 void *ptr;
10585 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010586 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010587 Py_ssize_t buffer_size = buffer_sizes[i];
10588 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010589 path_error(path);
10590 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010591 }
10592 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10593 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010594 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010596
Larry Hastings9cf065c2012-06-22 16:30:09 -070010597 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010598 if (path->fd >= 0)
10599 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010600 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010601 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010602 else
Larry Hastings2f936352014-08-05 14:04:04 +100010603 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010604 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010605
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 if (result < 0) {
10607 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608 if (errno == ERANGE)
10609 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010610 path_error(path);
10611 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010613
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 if (result != buffer_size) {
10615 /* Can only shrink. */
10616 _PyBytes_Resize(&buffer, result);
10617 }
10618 break;
10619 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010620
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622}
10623
Larry Hastings2f936352014-08-05 14:04:04 +100010624
10625/*[clinic input]
10626os.setxattr
10627
10628 path: path_t(allow_fd=True)
10629 attribute: path_t
10630 value: Py_buffer
10631 flags: int = 0
10632 *
10633 follow_symlinks: bool = True
10634
10635Set extended attribute attribute on path to value.
10636
10637path may be either a string or an open file descriptor.
10638If follow_symlinks is False, and the last element of the path is a symbolic
10639 link, setxattr will modify the symbolic link itself instead of the file
10640 the link points to.
10641
10642[clinic start generated code]*/
10643
Benjamin Peterson799bd802011-08-31 22:15:17 -040010644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010645os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010646 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010647/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648{
Larry Hastings2f936352014-08-05 14:04:04 +100010649 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010650
Larry Hastings2f936352014-08-05 14:04:04 +100010651 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010653
Benjamin Peterson799bd802011-08-31 22:15:17 -040010654 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010655 if (path->fd > -1)
10656 result = fsetxattr(path->fd, attribute->narrow,
10657 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010658 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010659 result = setxattr(path->narrow, attribute->narrow,
10660 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661 else
Larry Hastings2f936352014-08-05 14:04:04 +100010662 result = lsetxattr(path->narrow, attribute->narrow,
10663 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010664 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010665
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010667 path_error(path);
10668 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010669 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670
Larry Hastings2f936352014-08-05 14:04:04 +100010671 Py_RETURN_NONE;
10672}
10673
10674
10675/*[clinic input]
10676os.removexattr
10677
10678 path: path_t(allow_fd=True)
10679 attribute: path_t
10680 *
10681 follow_symlinks: bool = True
10682
10683Remove extended attribute attribute on path.
10684
10685path may be either a string or an open file descriptor.
10686If follow_symlinks is False, and the last element of the path is a symbolic
10687 link, removexattr will modify the symbolic link itself instead of the file
10688 the link points to.
10689
10690[clinic start generated code]*/
10691
Larry Hastings2f936352014-08-05 14:04:04 +100010692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010693os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010694 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010695/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010696{
10697 ssize_t result;
10698
10699 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10700 return NULL;
10701
10702 Py_BEGIN_ALLOW_THREADS;
10703 if (path->fd > -1)
10704 result = fremovexattr(path->fd, attribute->narrow);
10705 else if (follow_symlinks)
10706 result = removexattr(path->narrow, attribute->narrow);
10707 else
10708 result = lremovexattr(path->narrow, attribute->narrow);
10709 Py_END_ALLOW_THREADS;
10710
10711 if (result) {
10712 return path_error(path);
10713 }
10714
10715 Py_RETURN_NONE;
10716}
10717
10718
10719/*[clinic input]
10720os.listxattr
10721
10722 path: path_t(allow_fd=True, nullable=True) = None
10723 *
10724 follow_symlinks: bool = True
10725
10726Return a list of extended attributes on path.
10727
10728path may be either None, a string, or an open file descriptor.
10729if path is None, listxattr will examine the current directory.
10730If follow_symlinks is False, and the last element of the path is a symbolic
10731 link, listxattr will examine the symbolic link itself instead of the file
10732 the link points to.
10733[clinic start generated code]*/
10734
Larry Hastings2f936352014-08-05 14:04:04 +100010735static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010736os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10737/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010738{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010739 Py_ssize_t i;
10740 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010741 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010742 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743
Larry Hastings2f936352014-08-05 14:04:04 +100010744 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010746
Larry Hastings2f936352014-08-05 14:04:04 +100010747 name = path->narrow ? path->narrow : ".";
10748
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010750 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010752 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 Py_ssize_t buffer_size = buffer_sizes[i];
10754 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010755 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010756 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 break;
10758 }
10759 buffer = PyMem_MALLOC(buffer_size);
10760 if (!buffer) {
10761 PyErr_NoMemory();
10762 break;
10763 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010764
Larry Hastings9cf065c2012-06-22 16:30:09 -070010765 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010766 if (path->fd > -1)
10767 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 else if (follow_symlinks)
10769 length = listxattr(name, buffer, buffer_size);
10770 else
10771 length = llistxattr(name, buffer, buffer_size);
10772 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010773
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010775 if (errno == ERANGE) {
10776 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010777 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010779 }
Larry Hastings2f936352014-08-05 14:04:04 +100010780 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010781 break;
10782 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783
Larry Hastings9cf065c2012-06-22 16:30:09 -070010784 result = PyList_New(0);
10785 if (!result) {
10786 goto exit;
10787 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010788
Larry Hastings9cf065c2012-06-22 16:30:09 -070010789 end = buffer + length;
10790 for (trace = start = buffer; trace != end; trace++) {
10791 if (!*trace) {
10792 int error;
10793 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10794 trace - start);
10795 if (!attribute) {
10796 Py_DECREF(result);
10797 result = NULL;
10798 goto exit;
10799 }
10800 error = PyList_Append(result, attribute);
10801 Py_DECREF(attribute);
10802 if (error) {
10803 Py_DECREF(result);
10804 result = NULL;
10805 goto exit;
10806 }
10807 start = trace + 1;
10808 }
10809 }
10810 break;
10811 }
10812exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010813 if (buffer)
10814 PyMem_FREE(buffer);
10815 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010816}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010817#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010819
Larry Hastings2f936352014-08-05 14:04:04 +100010820/*[clinic input]
10821os.urandom
10822
10823 size: Py_ssize_t
10824 /
10825
10826Return a bytes object containing random bytes suitable for cryptographic use.
10827[clinic start generated code]*/
10828
Larry Hastings2f936352014-08-05 14:04:04 +100010829static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010830os_urandom_impl(PyObject *module, Py_ssize_t size)
10831/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010832{
10833 PyObject *bytes;
10834 int result;
10835
Georg Brandl2fb477c2012-02-21 00:33:36 +010010836 if (size < 0)
10837 return PyErr_Format(PyExc_ValueError,
10838 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010839 bytes = PyBytes_FromStringAndSize(NULL, size);
10840 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010841 return NULL;
10842
Victor Stinnere66987e2016-09-06 16:33:52 -070010843 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010844 if (result == -1) {
10845 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010846 return NULL;
10847 }
Larry Hastings2f936352014-08-05 14:04:04 +100010848 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010849}
10850
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010851/* Terminal size querying */
10852
10853static PyTypeObject TerminalSizeType;
10854
10855PyDoc_STRVAR(TerminalSize_docstring,
10856 "A tuple of (columns, lines) for holding terminal window size");
10857
10858static PyStructSequence_Field TerminalSize_fields[] = {
10859 {"columns", "width of the terminal window in characters"},
10860 {"lines", "height of the terminal window in characters"},
10861 {NULL, NULL}
10862};
10863
10864static PyStructSequence_Desc TerminalSize_desc = {
10865 "os.terminal_size",
10866 TerminalSize_docstring,
10867 TerminalSize_fields,
10868 2,
10869};
10870
10871#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010872/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010873PyDoc_STRVAR(termsize__doc__,
10874 "Return the size of the terminal window as (columns, lines).\n" \
10875 "\n" \
10876 "The optional argument fd (default standard output) specifies\n" \
10877 "which file descriptor should be queried.\n" \
10878 "\n" \
10879 "If the file descriptor is not connected to a terminal, an OSError\n" \
10880 "is thrown.\n" \
10881 "\n" \
10882 "This function will only be defined if an implementation is\n" \
10883 "available for this system.\n" \
10884 "\n" \
10885 "shutil.get_terminal_size is the high-level function which should \n" \
10886 "normally be used, os.get_terminal_size is the low-level implementation.");
10887
10888static PyObject*
10889get_terminal_size(PyObject *self, PyObject *args)
10890{
10891 int columns, lines;
10892 PyObject *termsize;
10893
10894 int fd = fileno(stdout);
10895 /* Under some conditions stdout may not be connected and
10896 * fileno(stdout) may point to an invalid file descriptor. For example
10897 * GUI apps don't have valid standard streams by default.
10898 *
10899 * If this happens, and the optional fd argument is not present,
10900 * the ioctl below will fail returning EBADF. This is what we want.
10901 */
10902
10903 if (!PyArg_ParseTuple(args, "|i", &fd))
10904 return NULL;
10905
10906#ifdef TERMSIZE_USE_IOCTL
10907 {
10908 struct winsize w;
10909 if (ioctl(fd, TIOCGWINSZ, &w))
10910 return PyErr_SetFromErrno(PyExc_OSError);
10911 columns = w.ws_col;
10912 lines = w.ws_row;
10913 }
10914#endif /* TERMSIZE_USE_IOCTL */
10915
10916#ifdef TERMSIZE_USE_CONIO
10917 {
10918 DWORD nhandle;
10919 HANDLE handle;
10920 CONSOLE_SCREEN_BUFFER_INFO csbi;
10921 switch (fd) {
10922 case 0: nhandle = STD_INPUT_HANDLE;
10923 break;
10924 case 1: nhandle = STD_OUTPUT_HANDLE;
10925 break;
10926 case 2: nhandle = STD_ERROR_HANDLE;
10927 break;
10928 default:
10929 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10930 }
10931 handle = GetStdHandle(nhandle);
10932 if (handle == NULL)
10933 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10934 if (handle == INVALID_HANDLE_VALUE)
10935 return PyErr_SetFromWindowsErr(0);
10936
10937 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10938 return PyErr_SetFromWindowsErr(0);
10939
10940 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10941 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10942 }
10943#endif /* TERMSIZE_USE_CONIO */
10944
10945 termsize = PyStructSequence_New(&TerminalSizeType);
10946 if (termsize == NULL)
10947 return NULL;
10948 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10949 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10950 if (PyErr_Occurred()) {
10951 Py_DECREF(termsize);
10952 return NULL;
10953 }
10954 return termsize;
10955}
10956#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10957
Larry Hastings2f936352014-08-05 14:04:04 +100010958
10959/*[clinic input]
10960os.cpu_count
10961
Charles-François Natali80d62e62015-08-13 20:37:08 +010010962Return the number of CPUs in the system; return None if indeterminable.
10963
10964This number is not equivalent to the number of CPUs the current process can
10965use. The number of usable CPUs can be obtained with
10966``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010967[clinic start generated code]*/
10968
Larry Hastings2f936352014-08-05 14:04:04 +100010969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010970os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010971/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010972{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010973 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010974#ifdef MS_WINDOWS
10975 SYSTEM_INFO sysinfo;
10976 GetSystemInfo(&sysinfo);
10977 ncpu = sysinfo.dwNumberOfProcessors;
10978#elif defined(__hpux)
10979 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10980#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10981 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010982#elif defined(__DragonFly__) || \
10983 defined(__OpenBSD__) || \
10984 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010985 defined(__NetBSD__) || \
10986 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010987 int mib[2];
10988 size_t len = sizeof(ncpu);
10989 mib[0] = CTL_HW;
10990 mib[1] = HW_NCPU;
10991 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10992 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010993#endif
10994 if (ncpu >= 1)
10995 return PyLong_FromLong(ncpu);
10996 else
10997 Py_RETURN_NONE;
10998}
10999
Victor Stinnerdaf45552013-08-28 00:53:59 +020011000
Larry Hastings2f936352014-08-05 14:04:04 +100011001/*[clinic input]
11002os.get_inheritable -> bool
11003
11004 fd: int
11005 /
11006
11007Get the close-on-exe flag of the specified file descriptor.
11008[clinic start generated code]*/
11009
Larry Hastings2f936352014-08-05 14:04:04 +100011010static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011011os_get_inheritable_impl(PyObject *module, int fd)
11012/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011013{
Steve Dower8fc89802015-04-12 00:26:27 -040011014 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011015 _Py_BEGIN_SUPPRESS_IPH
11016 return_value = _Py_get_inheritable(fd);
11017 _Py_END_SUPPRESS_IPH
11018 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011019}
11020
11021
11022/*[clinic input]
11023os.set_inheritable
11024 fd: int
11025 inheritable: int
11026 /
11027
11028Set the inheritable flag of the specified file descriptor.
11029[clinic start generated code]*/
11030
Larry Hastings2f936352014-08-05 14:04:04 +100011031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011032os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11033/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011034{
Steve Dower8fc89802015-04-12 00:26:27 -040011035 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011036
Steve Dower8fc89802015-04-12 00:26:27 -040011037 _Py_BEGIN_SUPPRESS_IPH
11038 result = _Py_set_inheritable(fd, inheritable, NULL);
11039 _Py_END_SUPPRESS_IPH
11040 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011041 return NULL;
11042 Py_RETURN_NONE;
11043}
11044
11045
11046#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011047/*[clinic input]
11048os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011049 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011050 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011051
Larry Hastings2f936352014-08-05 14:04:04 +100011052Get the close-on-exe flag of the specified file descriptor.
11053[clinic start generated code]*/
11054
Larry Hastings2f936352014-08-05 14:04:04 +100011055static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011056os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011057/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011058{
11059 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011060
11061 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11062 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011063 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011064 }
11065
Larry Hastings2f936352014-08-05 14:04:04 +100011066 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011067}
11068
Victor Stinnerdaf45552013-08-28 00:53:59 +020011069
Larry Hastings2f936352014-08-05 14:04:04 +100011070/*[clinic input]
11071os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011072 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011073 inheritable: bool
11074 /
11075
11076Set the inheritable flag of the specified handle.
11077[clinic start generated code]*/
11078
Larry Hastings2f936352014-08-05 14:04:04 +100011079static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011080os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011081 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011082/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011083{
11084 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011085 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11086 PyErr_SetFromWindowsErr(0);
11087 return NULL;
11088 }
11089 Py_RETURN_NONE;
11090}
Larry Hastings2f936352014-08-05 14:04:04 +100011091#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011092
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011093#ifndef MS_WINDOWS
11094PyDoc_STRVAR(get_blocking__doc__,
11095 "get_blocking(fd) -> bool\n" \
11096 "\n" \
11097 "Get the blocking mode of the file descriptor:\n" \
11098 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11099
11100static PyObject*
11101posix_get_blocking(PyObject *self, PyObject *args)
11102{
11103 int fd;
11104 int blocking;
11105
11106 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11107 return NULL;
11108
Steve Dower8fc89802015-04-12 00:26:27 -040011109 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011110 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011111 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011112 if (blocking < 0)
11113 return NULL;
11114 return PyBool_FromLong(blocking);
11115}
11116
11117PyDoc_STRVAR(set_blocking__doc__,
11118 "set_blocking(fd, blocking)\n" \
11119 "\n" \
11120 "Set the blocking mode of the specified file descriptor.\n" \
11121 "Set the O_NONBLOCK flag if blocking is False,\n" \
11122 "clear the O_NONBLOCK flag otherwise.");
11123
11124static PyObject*
11125posix_set_blocking(PyObject *self, PyObject *args)
11126{
Steve Dower8fc89802015-04-12 00:26:27 -040011127 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011128
11129 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11130 return NULL;
11131
Steve Dower8fc89802015-04-12 00:26:27 -040011132 _Py_BEGIN_SUPPRESS_IPH
11133 result = _Py_set_blocking(fd, blocking);
11134 _Py_END_SUPPRESS_IPH
11135 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011136 return NULL;
11137 Py_RETURN_NONE;
11138}
11139#endif /* !MS_WINDOWS */
11140
11141
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011142/*[clinic input]
11143class os.DirEntry "DirEntry *" "&DirEntryType"
11144[clinic start generated code]*/
11145/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011146
11147typedef struct {
11148 PyObject_HEAD
11149 PyObject *name;
11150 PyObject *path;
11151 PyObject *stat;
11152 PyObject *lstat;
11153#ifdef MS_WINDOWS
11154 struct _Py_stat_struct win32_lstat;
11155 __int64 win32_file_index;
11156 int got_file_index;
11157#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011158#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011159 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011160#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011161 ino_t d_ino;
11162#endif
11163} DirEntry;
11164
11165static void
11166DirEntry_dealloc(DirEntry *entry)
11167{
11168 Py_XDECREF(entry->name);
11169 Py_XDECREF(entry->path);
11170 Py_XDECREF(entry->stat);
11171 Py_XDECREF(entry->lstat);
11172 Py_TYPE(entry)->tp_free((PyObject *)entry);
11173}
11174
11175/* Forward reference */
11176static int
11177DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11178
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011179/*[clinic input]
11180os.DirEntry.is_symlink -> bool
11181
11182Return True if the entry is a symbolic link; cached per entry.
11183[clinic start generated code]*/
11184
Victor Stinner6036e442015-03-08 01:58:04 +010011185static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011186os_DirEntry_is_symlink_impl(DirEntry *self)
11187/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011188{
11189#ifdef MS_WINDOWS
11190 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011191#elif defined(HAVE_DIRENT_D_TYPE)
11192 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011193 if (self->d_type != DT_UNKNOWN)
11194 return self->d_type == DT_LNK;
11195 else
11196 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011197#else
11198 /* POSIX without d_type */
11199 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011200#endif
11201}
11202
11203static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011204DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11205{
11206 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011207 STRUCT_STAT st;
11208 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011209
11210#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011211 if (PyUnicode_FSDecoder(self->path, &ub)) {
11212 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011213#else /* POSIX */
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011214 if (PyUnicode_FSConverter(self->path, &ub)) {
11215 const char *path = PyBytes_AS_STRING(ub);
11216#endif
11217 if (follow_symlinks)
11218 result = STAT(path, &st);
11219 else
11220 result = LSTAT(path, &st);
11221 Py_DECREF(ub);
11222 } else
Victor Stinner6036e442015-03-08 01:58:04 +010011223 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011224
11225 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011226 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011227
11228 return _pystat_fromstructstat(&st);
11229}
11230
11231static PyObject *
11232DirEntry_get_lstat(DirEntry *self)
11233{
11234 if (!self->lstat) {
11235#ifdef MS_WINDOWS
11236 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11237#else /* POSIX */
11238 self->lstat = DirEntry_fetch_stat(self, 0);
11239#endif
11240 }
11241 Py_XINCREF(self->lstat);
11242 return self->lstat;
11243}
11244
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011245/*[clinic input]
11246os.DirEntry.stat
11247 *
11248 follow_symlinks: bool = True
11249
11250Return stat_result object for the entry; cached per entry.
11251[clinic start generated code]*/
11252
Victor Stinner6036e442015-03-08 01:58:04 +010011253static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011254os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11255/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011256{
11257 if (!follow_symlinks)
11258 return DirEntry_get_lstat(self);
11259
11260 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011261 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011262 if (result == -1)
11263 return NULL;
11264 else if (result)
11265 self->stat = DirEntry_fetch_stat(self, 1);
11266 else
11267 self->stat = DirEntry_get_lstat(self);
11268 }
11269
11270 Py_XINCREF(self->stat);
11271 return self->stat;
11272}
11273
Victor Stinner6036e442015-03-08 01:58:04 +010011274/* Set exception and return -1 on error, 0 for False, 1 for True */
11275static int
11276DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11277{
11278 PyObject *stat = NULL;
11279 PyObject *st_mode = NULL;
11280 long mode;
11281 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011282#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011283 int is_symlink;
11284 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011285#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011286#ifdef MS_WINDOWS
11287 unsigned long dir_bits;
11288#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011289 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011290
11291#ifdef MS_WINDOWS
11292 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11293 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011294#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011295 is_symlink = self->d_type == DT_LNK;
11296 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11297#endif
11298
Victor Stinner35a97c02015-03-08 02:59:09 +010011299#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011300 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011301#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011302 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011303 if (!stat) {
11304 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11305 /* If file doesn't exist (anymore), then return False
11306 (i.e., say it's not a file/directory) */
11307 PyErr_Clear();
11308 return 0;
11309 }
11310 goto error;
11311 }
11312 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11313 if (!st_mode)
11314 goto error;
11315
11316 mode = PyLong_AsLong(st_mode);
11317 if (mode == -1 && PyErr_Occurred())
11318 goto error;
11319 Py_CLEAR(st_mode);
11320 Py_CLEAR(stat);
11321 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011322#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011323 }
11324 else if (is_symlink) {
11325 assert(mode_bits != S_IFLNK);
11326 result = 0;
11327 }
11328 else {
11329 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11330#ifdef MS_WINDOWS
11331 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11332 if (mode_bits == S_IFDIR)
11333 result = dir_bits != 0;
11334 else
11335 result = dir_bits == 0;
11336#else /* POSIX */
11337 if (mode_bits == S_IFDIR)
11338 result = self->d_type == DT_DIR;
11339 else
11340 result = self->d_type == DT_REG;
11341#endif
11342 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011343#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011344
11345 return result;
11346
11347error:
11348 Py_XDECREF(st_mode);
11349 Py_XDECREF(stat);
11350 return -1;
11351}
11352
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011353/*[clinic input]
11354os.DirEntry.is_dir -> bool
11355 *
11356 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011357
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011358Return True if the entry is a directory; cached per entry.
11359[clinic start generated code]*/
11360
11361static int
11362os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11363/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11364{
11365 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011366}
11367
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011368/*[clinic input]
11369os.DirEntry.is_file -> bool
11370 *
11371 follow_symlinks: bool = True
11372
11373Return True if the entry is a file; cached per entry.
11374[clinic start generated code]*/
11375
11376static int
11377os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11378/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011379{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011380 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011381}
11382
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011383/*[clinic input]
11384os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011385
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011386Return inode of the entry; cached per entry.
11387[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011388
11389static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011390os_DirEntry_inode_impl(DirEntry *self)
11391/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011392{
11393#ifdef MS_WINDOWS
11394 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011395 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011396 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011397 STRUCT_STAT stat;
11398 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011399
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011400 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011401 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011402 path = PyUnicode_AsUnicode(unicode);
11403 result = LSTAT(path, &stat);
11404 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011405
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011406 if (result != 0)
11407 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011408
11409 self->win32_file_index = stat.st_ino;
11410 self->got_file_index = 1;
11411 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011412 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011413#else /* POSIX */
11414#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011415 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011416#else
11417 return PyLong_FromLong((long)self->d_ino);
11418#endif
11419#endif
11420}
11421
11422static PyObject *
11423DirEntry_repr(DirEntry *self)
11424{
11425 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11426}
11427
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011428/*[clinic input]
11429os.DirEntry.__fspath__
11430
11431Returns the path for the entry.
11432[clinic start generated code]*/
11433
Brett Cannon96881cd2016-06-10 14:37:21 -070011434static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011435os_DirEntry___fspath___impl(DirEntry *self)
11436/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011437{
11438 Py_INCREF(self->path);
11439 return self->path;
11440}
11441
Victor Stinner6036e442015-03-08 01:58:04 +010011442static PyMemberDef DirEntry_members[] = {
11443 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11444 "the entry's base filename, relative to scandir() \"path\" argument"},
11445 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11446 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11447 {NULL}
11448};
11449
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011450#include "clinic/posixmodule.c.h"
11451
Victor Stinner6036e442015-03-08 01:58:04 +010011452static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011453 OS_DIRENTRY_IS_DIR_METHODDEF
11454 OS_DIRENTRY_IS_FILE_METHODDEF
11455 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11456 OS_DIRENTRY_STAT_METHODDEF
11457 OS_DIRENTRY_INODE_METHODDEF
11458 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011459 {NULL}
11460};
11461
Benjamin Peterson5646de42015-04-12 17:56:34 -040011462static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011463 PyVarObject_HEAD_INIT(NULL, 0)
11464 MODNAME ".DirEntry", /* tp_name */
11465 sizeof(DirEntry), /* tp_basicsize */
11466 0, /* tp_itemsize */
11467 /* methods */
11468 (destructor)DirEntry_dealloc, /* tp_dealloc */
11469 0, /* tp_print */
11470 0, /* tp_getattr */
11471 0, /* tp_setattr */
11472 0, /* tp_compare */
11473 (reprfunc)DirEntry_repr, /* tp_repr */
11474 0, /* tp_as_number */
11475 0, /* tp_as_sequence */
11476 0, /* tp_as_mapping */
11477 0, /* tp_hash */
11478 0, /* tp_call */
11479 0, /* tp_str */
11480 0, /* tp_getattro */
11481 0, /* tp_setattro */
11482 0, /* tp_as_buffer */
11483 Py_TPFLAGS_DEFAULT, /* tp_flags */
11484 0, /* tp_doc */
11485 0, /* tp_traverse */
11486 0, /* tp_clear */
11487 0, /* tp_richcompare */
11488 0, /* tp_weaklistoffset */
11489 0, /* tp_iter */
11490 0, /* tp_iternext */
11491 DirEntry_methods, /* tp_methods */
11492 DirEntry_members, /* tp_members */
11493};
11494
11495#ifdef MS_WINDOWS
11496
11497static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011498join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011499{
11500 Py_ssize_t path_len;
11501 Py_ssize_t size;
11502 wchar_t *result;
11503 wchar_t ch;
11504
11505 if (!path_wide) { /* Default arg: "." */
11506 path_wide = L".";
11507 path_len = 1;
11508 }
11509 else {
11510 path_len = wcslen(path_wide);
11511 }
11512
11513 /* The +1's are for the path separator and the NUL */
11514 size = path_len + 1 + wcslen(filename) + 1;
11515 result = PyMem_New(wchar_t, size);
11516 if (!result) {
11517 PyErr_NoMemory();
11518 return NULL;
11519 }
11520 wcscpy(result, path_wide);
11521 if (path_len > 0) {
11522 ch = result[path_len - 1];
11523 if (ch != SEP && ch != ALTSEP && ch != L':')
11524 result[path_len++] = SEP;
11525 wcscpy(result + path_len, filename);
11526 }
11527 return result;
11528}
11529
11530static PyObject *
11531DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11532{
11533 DirEntry *entry;
11534 BY_HANDLE_FILE_INFORMATION file_info;
11535 ULONG reparse_tag;
11536 wchar_t *joined_path;
11537
11538 entry = PyObject_New(DirEntry, &DirEntryType);
11539 if (!entry)
11540 return NULL;
11541 entry->name = NULL;
11542 entry->path = NULL;
11543 entry->stat = NULL;
11544 entry->lstat = NULL;
11545 entry->got_file_index = 0;
11546
11547 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11548 if (!entry->name)
11549 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011550 if (path->narrow) {
11551 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11552 if (!entry->name)
11553 goto error;
11554 }
Victor Stinner6036e442015-03-08 01:58:04 +010011555
11556 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11557 if (!joined_path)
11558 goto error;
11559
11560 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11561 PyMem_Free(joined_path);
11562 if (!entry->path)
11563 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011564 if (path->narrow) {
11565 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11566 if (!entry->path)
11567 goto error;
11568 }
Victor Stinner6036e442015-03-08 01:58:04 +010011569
Steve Dowercc16be82016-09-08 10:35:16 -070011570 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011571 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11572
11573 return (PyObject *)entry;
11574
11575error:
11576 Py_DECREF(entry);
11577 return NULL;
11578}
11579
11580#else /* POSIX */
11581
11582static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011583join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011584{
11585 Py_ssize_t path_len;
11586 Py_ssize_t size;
11587 char *result;
11588
11589 if (!path_narrow) { /* Default arg: "." */
11590 path_narrow = ".";
11591 path_len = 1;
11592 }
11593 else {
11594 path_len = strlen(path_narrow);
11595 }
11596
11597 if (filename_len == -1)
11598 filename_len = strlen(filename);
11599
11600 /* The +1's are for the path separator and the NUL */
11601 size = path_len + 1 + filename_len + 1;
11602 result = PyMem_New(char, size);
11603 if (!result) {
11604 PyErr_NoMemory();
11605 return NULL;
11606 }
11607 strcpy(result, path_narrow);
11608 if (path_len > 0 && result[path_len - 1] != '/')
11609 result[path_len++] = '/';
11610 strcpy(result + path_len, filename);
11611 return result;
11612}
11613
11614static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011615DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011616 ino_t d_ino
11617#ifdef HAVE_DIRENT_D_TYPE
11618 , unsigned char d_type
11619#endif
11620 )
Victor Stinner6036e442015-03-08 01:58:04 +010011621{
11622 DirEntry *entry;
11623 char *joined_path;
11624
11625 entry = PyObject_New(DirEntry, &DirEntryType);
11626 if (!entry)
11627 return NULL;
11628 entry->name = NULL;
11629 entry->path = NULL;
11630 entry->stat = NULL;
11631 entry->lstat = NULL;
11632
11633 joined_path = join_path_filename(path->narrow, name, name_len);
11634 if (!joined_path)
11635 goto error;
11636
11637 if (!path->narrow || !PyBytes_Check(path->object)) {
11638 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11639 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11640 }
11641 else {
11642 entry->name = PyBytes_FromStringAndSize(name, name_len);
11643 entry->path = PyBytes_FromString(joined_path);
11644 }
11645 PyMem_Free(joined_path);
11646 if (!entry->name || !entry->path)
11647 goto error;
11648
Victor Stinner35a97c02015-03-08 02:59:09 +010011649#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011650 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011651#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011652 entry->d_ino = d_ino;
11653
11654 return (PyObject *)entry;
11655
11656error:
11657 Py_XDECREF(entry);
11658 return NULL;
11659}
11660
11661#endif
11662
11663
11664typedef struct {
11665 PyObject_HEAD
11666 path_t path;
11667#ifdef MS_WINDOWS
11668 HANDLE handle;
11669 WIN32_FIND_DATAW file_data;
11670 int first_time;
11671#else /* POSIX */
11672 DIR *dirp;
11673#endif
11674} ScandirIterator;
11675
11676#ifdef MS_WINDOWS
11677
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011678static int
11679ScandirIterator_is_closed(ScandirIterator *iterator)
11680{
11681 return iterator->handle == INVALID_HANDLE_VALUE;
11682}
11683
Victor Stinner6036e442015-03-08 01:58:04 +010011684static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011685ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011686{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011687 HANDLE handle = iterator->handle;
11688
11689 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011690 return;
11691
Victor Stinner6036e442015-03-08 01:58:04 +010011692 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011693 Py_BEGIN_ALLOW_THREADS
11694 FindClose(handle);
11695 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011696}
11697
11698static PyObject *
11699ScandirIterator_iternext(ScandirIterator *iterator)
11700{
11701 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11702 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011703 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011704
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011705 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011706 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011707 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011708
11709 while (1) {
11710 if (!iterator->first_time) {
11711 Py_BEGIN_ALLOW_THREADS
11712 success = FindNextFileW(iterator->handle, file_data);
11713 Py_END_ALLOW_THREADS
11714 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011715 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011716 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011717 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011718 break;
11719 }
11720 }
11721 iterator->first_time = 0;
11722
11723 /* Skip over . and .. */
11724 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011725 wcscmp(file_data->cFileName, L"..") != 0) {
11726 entry = DirEntry_from_find_data(&iterator->path, file_data);
11727 if (!entry)
11728 break;
11729 return entry;
11730 }
Victor Stinner6036e442015-03-08 01:58:04 +010011731
11732 /* Loop till we get a non-dot directory or finish iterating */
11733 }
11734
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011735 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011736 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011737 return NULL;
11738}
11739
11740#else /* POSIX */
11741
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011742static int
11743ScandirIterator_is_closed(ScandirIterator *iterator)
11744{
11745 return !iterator->dirp;
11746}
11747
Victor Stinner6036e442015-03-08 01:58:04 +010011748static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011749ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011750{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011751 DIR *dirp = iterator->dirp;
11752
11753 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011754 return;
11755
Victor Stinner6036e442015-03-08 01:58:04 +010011756 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011757 Py_BEGIN_ALLOW_THREADS
11758 closedir(dirp);
11759 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011760 return;
11761}
11762
11763static PyObject *
11764ScandirIterator_iternext(ScandirIterator *iterator)
11765{
11766 struct dirent *direntp;
11767 Py_ssize_t name_len;
11768 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011769 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011770
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011771 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011772 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011773 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011774
11775 while (1) {
11776 errno = 0;
11777 Py_BEGIN_ALLOW_THREADS
11778 direntp = readdir(iterator->dirp);
11779 Py_END_ALLOW_THREADS
11780
11781 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011782 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011783 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011784 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011785 break;
11786 }
11787
11788 /* Skip over . and .. */
11789 name_len = NAMLEN(direntp);
11790 is_dot = direntp->d_name[0] == '.' &&
11791 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11792 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011793 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011794 name_len, direntp->d_ino
11795#ifdef HAVE_DIRENT_D_TYPE
11796 , direntp->d_type
11797#endif
11798 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011799 if (!entry)
11800 break;
11801 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011802 }
11803
11804 /* Loop till we get a non-dot directory or finish iterating */
11805 }
11806
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011807 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011808 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011809 return NULL;
11810}
11811
11812#endif
11813
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011814static PyObject *
11815ScandirIterator_close(ScandirIterator *self, PyObject *args)
11816{
11817 ScandirIterator_closedir(self);
11818 Py_RETURN_NONE;
11819}
11820
11821static PyObject *
11822ScandirIterator_enter(PyObject *self, PyObject *args)
11823{
11824 Py_INCREF(self);
11825 return self;
11826}
11827
11828static PyObject *
11829ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11830{
11831 ScandirIterator_closedir(self);
11832 Py_RETURN_NONE;
11833}
11834
Victor Stinner6036e442015-03-08 01:58:04 +010011835static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011836ScandirIterator_finalize(ScandirIterator *iterator)
11837{
11838 PyObject *error_type, *error_value, *error_traceback;
11839
11840 /* Save the current exception, if any. */
11841 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11842
11843 if (!ScandirIterator_is_closed(iterator)) {
11844 ScandirIterator_closedir(iterator);
11845
11846 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11847 "unclosed scandir iterator %R", iterator)) {
11848 /* Spurious errors can appear at shutdown */
11849 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11850 PyErr_WriteUnraisable((PyObject *) iterator);
11851 }
11852 }
11853 }
11854
Victor Stinner7bfa4092016-03-23 00:43:54 +010011855 path_cleanup(&iterator->path);
11856
11857 /* Restore the saved exception. */
11858 PyErr_Restore(error_type, error_value, error_traceback);
11859}
11860
11861static void
Victor Stinner6036e442015-03-08 01:58:04 +010011862ScandirIterator_dealloc(ScandirIterator *iterator)
11863{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011864 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11865 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011866
Victor Stinner6036e442015-03-08 01:58:04 +010011867 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11868}
11869
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011870static PyMethodDef ScandirIterator_methods[] = {
11871 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11872 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11873 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11874 {NULL}
11875};
11876
Benjamin Peterson5646de42015-04-12 17:56:34 -040011877static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011878 PyVarObject_HEAD_INIT(NULL, 0)
11879 MODNAME ".ScandirIterator", /* tp_name */
11880 sizeof(ScandirIterator), /* tp_basicsize */
11881 0, /* tp_itemsize */
11882 /* methods */
11883 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11884 0, /* tp_print */
11885 0, /* tp_getattr */
11886 0, /* tp_setattr */
11887 0, /* tp_compare */
11888 0, /* tp_repr */
11889 0, /* tp_as_number */
11890 0, /* tp_as_sequence */
11891 0, /* tp_as_mapping */
11892 0, /* tp_hash */
11893 0, /* tp_call */
11894 0, /* tp_str */
11895 0, /* tp_getattro */
11896 0, /* tp_setattro */
11897 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011898 Py_TPFLAGS_DEFAULT
11899 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011900 0, /* tp_doc */
11901 0, /* tp_traverse */
11902 0, /* tp_clear */
11903 0, /* tp_richcompare */
11904 0, /* tp_weaklistoffset */
11905 PyObject_SelfIter, /* tp_iter */
11906 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011907 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011908 0, /* tp_members */
11909 0, /* tp_getset */
11910 0, /* tp_base */
11911 0, /* tp_dict */
11912 0, /* tp_descr_get */
11913 0, /* tp_descr_set */
11914 0, /* tp_dictoffset */
11915 0, /* tp_init */
11916 0, /* tp_alloc */
11917 0, /* tp_new */
11918 0, /* tp_free */
11919 0, /* tp_is_gc */
11920 0, /* tp_bases */
11921 0, /* tp_mro */
11922 0, /* tp_cache */
11923 0, /* tp_subclasses */
11924 0, /* tp_weaklist */
11925 0, /* tp_del */
11926 0, /* tp_version_tag */
11927 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011928};
11929
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011930/*[clinic input]
11931os.scandir
11932
11933 path : path_t(nullable=True) = None
11934
11935Return an iterator of DirEntry objects for given path.
11936
11937path can be specified as either str, bytes or path-like object. If path
11938is bytes, the names of yielded DirEntry objects will also be bytes; in
11939all other circumstances they will be str.
11940
11941If path is None, uses the path='.'.
11942[clinic start generated code]*/
11943
Victor Stinner6036e442015-03-08 01:58:04 +010011944static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011945os_scandir_impl(PyObject *module, path_t *path)
11946/*[clinic end generated code: output=6eb2668b675ca89e input=e62b08b3cd41f604]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011947{
11948 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010011949#ifdef MS_WINDOWS
11950 wchar_t *path_strW;
11951#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011952 const char *path_str;
Victor Stinner6036e442015-03-08 01:58:04 +010011953#endif
11954
11955 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11956 if (!iterator)
11957 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011958
11959#ifdef MS_WINDOWS
11960 iterator->handle = INVALID_HANDLE_VALUE;
11961#else
11962 iterator->dirp = NULL;
11963#endif
11964
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011965 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020011966 /* Move the ownership to iterator->path */
11967 path->object = NULL;
11968 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011969
11970#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011971 iterator->first_time = 1;
11972
11973 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11974 if (!path_strW)
11975 goto error;
11976
11977 Py_BEGIN_ALLOW_THREADS
11978 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11979 Py_END_ALLOW_THREADS
11980
11981 PyMem_Free(path_strW);
11982
11983 if (iterator->handle == INVALID_HANDLE_VALUE) {
11984 path_error(&iterator->path);
11985 goto error;
11986 }
11987#else /* POSIX */
11988 if (iterator->path.narrow)
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011989 path_str = iterator->path.narrow;
Victor Stinner6036e442015-03-08 01:58:04 +010011990 else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011991 path_str = ".";
Victor Stinner6036e442015-03-08 01:58:04 +010011992
11993 errno = 0;
11994 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011995 iterator->dirp = opendir(path_str);
Victor Stinner6036e442015-03-08 01:58:04 +010011996 Py_END_ALLOW_THREADS
11997
11998 if (!iterator->dirp) {
11999 path_error(&iterator->path);
12000 goto error;
12001 }
12002#endif
12003
12004 return (PyObject *)iterator;
12005
12006error:
12007 Py_DECREF(iterator);
12008 return NULL;
12009}
12010
Ethan Furman410ef8e2016-06-04 12:06:26 -070012011/*
12012 Return the file system path representation of the object.
12013
12014 If the object is str or bytes, then allow it to pass through with
12015 an incremented refcount. If the object defines __fspath__(), then
12016 return the result of that method. All other types raise a TypeError.
12017*/
12018PyObject *
12019PyOS_FSPath(PyObject *path)
12020{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012021 /* For error message reasons, this function is manually inlined in
12022 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012023 _Py_IDENTIFIER(__fspath__);
12024 PyObject *func = NULL;
12025 PyObject *path_repr = NULL;
12026
12027 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12028 Py_INCREF(path);
12029 return path;
12030 }
12031
12032 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12033 if (NULL == func) {
12034 return PyErr_Format(PyExc_TypeError,
12035 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012036 "not %.200s",
12037 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012038 }
12039
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012040 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012041 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012042 if (NULL == path_repr) {
12043 return NULL;
12044 }
12045
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012046 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12047 PyErr_Format(PyExc_TypeError,
12048 "expected %.200s.__fspath__() to return str or bytes, "
12049 "not %.200s", Py_TYPE(path)->tp_name,
12050 Py_TYPE(path_repr)->tp_name);
12051 Py_DECREF(path_repr);
12052 return NULL;
12053 }
12054
Ethan Furman410ef8e2016-06-04 12:06:26 -070012055 return path_repr;
12056}
12057
12058/*[clinic input]
12059os.fspath
12060
12061 path: object
12062
12063Return the file system path representation of the object.
12064
Brett Cannonb4f43e92016-06-09 14:32:08 -070012065If the object is str or bytes, then allow it to pass through as-is. If the
12066object defines __fspath__(), then return the result of that method. All other
12067types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012068[clinic start generated code]*/
12069
12070static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012071os_fspath_impl(PyObject *module, PyObject *path)
12072/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012073{
12074 return PyOS_FSPath(path);
12075}
Victor Stinner6036e442015-03-08 01:58:04 +010012076
Victor Stinner9b1f4742016-09-06 16:18:52 -070012077#ifdef HAVE_GETRANDOM_SYSCALL
12078/*[clinic input]
12079os.getrandom
12080
12081 size: Py_ssize_t
12082 flags: int=0
12083
12084Obtain a series of random bytes.
12085[clinic start generated code]*/
12086
12087static PyObject *
12088os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12089/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12090{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012091 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012092 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012093
12094 if (size < 0) {
12095 errno = EINVAL;
12096 return posix_error();
12097 }
12098
Victor Stinnerec2319c2016-09-20 23:00:59 +020012099 bytes = PyBytes_FromStringAndSize(NULL, size);
12100 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012101 PyErr_NoMemory();
12102 return NULL;
12103 }
12104
12105 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012106 n = syscall(SYS_getrandom,
12107 PyBytes_AS_STRING(bytes),
12108 PyBytes_GET_SIZE(bytes),
12109 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012110 if (n < 0 && errno == EINTR) {
12111 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012112 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012113 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012114
12115 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012116 continue;
12117 }
12118 break;
12119 }
12120
12121 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012122 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012123 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012124 }
12125
Victor Stinnerec2319c2016-09-20 23:00:59 +020012126 if (n != size) {
12127 _PyBytes_Resize(&bytes, n);
12128 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012129
12130 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012131
12132error:
12133 Py_DECREF(bytes);
12134 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012135}
12136#endif /* HAVE_GETRANDOM_SYSCALL */
12137
Larry Hastings31826802013-10-19 00:09:25 -070012138
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012139static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012140
12141 OS_STAT_METHODDEF
12142 OS_ACCESS_METHODDEF
12143 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012144 OS_CHDIR_METHODDEF
12145 OS_CHFLAGS_METHODDEF
12146 OS_CHMOD_METHODDEF
12147 OS_FCHMOD_METHODDEF
12148 OS_LCHMOD_METHODDEF
12149 OS_CHOWN_METHODDEF
12150 OS_FCHOWN_METHODDEF
12151 OS_LCHOWN_METHODDEF
12152 OS_LCHFLAGS_METHODDEF
12153 OS_CHROOT_METHODDEF
12154 OS_CTERMID_METHODDEF
12155 OS_GETCWD_METHODDEF
12156 OS_GETCWDB_METHODDEF
12157 OS_LINK_METHODDEF
12158 OS_LISTDIR_METHODDEF
12159 OS_LSTAT_METHODDEF
12160 OS_MKDIR_METHODDEF
12161 OS_NICE_METHODDEF
12162 OS_GETPRIORITY_METHODDEF
12163 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012164#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012165 {"readlink", (PyCFunction)posix_readlink,
12166 METH_VARARGS | METH_KEYWORDS,
12167 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012168#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012169#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012170 {"readlink", (PyCFunction)win_readlink,
12171 METH_VARARGS | METH_KEYWORDS,
12172 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012173#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012174 OS_RENAME_METHODDEF
12175 OS_REPLACE_METHODDEF
12176 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012177 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012178 OS_SYMLINK_METHODDEF
12179 OS_SYSTEM_METHODDEF
12180 OS_UMASK_METHODDEF
12181 OS_UNAME_METHODDEF
12182 OS_UNLINK_METHODDEF
12183 OS_REMOVE_METHODDEF
12184 OS_UTIME_METHODDEF
12185 OS_TIMES_METHODDEF
12186 OS__EXIT_METHODDEF
12187 OS_EXECV_METHODDEF
12188 OS_EXECVE_METHODDEF
12189 OS_SPAWNV_METHODDEF
12190 OS_SPAWNVE_METHODDEF
12191 OS_FORK1_METHODDEF
12192 OS_FORK_METHODDEF
12193 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12194 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12195 OS_SCHED_GETPARAM_METHODDEF
12196 OS_SCHED_GETSCHEDULER_METHODDEF
12197 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12198 OS_SCHED_SETPARAM_METHODDEF
12199 OS_SCHED_SETSCHEDULER_METHODDEF
12200 OS_SCHED_YIELD_METHODDEF
12201 OS_SCHED_SETAFFINITY_METHODDEF
12202 OS_SCHED_GETAFFINITY_METHODDEF
12203 OS_OPENPTY_METHODDEF
12204 OS_FORKPTY_METHODDEF
12205 OS_GETEGID_METHODDEF
12206 OS_GETEUID_METHODDEF
12207 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012208#ifdef HAVE_GETGROUPLIST
12209 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12210#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012211 OS_GETGROUPS_METHODDEF
12212 OS_GETPID_METHODDEF
12213 OS_GETPGRP_METHODDEF
12214 OS_GETPPID_METHODDEF
12215 OS_GETUID_METHODDEF
12216 OS_GETLOGIN_METHODDEF
12217 OS_KILL_METHODDEF
12218 OS_KILLPG_METHODDEF
12219 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012220#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012221 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012222#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012223 OS_SETUID_METHODDEF
12224 OS_SETEUID_METHODDEF
12225 OS_SETREUID_METHODDEF
12226 OS_SETGID_METHODDEF
12227 OS_SETEGID_METHODDEF
12228 OS_SETREGID_METHODDEF
12229 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012230#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012231 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012232#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012233 OS_GETPGID_METHODDEF
12234 OS_SETPGRP_METHODDEF
12235 OS_WAIT_METHODDEF
12236 OS_WAIT3_METHODDEF
12237 OS_WAIT4_METHODDEF
12238 OS_WAITID_METHODDEF
12239 OS_WAITPID_METHODDEF
12240 OS_GETSID_METHODDEF
12241 OS_SETSID_METHODDEF
12242 OS_SETPGID_METHODDEF
12243 OS_TCGETPGRP_METHODDEF
12244 OS_TCSETPGRP_METHODDEF
12245 OS_OPEN_METHODDEF
12246 OS_CLOSE_METHODDEF
12247 OS_CLOSERANGE_METHODDEF
12248 OS_DEVICE_ENCODING_METHODDEF
12249 OS_DUP_METHODDEF
12250 OS_DUP2_METHODDEF
12251 OS_LOCKF_METHODDEF
12252 OS_LSEEK_METHODDEF
12253 OS_READ_METHODDEF
12254 OS_READV_METHODDEF
12255 OS_PREAD_METHODDEF
12256 OS_WRITE_METHODDEF
12257 OS_WRITEV_METHODDEF
12258 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012259#ifdef HAVE_SENDFILE
12260 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12261 posix_sendfile__doc__},
12262#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012263 OS_FSTAT_METHODDEF
12264 OS_ISATTY_METHODDEF
12265 OS_PIPE_METHODDEF
12266 OS_PIPE2_METHODDEF
12267 OS_MKFIFO_METHODDEF
12268 OS_MKNOD_METHODDEF
12269 OS_MAJOR_METHODDEF
12270 OS_MINOR_METHODDEF
12271 OS_MAKEDEV_METHODDEF
12272 OS_FTRUNCATE_METHODDEF
12273 OS_TRUNCATE_METHODDEF
12274 OS_POSIX_FALLOCATE_METHODDEF
12275 OS_POSIX_FADVISE_METHODDEF
12276 OS_PUTENV_METHODDEF
12277 OS_UNSETENV_METHODDEF
12278 OS_STRERROR_METHODDEF
12279 OS_FCHDIR_METHODDEF
12280 OS_FSYNC_METHODDEF
12281 OS_SYNC_METHODDEF
12282 OS_FDATASYNC_METHODDEF
12283 OS_WCOREDUMP_METHODDEF
12284 OS_WIFCONTINUED_METHODDEF
12285 OS_WIFSTOPPED_METHODDEF
12286 OS_WIFSIGNALED_METHODDEF
12287 OS_WIFEXITED_METHODDEF
12288 OS_WEXITSTATUS_METHODDEF
12289 OS_WTERMSIG_METHODDEF
12290 OS_WSTOPSIG_METHODDEF
12291 OS_FSTATVFS_METHODDEF
12292 OS_STATVFS_METHODDEF
12293 OS_CONFSTR_METHODDEF
12294 OS_SYSCONF_METHODDEF
12295 OS_FPATHCONF_METHODDEF
12296 OS_PATHCONF_METHODDEF
12297 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012298 OS__GETFULLPATHNAME_METHODDEF
12299 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012300 OS__GETDISKUSAGE_METHODDEF
12301 OS__GETFINALPATHNAME_METHODDEF
12302 OS__GETVOLUMEPATHNAME_METHODDEF
12303 OS_GETLOADAVG_METHODDEF
12304 OS_URANDOM_METHODDEF
12305 OS_SETRESUID_METHODDEF
12306 OS_SETRESGID_METHODDEF
12307 OS_GETRESUID_METHODDEF
12308 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012309
Larry Hastings2f936352014-08-05 14:04:04 +100012310 OS_GETXATTR_METHODDEF
12311 OS_SETXATTR_METHODDEF
12312 OS_REMOVEXATTR_METHODDEF
12313 OS_LISTXATTR_METHODDEF
12314
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012315#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12316 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12317#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012318 OS_CPU_COUNT_METHODDEF
12319 OS_GET_INHERITABLE_METHODDEF
12320 OS_SET_INHERITABLE_METHODDEF
12321 OS_GET_HANDLE_INHERITABLE_METHODDEF
12322 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012323#ifndef MS_WINDOWS
12324 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12325 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12326#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012327 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012328 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012329 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012330 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012331};
12332
12333
Brian Curtin52173d42010-12-02 18:29:18 +000012334#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012335static int
Brian Curtin52173d42010-12-02 18:29:18 +000012336enable_symlink()
12337{
12338 HANDLE tok;
12339 TOKEN_PRIVILEGES tok_priv;
12340 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012341
12342 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012343 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012344
12345 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012346 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012347
12348 tok_priv.PrivilegeCount = 1;
12349 tok_priv.Privileges[0].Luid = luid;
12350 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12351
12352 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12353 sizeof(TOKEN_PRIVILEGES),
12354 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012355 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012356
Brian Curtin3b4499c2010-12-28 14:31:47 +000012357 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12358 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012359}
12360#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12361
Barry Warsaw4a342091996-12-19 23:50:02 +000012362static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012363all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012364{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012365#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012366 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012367#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012368#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012369 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012370#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012371#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012372 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012373#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012374#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012375 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012376#endif
Fred Drakec9680921999-12-13 16:37:25 +000012377#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012378 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012379#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012380#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012381 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012382#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012383#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012384 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012385#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012386#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012387 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012388#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012389#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012390 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012391#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012392#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012393 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012394#endif
12395#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012396 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012397#endif
12398#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012399 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012400#endif
12401#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012402 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012403#endif
12404#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012405 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012406#endif
12407#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012408 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012409#endif
12410#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012411 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012412#endif
12413#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012414 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012415#endif
12416#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012417 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012418#endif
12419#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012420 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012421#endif
12422#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012423 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012424#endif
12425#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012426 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012427#endif
12428#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012429 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012430#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012431#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012433#endif
12434#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012435 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012436#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012437#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012438 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012439#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012440#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012441 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012442#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012443#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012444#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012445 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012446#endif
12447#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012449#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012450#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012451#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012452 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012453#endif
12454#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012456#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012457#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012459#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012460#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012462#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012463#ifdef O_TMPFILE
12464 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12465#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012466#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012468#endif
12469#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012470 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012471#endif
12472#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012473 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012474#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012475#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012476 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012477#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012478#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012480#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012481
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012482
Jesus Cea94363612012-06-22 18:32:07 +020012483#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012484 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012485#endif
12486#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012487 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012488#endif
12489
Tim Peters5aa91602002-01-30 05:46:57 +000012490/* MS Windows */
12491#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012492 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012493 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012494#endif
12495#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012496 /* Optimize for short life (keep in memory). */
12497 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012498 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012499#endif
12500#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012501 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012502 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012503#endif
12504#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012505 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012507#endif
12508#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012509 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012510 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012511#endif
12512
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012513/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012514#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012515 /* Send a SIGIO signal whenever input or output
12516 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012517 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012518#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012519#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012520 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012522#endif
12523#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012524 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012525 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012526#endif
12527#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012528 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012530#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012531#ifdef O_NOLINKS
12532 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012533 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012534#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012535#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012536 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012537 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012538#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012539
Victor Stinner8c62be82010-05-06 00:08:46 +000012540 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012541#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012542 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012543#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012544#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012545 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012546#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012547#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012548 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012549#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012550#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012551 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012552#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012553#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012555#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012556#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012557 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012558#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012559#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012560 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012561#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012562#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012563 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012564#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012565#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012567#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012568#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012569 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012570#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012571#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012573#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012574#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012576#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012577#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012578 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012579#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012580#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012581 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012582#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012583#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012584 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012585#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012586#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012587 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012588#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012589#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012591#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012592
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012593 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012594#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012595 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012596#endif /* ST_RDONLY */
12597#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012599#endif /* ST_NOSUID */
12600
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012601 /* GNU extensions */
12602#ifdef ST_NODEV
12603 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12604#endif /* ST_NODEV */
12605#ifdef ST_NOEXEC
12606 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12607#endif /* ST_NOEXEC */
12608#ifdef ST_SYNCHRONOUS
12609 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12610#endif /* ST_SYNCHRONOUS */
12611#ifdef ST_MANDLOCK
12612 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12613#endif /* ST_MANDLOCK */
12614#ifdef ST_WRITE
12615 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12616#endif /* ST_WRITE */
12617#ifdef ST_APPEND
12618 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12619#endif /* ST_APPEND */
12620#ifdef ST_NOATIME
12621 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12622#endif /* ST_NOATIME */
12623#ifdef ST_NODIRATIME
12624 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12625#endif /* ST_NODIRATIME */
12626#ifdef ST_RELATIME
12627 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12628#endif /* ST_RELATIME */
12629
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012630 /* FreeBSD sendfile() constants */
12631#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012633#endif
12634#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012636#endif
12637#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012639#endif
12640
Ross Lagerwall7807c352011-03-17 20:20:30 +020012641 /* constants for posix_fadvise */
12642#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012644#endif
12645#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012647#endif
12648#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012649 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012650#endif
12651#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012653#endif
12654#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012656#endif
12657#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012659#endif
12660
12661 /* constants for waitid */
12662#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012663 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12664 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12665 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012666#endif
12667#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012669#endif
12670#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012672#endif
12673#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012675#endif
12676#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012678#endif
12679#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012681#endif
12682#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684#endif
12685#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688
12689 /* constants for lockf */
12690#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012692#endif
12693#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012695#endif
12696#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012698#endif
12699#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012701#endif
12702
Guido van Rossum246bc171999-02-01 23:54:31 +000012703#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12705 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12706 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12707 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12708 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012709#endif
12710
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012711#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012712#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012714#endif
12715#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012717#endif
12718#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012719 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012720#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012721#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012722 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012723#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012724#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012726#endif
12727#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012729#endif
12730#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012732#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012733#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012735#endif
12736#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012738#endif
12739#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012741#endif
12742#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012744#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012745#endif
12746
Benjamin Peterson9428d532011-09-14 11:45:52 -040012747#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012748 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12749 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12750 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012751#endif
12752
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012753#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012754 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012755#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012756#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012758#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012759#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012761#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012762#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012764#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012765#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012767#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012768#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012770#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012771#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012773#endif
12774
Victor Stinner9b1f4742016-09-06 16:18:52 -070012775#ifdef HAVE_GETRANDOM_SYSCALL
12776 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12777 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12778#endif
12779
Victor Stinner8c62be82010-05-06 00:08:46 +000012780 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012781}
12782
12783
Martin v. Löwis1a214512008-06-11 05:26:20 +000012784static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012785 PyModuleDef_HEAD_INIT,
12786 MODNAME,
12787 posix__doc__,
12788 -1,
12789 posix_methods,
12790 NULL,
12791 NULL,
12792 NULL,
12793 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012794};
12795
12796
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012797static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012798
12799#ifdef HAVE_FACCESSAT
12800 "HAVE_FACCESSAT",
12801#endif
12802
12803#ifdef HAVE_FCHDIR
12804 "HAVE_FCHDIR",
12805#endif
12806
12807#ifdef HAVE_FCHMOD
12808 "HAVE_FCHMOD",
12809#endif
12810
12811#ifdef HAVE_FCHMODAT
12812 "HAVE_FCHMODAT",
12813#endif
12814
12815#ifdef HAVE_FCHOWN
12816 "HAVE_FCHOWN",
12817#endif
12818
Larry Hastings00964ed2013-08-12 13:49:30 -040012819#ifdef HAVE_FCHOWNAT
12820 "HAVE_FCHOWNAT",
12821#endif
12822
Larry Hastings9cf065c2012-06-22 16:30:09 -070012823#ifdef HAVE_FEXECVE
12824 "HAVE_FEXECVE",
12825#endif
12826
12827#ifdef HAVE_FDOPENDIR
12828 "HAVE_FDOPENDIR",
12829#endif
12830
Georg Brandl306336b2012-06-24 12:55:33 +020012831#ifdef HAVE_FPATHCONF
12832 "HAVE_FPATHCONF",
12833#endif
12834
Larry Hastings9cf065c2012-06-22 16:30:09 -070012835#ifdef HAVE_FSTATAT
12836 "HAVE_FSTATAT",
12837#endif
12838
12839#ifdef HAVE_FSTATVFS
12840 "HAVE_FSTATVFS",
12841#endif
12842
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012843#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012844 "HAVE_FTRUNCATE",
12845#endif
12846
Larry Hastings9cf065c2012-06-22 16:30:09 -070012847#ifdef HAVE_FUTIMENS
12848 "HAVE_FUTIMENS",
12849#endif
12850
12851#ifdef HAVE_FUTIMES
12852 "HAVE_FUTIMES",
12853#endif
12854
12855#ifdef HAVE_FUTIMESAT
12856 "HAVE_FUTIMESAT",
12857#endif
12858
12859#ifdef HAVE_LINKAT
12860 "HAVE_LINKAT",
12861#endif
12862
12863#ifdef HAVE_LCHFLAGS
12864 "HAVE_LCHFLAGS",
12865#endif
12866
12867#ifdef HAVE_LCHMOD
12868 "HAVE_LCHMOD",
12869#endif
12870
12871#ifdef HAVE_LCHOWN
12872 "HAVE_LCHOWN",
12873#endif
12874
12875#ifdef HAVE_LSTAT
12876 "HAVE_LSTAT",
12877#endif
12878
12879#ifdef HAVE_LUTIMES
12880 "HAVE_LUTIMES",
12881#endif
12882
12883#ifdef HAVE_MKDIRAT
12884 "HAVE_MKDIRAT",
12885#endif
12886
12887#ifdef HAVE_MKFIFOAT
12888 "HAVE_MKFIFOAT",
12889#endif
12890
12891#ifdef HAVE_MKNODAT
12892 "HAVE_MKNODAT",
12893#endif
12894
12895#ifdef HAVE_OPENAT
12896 "HAVE_OPENAT",
12897#endif
12898
12899#ifdef HAVE_READLINKAT
12900 "HAVE_READLINKAT",
12901#endif
12902
12903#ifdef HAVE_RENAMEAT
12904 "HAVE_RENAMEAT",
12905#endif
12906
12907#ifdef HAVE_SYMLINKAT
12908 "HAVE_SYMLINKAT",
12909#endif
12910
12911#ifdef HAVE_UNLINKAT
12912 "HAVE_UNLINKAT",
12913#endif
12914
12915#ifdef HAVE_UTIMENSAT
12916 "HAVE_UTIMENSAT",
12917#endif
12918
12919#ifdef MS_WINDOWS
12920 "MS_WINDOWS",
12921#endif
12922
12923 NULL
12924};
12925
12926
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012927PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012928INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012929{
Victor Stinner8c62be82010-05-06 00:08:46 +000012930 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012931 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012932 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012933
Brian Curtin52173d42010-12-02 18:29:18 +000012934#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012935 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012936#endif
12937
Victor Stinner8c62be82010-05-06 00:08:46 +000012938 m = PyModule_Create(&posixmodule);
12939 if (m == NULL)
12940 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012941
Victor Stinner8c62be82010-05-06 00:08:46 +000012942 /* Initialize environ dictionary */
12943 v = convertenviron();
12944 Py_XINCREF(v);
12945 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12946 return NULL;
12947 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012948
Victor Stinner8c62be82010-05-06 00:08:46 +000012949 if (all_ins(m))
12950 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012951
Victor Stinner8c62be82010-05-06 00:08:46 +000012952 if (setup_confname_tables(m))
12953 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012954
Victor Stinner8c62be82010-05-06 00:08:46 +000012955 Py_INCREF(PyExc_OSError);
12956 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012957
Guido van Rossumb3d39562000-01-31 18:41:26 +000012958#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012959 if (posix_putenv_garbage == NULL)
12960 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012961#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012962
Victor Stinner8c62be82010-05-06 00:08:46 +000012963 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012964#if defined(HAVE_WAITID) && !defined(__APPLE__)
12965 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012966 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12967 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012968#endif
12969
Christian Heimes25827622013-10-12 01:27:08 +020012970 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012971 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12972 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12973 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012974 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12975 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 structseq_new = StatResultType.tp_new;
12977 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012978
Christian Heimes25827622013-10-12 01:27:08 +020012979 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012980 if (PyStructSequence_InitType2(&StatVFSResultType,
12981 &statvfs_result_desc) < 0)
12982 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012983#ifdef NEED_TICKS_PER_SECOND
12984# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012985 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012986# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012987 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012988# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012990# endif
12991#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012992
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012993#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012994 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012995 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12996 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012997 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012998#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012999
13000 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013001 if (PyStructSequence_InitType2(&TerminalSizeType,
13002 &TerminalSize_desc) < 0)
13003 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013004
13005 /* initialize scandir types */
13006 if (PyType_Ready(&ScandirIteratorType) < 0)
13007 return NULL;
13008 if (PyType_Ready(&DirEntryType) < 0)
13009 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013010 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013011#if defined(HAVE_WAITID) && !defined(__APPLE__)
13012 Py_INCREF((PyObject*) &WaitidResultType);
13013 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13014#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013015 Py_INCREF((PyObject*) &StatResultType);
13016 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13017 Py_INCREF((PyObject*) &StatVFSResultType);
13018 PyModule_AddObject(m, "statvfs_result",
13019 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013020
13021#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013022 Py_INCREF(&SchedParamType);
13023 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013024#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013025
Larry Hastings605a62d2012-06-24 04:33:36 -070013026 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013027 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13028 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013029 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13030
13031 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013032 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13033 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013034 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13035
Thomas Wouters477c8d52006-05-27 19:21:47 +000013036#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013037 /*
13038 * Step 2 of weak-linking support on Mac OS X.
13039 *
13040 * The code below removes functions that are not available on the
13041 * currently active platform.
13042 *
13043 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013044 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013045 * OSX 10.4.
13046 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013047#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013048 if (fstatvfs == NULL) {
13049 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13050 return NULL;
13051 }
13052 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013053#endif /* HAVE_FSTATVFS */
13054
13055#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013056 if (statvfs == NULL) {
13057 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13058 return NULL;
13059 }
13060 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013061#endif /* HAVE_STATVFS */
13062
13063# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013064 if (lchown == NULL) {
13065 if (PyObject_DelAttrString(m, "lchown") == -1) {
13066 return NULL;
13067 }
13068 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013069#endif /* HAVE_LCHOWN */
13070
13071
13072#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013073
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013074 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013075 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13076
Larry Hastings6fe20b32012-04-19 15:07:49 -070013077 billion = PyLong_FromLong(1000000000);
13078 if (!billion)
13079 return NULL;
13080
Larry Hastings9cf065c2012-06-22 16:30:09 -070013081 /* suppress "function not used" warnings */
13082 {
13083 int ignored;
13084 fd_specified("", -1);
13085 follow_symlinks_specified("", 1);
13086 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13087 dir_fd_converter(Py_None, &ignored);
13088 dir_fd_unavailable(Py_None, &ignored);
13089 }
13090
13091 /*
13092 * provide list of locally available functions
13093 * so os.py can populate support_* lists
13094 */
13095 list = PyList_New(0);
13096 if (!list)
13097 return NULL;
13098 for (trace = have_functions; *trace; trace++) {
13099 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13100 if (!unicode)
13101 return NULL;
13102 if (PyList_Append(list, unicode))
13103 return NULL;
13104 Py_DECREF(unicode);
13105 }
13106 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013107
13108 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013109 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013110
13111 initialized = 1;
13112
Victor Stinner8c62be82010-05-06 00:08:46 +000013113 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013114}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013115
13116#ifdef __cplusplus
13117}
13118#endif