blob: fb879e3821aa683afd1de6e61ef75dafb16f84a8 [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"
Antoine Pitrou346cbd32017-05-27 17:50:54 +020028#include "pythread.h"
Victor Stinner6036e442015-03-08 01:58:04 +010029#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020030#ifndef MS_WINDOWS
31#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010032#else
33#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020034#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000035
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020036/* On android API level 21, 'AT_EACCESS' is not declared although
37 * HAVE_FACCESSAT is defined. */
38#ifdef __ANDROID__
39#undef HAVE_FACCESSAT
40#endif
41
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000042#include <stdio.h> /* needed for ctermid() */
43
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000044#ifdef __cplusplus
45extern "C" {
46#endif
47
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000048PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000049"This module provides access to operating system functionality that is\n\
50standardized by the C Standard and the POSIX standard (a thinly\n\
51disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000052corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000054
Ross Lagerwall4d076da2011-03-18 06:56:53 +020055#ifdef HAVE_SYS_UIO_H
56#include <sys/uio.h>
57#endif
58
Christian Heimes75b96182017-09-05 15:53:09 +020059#ifdef HAVE_SYS_SYSMACROS_H
60/* GNU C Library: major(), minor(), makedev() */
61#include <sys/sysmacros.h>
62#endif
63
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000065#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif /* HAVE_SYS_TYPES_H */
67
68#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000069#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000071
Guido van Rossum36bc6801995-06-14 22:54:23 +000072#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000073#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000075
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000077#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000079
Guido van Rossumb6775db1994-08-01 11:34:53 +000080#ifdef HAVE_FCNTL_H
81#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000082#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000083
Guido van Rossuma6535fd2001-10-18 19:44:10 +000084#ifdef HAVE_GRP_H
85#include <grp.h>
86#endif
87
Barry Warsaw5676bd12003-01-07 20:57:09 +000088#ifdef HAVE_SYSEXITS_H
89#include <sysexits.h>
90#endif /* HAVE_SYSEXITS_H */
91
Anthony Baxter8a560de2004-10-13 15:30:56 +000092#ifdef HAVE_SYS_LOADAVG_H
93#include <sys/loadavg.h>
94#endif
95
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000096#ifdef HAVE_SYS_SENDFILE_H
97#include <sys/sendfile.h>
98#endif
99
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500100#ifdef HAVE_SCHED_H
101#include <sched.h>
102#endif
103
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500104#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500105#undef HAVE_SCHED_SETAFFINITY
106#endif
107
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200108#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400109#define USE_XATTRS
110#endif
111
112#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400113#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400114#endif
115
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000116#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
117#ifdef HAVE_SYS_SOCKET_H
118#include <sys/socket.h>
119#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000120#endif
121
Victor Stinner8b905bd2011-10-25 13:34:04 +0200122#ifdef HAVE_DLFCN_H
123#include <dlfcn.h>
124#endif
125
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200126#ifdef __hpux
127#include <sys/mpctl.h>
128#endif
129
130#if defined(__DragonFly__) || \
131 defined(__OpenBSD__) || \
132 defined(__FreeBSD__) || \
133 defined(__NetBSD__) || \
134 defined(__APPLE__)
135#include <sys/sysctl.h>
136#endif
137
Victor Stinner9b1f4742016-09-06 16:18:52 -0700138#ifdef HAVE_LINUX_RANDOM_H
139# include <linux/random.h>
140#endif
141#ifdef HAVE_GETRANDOM_SYSCALL
142# include <sys/syscall.h>
143#endif
144
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100145#if defined(MS_WINDOWS)
146# define TERMSIZE_USE_CONIO
147#elif defined(HAVE_SYS_IOCTL_H)
148# include <sys/ioctl.h>
149# if defined(HAVE_TERMIOS_H)
150# include <termios.h>
151# endif
152# if defined(TIOCGWINSZ)
153# define TERMSIZE_USE_IOCTL
154# endif
155#endif /* MS_WINDOWS */
156
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000158/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#include <process.h>
163#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000165#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000166#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700169#define HAVE_WSPAWNV 1
170#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SYSTEM 1
173#define HAVE_CWAIT 1
174#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000175#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000176#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177/* Unix functions that the configure script doesn't check for */
178#define HAVE_EXECV 1
179#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000181#define HAVE_FORK1 1
182#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#define HAVE_GETEGID 1
184#define HAVE_GETEUID 1
185#define HAVE_GETGID 1
186#define HAVE_GETPPID 1
187#define HAVE_GETUID 1
188#define HAVE_KILL 1
189#define HAVE_OPENDIR 1
190#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000193#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000194#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000195#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000196
Victor Stinnera2f7c002012-02-08 03:36:25 +0100197
Larry Hastings61272b72014-01-07 12:41:53 -0800198/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000199# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800200module os
Larry Hastings61272b72014-01-07 12:41:53 -0800201[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000202/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100203
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000205
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000206#if defined(__sgi)&&_COMPILER_VERSION>=700
207/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
208 (default) */
209extern char *ctermid_r(char *);
210#endif
211
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000212#ifndef HAVE_UNISTD_H
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000213#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000216extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chdir(char *);
220extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int chdir(const char *);
223extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000224#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000226/*#ifdef HAVE_FCHMOD
227extern int fchmod(int, mode_t);
228#endif*/
229/*#ifdef HAVE_LCHMOD
230extern int lchmod(const char *, mode_t);
231#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000232extern int chown(const char *, uid_t, gid_t);
233extern char *getcwd(char *, int);
234extern char *strerror(int);
235extern int link(const char *, const char *);
236extern int rename(const char *, const char *);
237extern int stat(const char *, struct stat *);
238extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000241#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000243extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000246
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000247#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#ifdef HAVE_UTIME_H
250#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000251#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000253#ifdef HAVE_SYS_UTIME_H
254#include <sys/utime.h>
255#define HAVE_UTIME_H /* pretend we do for the rest of this file */
256#endif /* HAVE_SYS_UTIME_H */
257
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#ifdef HAVE_SYS_TIMES_H
259#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000260#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261
262#ifdef HAVE_SYS_PARAM_H
263#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
266#ifdef HAVE_SYS_UTSNAME_H
267#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000268#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) strlen((dirent)->d_name)
273#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000274#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#include <direct.h>
276#define NAMLEN(dirent) strlen((dirent)->d_name)
277#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000280#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#endif
287#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000289#endif
290#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000292#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
296#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298#endif
299#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000301#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000302#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
305#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000306#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000307#endif
308#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000309#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000310#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100311#ifndef IO_REPARSE_TAG_MOUNT_POINT
312#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
313#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000315#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000316#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000317#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000318#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000319#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
320#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000321static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000322#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000323#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000324
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000326#if defined(PATH_MAX) && PATH_MAX > 1024
327#define MAXPATHLEN PATH_MAX
328#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#endif /* MAXPATHLEN */
332
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000333#ifdef UNION_WAIT
334/* Emulate some macros on systems that have a union instead of macros */
335
336#ifndef WIFEXITED
337#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
338#endif
339
340#ifndef WEXITSTATUS
341#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
342#endif
343
344#ifndef WTERMSIG
345#define WTERMSIG(u_wait) ((u_wait).w_termsig)
346#endif
347
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000348#define WAIT_TYPE union wait
349#define WAIT_STATUS_INT(s) (s.w_status)
350
351#else /* !UNION_WAIT */
352#define WAIT_TYPE int
353#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000354#endif /* UNION_WAIT */
355
Greg Wardb48bc172000-03-01 21:51:56 +0000356/* Don't use the "_r" form if we don't need it (also, won't have a
357 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200358#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000359#define USE_CTERMID_R
360#endif
361
Fred Drake699f3522000-06-29 21:12:41 +0000362/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000363#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000364#undef FSTAT
365#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200366#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700368# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200369# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800370# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000371#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000372# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700373# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define FSTAT fstat
375# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000376#endif
377
Tim Peters11b23062003-04-23 02:39:17 +0000378#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000379#include <sys/mkdev.h>
380#else
381#if defined(MAJOR_IN_SYSMACROS)
382#include <sys/sysmacros.h>
383#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000384#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
385#include <sys/mkdev.h>
386#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000387#endif
Fred Drake699f3522000-06-29 21:12:41 +0000388
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
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200397
398#ifdef HAVE_FORK
399static void
400run_at_forkers(PyObject *lst, int reverse)
401{
402 Py_ssize_t i;
403 PyObject *cpy;
404
405 if (lst != NULL) {
406 assert(PyList_CheckExact(lst));
407
408 /* Use a list copy in case register_at_fork() is called from
409 * one of the callbacks.
410 */
411 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
412 if (cpy == NULL)
413 PyErr_WriteUnraisable(lst);
414 else {
415 if (reverse)
416 PyList_Reverse(cpy);
417 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
418 PyObject *func, *res;
419 func = PyList_GET_ITEM(cpy, i);
420 res = PyObject_CallObject(func, NULL);
421 if (res == NULL)
422 PyErr_WriteUnraisable(func);
423 else
424 Py_DECREF(res);
425 }
426 Py_DECREF(cpy);
427 }
428 }
429}
430
431void
432PyOS_BeforeFork(void)
433{
434 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
435
436 _PyImport_AcquireLock();
437}
438
439void
440PyOS_AfterFork_Parent(void)
441{
442 if (_PyImport_ReleaseLock() <= 0)
443 Py_FatalError("failed releasing import lock after fork");
444
445 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
446}
447
448void
449PyOS_AfterFork_Child(void)
450{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200451 _PyGILState_Reinit();
452 PyEval_ReInitThreads();
453 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200454 _PySignal_AfterFork();
455
456 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
457}
458
459static int
460register_at_forker(PyObject **lst, PyObject *func)
461{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700462 if (func == NULL) /* nothing to register? do nothing. */
463 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200464 if (*lst == NULL) {
465 *lst = PyList_New(0);
466 if (*lst == NULL)
467 return -1;
468 }
469 return PyList_Append(*lst, func);
470}
471#endif
472
473/* Legacy wrapper */
474void
475PyOS_AfterFork(void)
476{
477#ifdef HAVE_FORK
478 PyOS_AfterFork_Child();
479#endif
480}
481
482
Victor Stinner6036e442015-03-08 01:58:04 +0100483#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200484/* defined in fileutils.c */
485PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
486PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
487 ULONG, struct _Py_stat_struct *);
488#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700489
490#ifdef MS_WINDOWS
491static int
492win32_warn_bytes_api()
493{
494 return PyErr_WarnEx(PyExc_DeprecationWarning,
495 "The Windows bytes API has been deprecated, "
496 "use Unicode filenames instead",
497 1);
498}
499#endif
500
501
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200502#ifndef MS_WINDOWS
503PyObject *
504_PyLong_FromUid(uid_t uid)
505{
506 if (uid == (uid_t)-1)
507 return PyLong_FromLong(-1);
508 return PyLong_FromUnsignedLong(uid);
509}
510
511PyObject *
512_PyLong_FromGid(gid_t gid)
513{
514 if (gid == (gid_t)-1)
515 return PyLong_FromLong(-1);
516 return PyLong_FromUnsignedLong(gid);
517}
518
519int
520_Py_Uid_Converter(PyObject *obj, void *p)
521{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700522 uid_t uid;
523 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200524 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200525 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 unsigned long uresult;
527
528 index = PyNumber_Index(obj);
529 if (index == NULL) {
530 PyErr_Format(PyExc_TypeError,
531 "uid should be integer, not %.200s",
532 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200533 return 0;
534 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535
536 /*
537 * Handling uid_t is complicated for two reasons:
538 * * Although uid_t is (always?) unsigned, it still
539 * accepts -1.
540 * * We don't know its size in advance--it may be
541 * bigger than an int, or it may be smaller than
542 * a long.
543 *
544 * So a bit of defensive programming is in order.
545 * Start with interpreting the value passed
546 * in as a signed long and see if it works.
547 */
548
549 result = PyLong_AsLongAndOverflow(index, &overflow);
550
551 if (!overflow) {
552 uid = (uid_t)result;
553
554 if (result == -1) {
555 if (PyErr_Occurred())
556 goto fail;
557 /* It's a legitimate -1, we're done. */
558 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200559 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700560
561 /* Any other negative number is disallowed. */
562 if (result < 0)
563 goto underflow;
564
565 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200566 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700567 (long)uid != result)
568 goto underflow;
569 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200570 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700571
572 if (overflow < 0)
573 goto underflow;
574
575 /*
576 * Okay, the value overflowed a signed long. If it
577 * fits in an *unsigned* long, it may still be okay,
578 * as uid_t may be unsigned long on this platform.
579 */
580 uresult = PyLong_AsUnsignedLong(index);
581 if (PyErr_Occurred()) {
582 if (PyErr_ExceptionMatches(PyExc_OverflowError))
583 goto overflow;
584 goto fail;
585 }
586
587 uid = (uid_t)uresult;
588
589 /*
590 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
591 * but this value would get interpreted as (uid_t)-1 by chown
592 * and its siblings. That's not what the user meant! So we
593 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100594 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700595 */
596 if (uid == (uid_t)-1)
597 goto overflow;
598
599 /* Ensure the value wasn't truncated. */
600 if (sizeof(uid_t) < sizeof(long) &&
601 (unsigned long)uid != uresult)
602 goto overflow;
603 /* fallthrough */
604
605success:
606 Py_DECREF(index);
607 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200608 return 1;
609
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700610underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200611 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700612 "uid is less than minimum");
613 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700617 "uid is greater than maximum");
618 /* fallthrough */
619
620fail:
621 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622 return 0;
623}
624
625int
626_Py_Gid_Converter(PyObject *obj, void *p)
627{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700628 gid_t gid;
629 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200631 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700632 unsigned long uresult;
633
634 index = PyNumber_Index(obj);
635 if (index == NULL) {
636 PyErr_Format(PyExc_TypeError,
637 "gid should be integer, not %.200s",
638 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200639 return 0;
640 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700641
642 /*
643 * Handling gid_t is complicated for two reasons:
644 * * Although gid_t is (always?) unsigned, it still
645 * accepts -1.
646 * * We don't know its size in advance--it may be
647 * bigger than an int, or it may be smaller than
648 * a long.
649 *
650 * So a bit of defensive programming is in order.
651 * Start with interpreting the value passed
652 * in as a signed long and see if it works.
653 */
654
655 result = PyLong_AsLongAndOverflow(index, &overflow);
656
657 if (!overflow) {
658 gid = (gid_t)result;
659
660 if (result == -1) {
661 if (PyErr_Occurred())
662 goto fail;
663 /* It's a legitimate -1, we're done. */
664 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200665 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700666
667 /* Any other negative number is disallowed. */
668 if (result < 0) {
669 goto underflow;
670 }
671
672 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200673 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700674 (long)gid != result)
675 goto underflow;
676 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200677 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700678
679 if (overflow < 0)
680 goto underflow;
681
682 /*
683 * Okay, the value overflowed a signed long. If it
684 * fits in an *unsigned* long, it may still be okay,
685 * as gid_t may be unsigned long on this platform.
686 */
687 uresult = PyLong_AsUnsignedLong(index);
688 if (PyErr_Occurred()) {
689 if (PyErr_ExceptionMatches(PyExc_OverflowError))
690 goto overflow;
691 goto fail;
692 }
693
694 gid = (gid_t)uresult;
695
696 /*
697 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
698 * but this value would get interpreted as (gid_t)-1 by chown
699 * and its siblings. That's not what the user meant! So we
700 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100701 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700702 */
703 if (gid == (gid_t)-1)
704 goto overflow;
705
706 /* Ensure the value wasn't truncated. */
707 if (sizeof(gid_t) < sizeof(long) &&
708 (unsigned long)gid != uresult)
709 goto overflow;
710 /* fallthrough */
711
712success:
713 Py_DECREF(index);
714 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200715 return 1;
716
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700717underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200718 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700719 "gid is less than minimum");
720 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700722overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200723 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700724 "gid is greater than maximum");
725 /* fallthrough */
726
727fail:
728 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200729 return 0;
730}
731#endif /* MS_WINDOWS */
732
733
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700734#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800735
736
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200737#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
738static int
739_Py_Dev_Converter(PyObject *obj, void *p)
740{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200741 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200742 if (PyErr_Occurred())
743 return 0;
744 return 1;
745}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800746#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200747
748
Larry Hastings9cf065c2012-06-22 16:30:09 -0700749#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400750/*
751 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
752 * without the int cast, the value gets interpreted as uint (4291925331),
753 * which doesn't play nicely with all the initializer lines in this file that
754 * look like this:
755 * int dir_fd = DEFAULT_DIR_FD;
756 */
757#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700758#else
759#define DEFAULT_DIR_FD (-100)
760#endif
761
762static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300763_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200764{
765 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700766 long long_value;
767
768 PyObject *index = PyNumber_Index(o);
769 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700770 return 0;
771 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300773 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700774 long_value = PyLong_AsLongAndOverflow(index, &overflow);
775 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300776 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200777 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700778 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700779 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780 return 0;
781 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200782 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700784 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700785 return 0;
786 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700787
Larry Hastings9cf065c2012-06-22 16:30:09 -0700788 *p = (int)long_value;
789 return 1;
790}
791
792static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200793dir_fd_converter(PyObject *o, void *p)
794{
795 if (o == Py_None) {
796 *(int *)p = DEFAULT_DIR_FD;
797 return 1;
798 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300799 else if (PyIndex_Check(o)) {
800 return _fd_converter(o, (int *)p);
801 }
802 else {
803 PyErr_Format(PyExc_TypeError,
804 "argument should be integer or None, not %.200s",
805 Py_TYPE(o)->tp_name);
806 return 0;
807 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700808}
809
810
Larry Hastings9cf065c2012-06-22 16:30:09 -0700811/*
812 * A PyArg_ParseTuple "converter" function
813 * that handles filesystem paths in the manner
814 * preferred by the os module.
815 *
816 * path_converter accepts (Unicode) strings and their
817 * subclasses, and bytes and their subclasses. What
818 * it does with the argument depends on the platform:
819 *
820 * * On Windows, if we get a (Unicode) string we
821 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700822 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700823 *
824 * * On all other platforms, strings are encoded
825 * to bytes using PyUnicode_FSConverter, then we
826 * extract the char * from the bytes object and
827 * return that.
828 *
829 * path_converter also optionally accepts signed
830 * integers (representing open file descriptors) instead
831 * of path strings.
832 *
833 * Input fields:
834 * path.nullable
835 * If nonzero, the path is permitted to be None.
836 * path.allow_fd
837 * If nonzero, the path is permitted to be a file handle
838 * (a signed int) instead of a string.
839 * path.function_name
840 * If non-NULL, path_converter will use that as the name
841 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700842 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700843 * path.argument_name
844 * If non-NULL, path_converter will use that as the name
845 * of the parameter in error messages.
846 * (If path.argument_name is NULL it uses "path".)
847 *
848 * Output fields:
849 * path.wide
850 * Points to the path if it was expressed as Unicode
851 * and was not encoded. (Only used on Windows.)
852 * path.narrow
853 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700854 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000855 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700856 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700857 * path.fd
858 * Contains a file descriptor if path.accept_fd was true
859 * and the caller provided a signed integer instead of any
860 * sort of string.
861 *
862 * WARNING: if your "path" parameter is optional, and is
863 * unspecified, path_converter will never get called.
864 * So if you set allow_fd, you *MUST* initialize path.fd = -1
865 * yourself!
866 * path.length
867 * The length of the path in characters, if specified as
868 * a string.
869 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800870 * The original object passed in (if get a PathLike object,
871 * the result of PyOS_FSPath() is treated as the original object).
872 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873 * path.cleanup
874 * For internal use only. May point to a temporary object.
875 * (Pay no attention to the man behind the curtain.)
876 *
877 * At most one of path.wide or path.narrow will be non-NULL.
878 * If path was None and path.nullable was set,
879 * or if path was an integer and path.allow_fd was set,
880 * both path.wide and path.narrow will be NULL
881 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200882 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700883 * path_converter takes care to not write to the path_t
884 * unless it's successful. However it must reset the
885 * "cleanup" field each time it's called.
886 *
887 * Use as follows:
888 * path_t path;
889 * memset(&path, 0, sizeof(path));
890 * PyArg_ParseTuple(args, "O&", path_converter, &path);
891 * // ... use values from path ...
892 * path_cleanup(&path);
893 *
894 * (Note that if PyArg_Parse fails you don't need to call
895 * path_cleanup(). However it is safe to do so.)
896 */
897typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100898 const char *function_name;
899 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700900 int nullable;
901 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300902 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700903#ifdef MS_WINDOWS
904 BOOL narrow;
905#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300906 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700907#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 int fd;
909 Py_ssize_t length;
910 PyObject *object;
911 PyObject *cleanup;
912} path_t;
913
Steve Dowercc16be82016-09-08 10:35:16 -0700914#ifdef MS_WINDOWS
915#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
916 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
917#else
Larry Hastings2f936352014-08-05 14:04:04 +1000918#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
919 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700920#endif
Larry Hastings31826802013-10-19 00:09:25 -0700921
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800923path_cleanup(path_t *path)
924{
925 Py_CLEAR(path->object);
926 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700927}
928
929static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300930path_converter(PyObject *o, void *p)
931{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700932 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800933 PyObject *bytes = NULL;
934 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700935 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300936 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700937#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800938 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700939 const wchar_t *wide;
940#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941
942#define FORMAT_EXCEPTION(exc, fmt) \
943 PyErr_Format(exc, "%s%s" fmt, \
944 path->function_name ? path->function_name : "", \
945 path->function_name ? ": " : "", \
946 path->argument_name ? path->argument_name : "path")
947
948 /* Py_CLEANUP_SUPPORTED support */
949 if (o == NULL) {
950 path_cleanup(path);
951 return 1;
952 }
953
Brett Cannon3f9183b2016-08-26 14:44:48 -0700954 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800955 path->object = path->cleanup = NULL;
956 /* path->object owns a reference to the original object */
957 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300959 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700961#ifdef MS_WINDOWS
962 path->narrow = FALSE;
963#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700965#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800967 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 }
969
Brett Cannon3f9183b2016-08-26 14:44:48 -0700970 /* Only call this here so that we don't treat the return value of
971 os.fspath() as an fd or buffer. */
972 is_index = path->allow_fd && PyIndex_Check(o);
973 is_buffer = PyObject_CheckBuffer(o);
974 is_bytes = PyBytes_Check(o);
975 is_unicode = PyUnicode_Check(o);
976
977 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
978 /* Inline PyOS_FSPath() for better error messages. */
979 _Py_IDENTIFIER(__fspath__);
980 PyObject *func = NULL;
981
982 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
983 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800984 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700985 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800986 /* still owns a reference to the original object */
987 Py_DECREF(o);
988 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700989 Py_DECREF(func);
990 if (NULL == o) {
991 goto error_exit;
992 }
993 else if (PyUnicode_Check(o)) {
994 is_unicode = 1;
995 }
996 else if (PyBytes_Check(o)) {
997 is_bytes = 1;
998 }
999 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001000 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001001 }
1002 }
1003
1004 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001006 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001007 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001008 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001009 }
Victor Stinner59799a82013-11-13 14:17:30 +01001010 if (length > 32767) {
1011 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001012 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001013 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001014 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001015 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001016 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001017 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001018
1019 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001022 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001023#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001024 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001025 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001026 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027#endif
1028 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001029 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001030 bytes = o;
1031 Py_INCREF(bytes);
1032 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001033 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001034 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001035 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001036 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1037 "%s%s%s should be %s, not %.200s",
1038 path->function_name ? path->function_name : "",
1039 path->function_name ? ": " : "",
1040 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001041 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1042 "integer or None" :
1043 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1044 path->nullable ? "string, bytes, os.PathLike or None" :
1045 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001046 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001047 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001049 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001051 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 }
1053 }
Steve Dowercc16be82016-09-08 10:35:16 -07001054 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001055 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001056 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001057 }
1058 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001059#ifdef MS_WINDOWS
1060 path->narrow = FALSE;
1061#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001062 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001063#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001064 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001065 }
1066 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001067 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001068 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1069 path->function_name ? path->function_name : "",
1070 path->function_name ? ": " : "",
1071 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001072 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1073 "integer or None" :
1074 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1075 path->nullable ? "string, bytes, os.PathLike or None" :
1076 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001077 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001078 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 }
1080
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001082 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001083 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001084 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001085 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086 }
1087
Steve Dowercc16be82016-09-08 10:35:16 -07001088#ifdef MS_WINDOWS
1089 wo = PyUnicode_DecodeFSDefaultAndSize(
1090 narrow,
1091 length
1092 );
1093 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001094 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001095 }
1096
Xiang Zhang04316c42017-01-08 23:26:57 +08001097 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001098 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001100 }
1101 if (length > 32767) {
1102 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001103 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001104 }
1105 if (wcslen(wide) != length) {
1106 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001107 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001108 }
1109 path->wide = wide;
1110 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001111 path->cleanup = wo;
1112 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001113#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001114 path->wide = NULL;
1115 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001116 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001117 /* Still a reference owned by path->object, don't have to
1118 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001119 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001120 }
1121 else {
1122 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001123 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001124#endif
1125 path->fd = -1;
1126
1127 success_exit:
1128 path->length = length;
1129 path->object = o;
1130 return Py_CLEANUP_SUPPORTED;
1131
1132 error_exit:
1133 Py_XDECREF(o);
1134 Py_XDECREF(bytes);
1135#ifdef MS_WINDOWS
1136 Py_XDECREF(wo);
1137#endif
1138 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001139}
1140
1141static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001142argument_unavailable_error(const char *function_name, const char *argument_name)
1143{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001144 PyErr_Format(PyExc_NotImplementedError,
1145 "%s%s%s unavailable on this platform",
1146 (function_name != NULL) ? function_name : "",
1147 (function_name != NULL) ? ": ": "",
1148 argument_name);
1149}
1150
1151static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001152dir_fd_unavailable(PyObject *o, void *p)
1153{
1154 int dir_fd;
1155 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001156 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001157 if (dir_fd != DEFAULT_DIR_FD) {
1158 argument_unavailable_error(NULL, "dir_fd");
1159 return 0;
1160 }
1161 *(int *)p = dir_fd;
1162 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163}
1164
1165static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001166fd_specified(const char *function_name, int fd)
1167{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001168 if (fd == -1)
1169 return 0;
1170
1171 argument_unavailable_error(function_name, "fd");
1172 return 1;
1173}
1174
1175static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001176follow_symlinks_specified(const char *function_name, int follow_symlinks)
1177{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001178 if (follow_symlinks)
1179 return 0;
1180
1181 argument_unavailable_error(function_name, "follow_symlinks");
1182 return 1;
1183}
1184
1185static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001186path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1187{
Steve Dowercc16be82016-09-08 10:35:16 -07001188 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1189#ifndef MS_WINDOWS
1190 && !path->narrow
1191#endif
1192 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001193 PyErr_Format(PyExc_ValueError,
1194 "%s: can't specify dir_fd without matching path",
1195 function_name);
1196 return 1;
1197 }
1198 return 0;
1199}
1200
1201static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001202dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1203{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001204 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1205 PyErr_Format(PyExc_ValueError,
1206 "%s: can't specify both dir_fd and fd",
1207 function_name);
1208 return 1;
1209 }
1210 return 0;
1211}
1212
1213static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001214fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1215 int follow_symlinks)
1216{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001217 if ((fd > 0) && (!follow_symlinks)) {
1218 PyErr_Format(PyExc_ValueError,
1219 "%s: cannot use fd and follow_symlinks together",
1220 function_name);
1221 return 1;
1222 }
1223 return 0;
1224}
1225
1226static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001227dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1228 int follow_symlinks)
1229{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001230 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1231 PyErr_Format(PyExc_ValueError,
1232 "%s: cannot use dir_fd and follow_symlinks together",
1233 function_name);
1234 return 1;
1235 }
1236 return 0;
1237}
1238
Larry Hastings2f936352014-08-05 14:04:04 +10001239#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001240 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001241#else
Larry Hastings2f936352014-08-05 14:04:04 +10001242 typedef off_t Py_off_t;
1243#endif
1244
1245static int
1246Py_off_t_converter(PyObject *arg, void *addr)
1247{
1248#ifdef HAVE_LARGEFILE_SUPPORT
1249 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1250#else
1251 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001252#endif
1253 if (PyErr_Occurred())
1254 return 0;
1255 return 1;
1256}
Larry Hastings2f936352014-08-05 14:04:04 +10001257
1258static PyObject *
1259PyLong_FromPy_off_t(Py_off_t offset)
1260{
1261#ifdef HAVE_LARGEFILE_SUPPORT
1262 return PyLong_FromLongLong(offset);
1263#else
1264 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001265#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001266}
1267
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001268#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001269
1270static int
Brian Curtind25aef52011-06-13 15:16:04 -05001271win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001272{
Martin Panter70214ad2016-08-04 02:38:59 +00001273 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1274 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001275 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276
1277 if (0 == DeviceIoControl(
1278 reparse_point_handle,
1279 FSCTL_GET_REPARSE_POINT,
1280 NULL, 0, /* in buffer */
1281 target_buffer, sizeof(target_buffer),
1282 &n_bytes_returned,
1283 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001284 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001285
1286 if (reparse_tag)
1287 *reparse_tag = rdb->ReparseTag;
1288
Brian Curtind25aef52011-06-13 15:16:04 -05001289 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001290}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001291
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001292#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001293
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001294/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001295#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001296/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001297** environ directly, we must obtain it with _NSGetEnviron(). See also
1298** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001299*/
1300#include <crt_externs.h>
1301static char **environ;
1302#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001304#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305
Barry Warsaw53699e91996-12-10 23:23:01 +00001306static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001307convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308{
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001310#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001314#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001315
Victor Stinner8c62be82010-05-06 00:08:46 +00001316 d = PyDict_New();
1317 if (d == NULL)
1318 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001319#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001320 if (environ == NULL)
1321 environ = *_NSGetEnviron();
1322#endif
1323#ifdef MS_WINDOWS
1324 /* _wenviron must be initialized in this way if the program is started
1325 through main() instead of wmain(). */
1326 _wgetenv(L"");
1327 if (_wenviron == NULL)
1328 return d;
1329 /* This part ignores errors */
1330 for (e = _wenviron; *e != NULL; e++) {
1331 PyObject *k;
1332 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001333 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001334 if (p == NULL)
1335 continue;
1336 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1337 if (k == NULL) {
1338 PyErr_Clear();
1339 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001340 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001341 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1342 if (v == NULL) {
1343 PyErr_Clear();
1344 Py_DECREF(k);
1345 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001346 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001347 if (PyDict_GetItem(d, k) == NULL) {
1348 if (PyDict_SetItem(d, k, v) != 0)
1349 PyErr_Clear();
1350 }
1351 Py_DECREF(k);
1352 Py_DECREF(v);
1353 }
1354#else
1355 if (environ == NULL)
1356 return d;
1357 /* This part ignores errors */
1358 for (e = environ; *e != NULL; e++) {
1359 PyObject *k;
1360 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001361 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 if (p == NULL)
1363 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001364 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001365 if (k == NULL) {
1366 PyErr_Clear();
1367 continue;
1368 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001369 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001370 if (v == NULL) {
1371 PyErr_Clear();
1372 Py_DECREF(k);
1373 continue;
1374 }
1375 if (PyDict_GetItem(d, k) == NULL) {
1376 if (PyDict_SetItem(d, k, v) != 0)
1377 PyErr_Clear();
1378 }
1379 Py_DECREF(k);
1380 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001381 }
1382#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001384}
1385
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001386/* Set a POSIX-specific error from errno, and return NULL */
1387
Barry Warsawd58d7641998-07-23 16:14:40 +00001388static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001389posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001390{
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392}
Mark Hammondef8b6542001-05-13 08:04:26 +00001393
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001394#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001395static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001396win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001397{
Victor Stinner8c62be82010-05-06 00:08:46 +00001398 /* XXX We should pass the function name along in the future.
1399 (winreg.c also wants to pass the function name.)
1400 This would however require an additional param to the
1401 Windows error object, which is non-trivial.
1402 */
1403 errno = GetLastError();
1404 if (filename)
1405 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1406 else
1407 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001408}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001409
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001410static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001411win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001412{
1413 /* XXX - see win32_error for comments on 'function' */
1414 errno = GetLastError();
1415 if (filename)
1416 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001417 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001418 errno,
1419 filename);
1420 else
1421 return PyErr_SetFromWindowsErr(errno);
1422}
1423
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001424#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001425
Larry Hastings9cf065c2012-06-22 16:30:09 -07001426static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001427path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001428{
1429#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001430 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1431 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001433 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001434#endif
1435}
1436
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001437static PyObject *
1438path_object_error2(PyObject *path, PyObject *path2)
1439{
1440#ifdef MS_WINDOWS
1441 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1442 PyExc_OSError, 0, path, path2);
1443#else
1444 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1445#endif
1446}
1447
1448static PyObject *
1449path_error(path_t *path)
1450{
1451 return path_object_error(path->object);
1452}
Larry Hastings31826802013-10-19 00:09:25 -07001453
Larry Hastingsb0827312014-02-09 22:05:19 -08001454static PyObject *
1455path_error2(path_t *path, path_t *path2)
1456{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001457 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001458}
1459
1460
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461/* POSIX generic methods */
1462
Larry Hastings2f936352014-08-05 14:04:04 +10001463static int
1464fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001465{
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001467 int *pointer = (int *)p;
1468 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001469 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001470 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001471 *pointer = fd;
1472 return 1;
1473}
1474
1475static PyObject *
1476posix_fildes_fd(int fd, int (*func)(int))
1477{
1478 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001479 int async_err = 0;
1480
1481 do {
1482 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001483 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001484 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001485 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001486 Py_END_ALLOW_THREADS
1487 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1488 if (res != 0)
1489 return (!async_err) ? posix_error() : NULL;
1490 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001491}
Guido van Rossum21142a01999-01-08 21:05:37 +00001492
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001493
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001494#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495/* This is a reimplementation of the C library's chdir function,
1496 but one that produces Win32 errors instead of DOS error codes.
1497 chdir is essentially a wrapper around SetCurrentDirectory; however,
1498 it also needs to set "magic" environment variables indicating
1499 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001500static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001501win32_wchdir(LPCWSTR path)
1502{
Victor Stinnered537822015-12-13 21:40:26 +01001503 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001504 int result;
1505 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001506
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 if(!SetCurrentDirectoryW(path))
1508 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001509 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001510 if (!result)
1511 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001512 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001513 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 if (!new_path) {
1515 SetLastError(ERROR_OUTOFMEMORY);
1516 return FALSE;
1517 }
1518 result = GetCurrentDirectoryW(result, new_path);
1519 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001520 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 return FALSE;
1522 }
1523 }
1524 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1525 wcsncmp(new_path, L"//", 2) == 0)
1526 /* UNC path, nothing to do. */
1527 return TRUE;
1528 env[1] = new_path[0];
1529 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001530 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001531 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001532 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533}
1534#endif
1535
Martin v. Löwis14694662006-02-03 12:54:16 +00001536#ifdef MS_WINDOWS
1537/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1538 - time stamps are restricted to second resolution
1539 - file modification times suffer from forth-and-back conversions between
1540 UTC and local time
1541 Therefore, we implement our own stat, based on the Win32 API directly.
1542*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001543#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001544#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001545
Victor Stinner6036e442015-03-08 01:58:04 +01001546static void
Steve Dowercc16be82016-09-08 10:35:16 -07001547find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1548 BY_HANDLE_FILE_INFORMATION *info,
1549 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001550{
1551 memset(info, 0, sizeof(*info));
1552 info->dwFileAttributes = pFileData->dwFileAttributes;
1553 info->ftCreationTime = pFileData->ftCreationTime;
1554 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1555 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1556 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1557 info->nFileSizeLow = pFileData->nFileSizeLow;
1558/* info->nNumberOfLinks = 1; */
1559 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1560 *reparse_tag = pFileData->dwReserved0;
1561 else
1562 *reparse_tag = 0;
1563}
1564
Guido van Rossumd8faa362007-04-27 19:54:29 +00001565static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001566attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001567{
Victor Stinner8c62be82010-05-06 00:08:46 +00001568 HANDLE hFindFile;
1569 WIN32_FIND_DATAW FileData;
1570 hFindFile = FindFirstFileW(pszFile, &FileData);
1571 if (hFindFile == INVALID_HANDLE_VALUE)
1572 return FALSE;
1573 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001574 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001576}
1577
Brian Curtind25aef52011-06-13 15:16:04 -05001578static BOOL
1579get_target_path(HANDLE hdl, wchar_t **target_path)
1580{
1581 int buf_size, result_length;
1582 wchar_t *buf;
1583
1584 /* We have a good handle to the target, use it to determine
1585 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001586 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1587 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001588 if(!buf_size)
1589 return FALSE;
1590
Victor Stinnerc36674a2016-03-16 14:30:16 +01001591 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001592 if (!buf) {
1593 SetLastError(ERROR_OUTOFMEMORY);
1594 return FALSE;
1595 }
1596
Steve Dower2ea51c92015-03-20 21:49:12 -07001597 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001598 buf, buf_size, VOLUME_NAME_DOS);
1599
1600 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001601 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001602 return FALSE;
1603 }
1604
1605 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001606 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001607 return FALSE;
1608 }
1609
1610 buf[result_length] = 0;
1611
1612 *target_path = buf;
1613 return TRUE;
1614}
1615
1616static int
Steve Dowercc16be82016-09-08 10:35:16 -07001617win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001618 BOOL traverse)
1619{
Victor Stinner26de69d2011-06-17 15:15:38 +02001620 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001621 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001624 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001625 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626
Steve Dowercc16be82016-09-08 10:35:16 -07001627 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001628 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001629 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001630 0, /* share mode */
1631 NULL, /* security attributes */
1632 OPEN_EXISTING,
1633 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001634 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1635 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001636 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001637 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1638 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 NULL);
1640
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001641 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001642 /* Either the target doesn't exist, or we don't have access to
1643 get a handle to it. If the former, we need to return an error.
1644 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001645 DWORD lastError = GetLastError();
1646 if (lastError != ERROR_ACCESS_DENIED &&
1647 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001648 return -1;
1649 /* Could not get attributes on open file. Fall back to
1650 reading the directory. */
1651 if (!attributes_from_dir(path, &info, &reparse_tag))
1652 /* Very strange. This should not fail now */
1653 return -1;
1654 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1655 if (traverse) {
1656 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001657 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 } else {
1662 if (!GetFileInformationByHandle(hFile, &info)) {
1663 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001664 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 }
1666 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001667 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1668 return -1;
1669
1670 /* Close the outer open file handle now that we're about to
1671 reopen it with different flags. */
1672 if (!CloseHandle(hFile))
1673 return -1;
1674
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001676 /* In order to call GetFinalPathNameByHandle we need to open
1677 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001678 hFile2 = CreateFileW(
1679 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1680 NULL, OPEN_EXISTING,
1681 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1682 NULL);
1683 if (hFile2 == INVALID_HANDLE_VALUE)
1684 return -1;
1685
1686 if (!get_target_path(hFile2, &target_path))
1687 return -1;
1688
Steve Dowercc16be82016-09-08 10:35:16 -07001689 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001690 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001691 return code;
1692 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001693 } else
1694 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001695 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001696 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697
1698 /* Set S_IEXEC if it is an .exe, .bat, ... */
1699 dot = wcsrchr(path, '.');
1700 if (dot) {
1701 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1702 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1703 result->st_mode |= 0111;
1704 }
1705 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706}
1707
1708static int
Steve Dowercc16be82016-09-08 10:35:16 -07001709win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 /* Protocol violation: we explicitly clear errno, instead of
1712 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001713 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 errno = 0;
1715 return code;
1716}
Brian Curtind25aef52011-06-13 15:16:04 -05001717/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001718
1719 In Posix, stat automatically traverses symlinks and returns the stat
1720 structure for the target. In Windows, the equivalent GetFileAttributes by
1721 default does not traverse symlinks and instead returns attributes for
1722 the symlink.
1723
1724 Therefore, win32_lstat will get the attributes traditionally, and
1725 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001726 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001727
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001728static int
Steve Dowercc16be82016-09-08 10:35:16 -07001729win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001730{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001731 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001732}
1733
Victor Stinner8c62be82010-05-06 00:08:46 +00001734static int
Steve Dowercc16be82016-09-08 10:35:16 -07001735win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001736{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001737 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001738}
1739
Martin v. Löwis14694662006-02-03 12:54:16 +00001740#endif /* MS_WINDOWS */
1741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001742PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001743"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001744This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001745 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001746or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1747\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001748Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1749or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001751See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001752
1753static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 {"st_mode", "protection bits"},
1755 {"st_ino", "inode"},
1756 {"st_dev", "device"},
1757 {"st_nlink", "number of hard links"},
1758 {"st_uid", "user ID of owner"},
1759 {"st_gid", "group ID of owner"},
1760 {"st_size", "total size, in bytes"},
1761 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1762 {NULL, "integer time of last access"},
1763 {NULL, "integer time of last modification"},
1764 {NULL, "integer time of last change"},
1765 {"st_atime", "time of last access"},
1766 {"st_mtime", "time of last modification"},
1767 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001768 {"st_atime_ns", "time of last access in nanoseconds"},
1769 {"st_mtime_ns", "time of last modification in nanoseconds"},
1770 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001771#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001772 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001773#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001774#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001775 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001776#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001777#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001778 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001779#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001780#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001782#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001783#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001785#endif
1786#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001788#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001789#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1790 {"st_file_attributes", "Windows file attribute bits"},
1791#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001793};
1794
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001795#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001796#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001798#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001799#endif
1800
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001801#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001802#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1803#else
1804#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1805#endif
1806
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001807#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001808#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1809#else
1810#define ST_RDEV_IDX ST_BLOCKS_IDX
1811#endif
1812
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001813#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1814#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1815#else
1816#define ST_FLAGS_IDX ST_RDEV_IDX
1817#endif
1818
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001819#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001820#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001821#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001822#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001823#endif
1824
1825#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1826#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1827#else
1828#define ST_BIRTHTIME_IDX ST_GEN_IDX
1829#endif
1830
Zachary Ware63f277b2014-06-19 09:46:37 -05001831#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1832#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1833#else
1834#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1835#endif
1836
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 "stat_result", /* name */
1839 stat_result__doc__, /* doc */
1840 stat_result_fields,
1841 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001842};
1843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001844PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001845"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1846This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001847 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001848or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851
1852static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 {"f_bsize", },
1854 {"f_frsize", },
1855 {"f_blocks", },
1856 {"f_bfree", },
1857 {"f_bavail", },
1858 {"f_files", },
1859 {"f_ffree", },
1860 {"f_favail", },
1861 {"f_flag", },
1862 {"f_namemax",},
1863 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864};
1865
1866static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 "statvfs_result", /* name */
1868 statvfs_result__doc__, /* doc */
1869 statvfs_result_fields,
1870 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001871};
1872
Ross Lagerwall7807c352011-03-17 20:20:30 +02001873#if defined(HAVE_WAITID) && !defined(__APPLE__)
1874PyDoc_STRVAR(waitid_result__doc__,
1875"waitid_result: Result from waitid.\n\n\
1876This object may be accessed either as a tuple of\n\
1877 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1878or via the attributes si_pid, si_uid, and so on.\n\
1879\n\
1880See os.waitid for more information.");
1881
1882static PyStructSequence_Field waitid_result_fields[] = {
1883 {"si_pid", },
1884 {"si_uid", },
1885 {"si_signo", },
1886 {"si_status", },
1887 {"si_code", },
1888 {0}
1889};
1890
1891static PyStructSequence_Desc waitid_result_desc = {
1892 "waitid_result", /* name */
1893 waitid_result__doc__, /* doc */
1894 waitid_result_fields,
1895 5
1896};
1897static PyTypeObject WaitidResultType;
1898#endif
1899
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001900static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001901static PyTypeObject StatResultType;
1902static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001903#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001904static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001905#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001906static newfunc structseq_new;
1907
1908static PyObject *
1909statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1910{
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 PyStructSequence *result;
1912 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001913
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 result = (PyStructSequence*)structseq_new(type, args, kwds);
1915 if (!result)
1916 return NULL;
1917 /* If we have been initialized from a tuple,
1918 st_?time might be set to None. Initialize it
1919 from the int slots. */
1920 for (i = 7; i <= 9; i++) {
1921 if (result->ob_item[i+3] == Py_None) {
1922 Py_DECREF(Py_None);
1923 Py_INCREF(result->ob_item[i]);
1924 result->ob_item[i+3] = result->ob_item[i];
1925 }
1926 }
1927 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001928}
1929
1930
Larry Hastings6fe20b32012-04-19 15:07:49 -07001931static PyObject *billion = NULL;
1932
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001933static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001934fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001935{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001936 PyObject *s = _PyLong_FromTime_t(sec);
1937 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1938 PyObject *s_in_ns = NULL;
1939 PyObject *ns_total = NULL;
1940 PyObject *float_s = NULL;
1941
1942 if (!(s && ns_fractional))
1943 goto exit;
1944
1945 s_in_ns = PyNumber_Multiply(s, billion);
1946 if (!s_in_ns)
1947 goto exit;
1948
1949 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1950 if (!ns_total)
1951 goto exit;
1952
Victor Stinner01b5aab2017-10-24 02:02:00 -07001953 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1954 if (!float_s) {
1955 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001956 }
1957
1958 PyStructSequence_SET_ITEM(v, index, s);
1959 PyStructSequence_SET_ITEM(v, index+3, float_s);
1960 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1961 s = NULL;
1962 float_s = NULL;
1963 ns_total = NULL;
1964exit:
1965 Py_XDECREF(s);
1966 Py_XDECREF(ns_fractional);
1967 Py_XDECREF(s_in_ns);
1968 Py_XDECREF(ns_total);
1969 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001970}
1971
Tim Peters5aa91602002-01-30 05:46:57 +00001972/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001973 (used by posix_stat() and posix_fstat()) */
1974static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001975_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001976{
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 unsigned long ansec, mnsec, cnsec;
1978 PyObject *v = PyStructSequence_New(&StatResultType);
1979 if (v == NULL)
1980 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001981
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01001983 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02001984 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001985#ifdef MS_WINDOWS
1986 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001987#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001988 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001989#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001991#if defined(MS_WINDOWS)
1992 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1993 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1994#else
1995 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1996 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1997#endif
xdegaye50e86032017-05-22 11:15:08 +02001998 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
1999 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002000
Martin v. Löwis14694662006-02-03 12:54:16 +00002001#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 ansec = st->st_atim.tv_nsec;
2003 mnsec = st->st_mtim.tv_nsec;
2004 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002005#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 ansec = st->st_atimespec.tv_nsec;
2007 mnsec = st->st_mtimespec.tv_nsec;
2008 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002009#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 ansec = st->st_atime_nsec;
2011 mnsec = st->st_mtime_nsec;
2012 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002013#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002015#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002016 fill_time(v, 7, st->st_atime, ansec);
2017 fill_time(v, 8, st->st_mtime, mnsec);
2018 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002019
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002020#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2022 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002024#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002025 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2026 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002028#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2030 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002031#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002032#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2034 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002035#endif
2036#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002038 PyObject *val;
2039 unsigned long bsec,bnsec;
2040 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002041#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002042 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002043#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002044 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002045#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002046 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002047 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2048 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002050#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002051#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2053 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002054#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002055#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2056 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2057 PyLong_FromUnsignedLong(st->st_file_attributes));
2058#endif
Fred Drake699f3522000-06-29 21:12:41 +00002059
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 if (PyErr_Occurred()) {
2061 Py_DECREF(v);
2062 return NULL;
2063 }
Fred Drake699f3522000-06-29 21:12:41 +00002064
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002066}
2067
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068/* POSIX methods */
2069
Guido van Rossum94f6f721999-01-06 18:42:14 +00002070
2071static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002072posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002073 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002074{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002075 STRUCT_STAT st;
2076 int result;
2077
2078#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2079 if (follow_symlinks_specified(function_name, follow_symlinks))
2080 return NULL;
2081#endif
2082
2083 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2084 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2085 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2086 return NULL;
2087
2088 Py_BEGIN_ALLOW_THREADS
2089 if (path->fd != -1)
2090 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002091#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002092 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002093 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002094 else
Steve Dowercc16be82016-09-08 10:35:16 -07002095 result = win32_lstat(path->wide, &st);
2096#else
2097 else
2098#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002099 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2100 result = LSTAT(path->narrow, &st);
2101 else
Steve Dowercc16be82016-09-08 10:35:16 -07002102#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002103#ifdef HAVE_FSTATAT
2104 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2105 result = fstatat(dir_fd, path->narrow, &st,
2106 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2107 else
Steve Dowercc16be82016-09-08 10:35:16 -07002108#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002109 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002110#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002111 Py_END_ALLOW_THREADS
2112
Victor Stinner292c8352012-10-30 02:17:38 +01002113 if (result != 0) {
2114 return path_error(path);
2115 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002116
2117 return _pystat_fromstructstat(&st);
2118}
2119
Larry Hastings2f936352014-08-05 14:04:04 +10002120/*[python input]
2121
2122for s in """
2123
2124FACCESSAT
2125FCHMODAT
2126FCHOWNAT
2127FSTATAT
2128LINKAT
2129MKDIRAT
2130MKFIFOAT
2131MKNODAT
2132OPENAT
2133READLINKAT
2134SYMLINKAT
2135UNLINKAT
2136
2137""".strip().split():
2138 s = s.strip()
2139 print("""
2140#ifdef HAVE_{s}
2141 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002142#else
Larry Hastings2f936352014-08-05 14:04:04 +10002143 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002144#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002145""".rstrip().format(s=s))
2146
2147for s in """
2148
2149FCHDIR
2150FCHMOD
2151FCHOWN
2152FDOPENDIR
2153FEXECVE
2154FPATHCONF
2155FSTATVFS
2156FTRUNCATE
2157
2158""".strip().split():
2159 s = s.strip()
2160 print("""
2161#ifdef HAVE_{s}
2162 #define PATH_HAVE_{s} 1
2163#else
2164 #define PATH_HAVE_{s} 0
2165#endif
2166
2167""".rstrip().format(s=s))
2168[python start generated code]*/
2169
2170#ifdef HAVE_FACCESSAT
2171 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2172#else
2173 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2174#endif
2175
2176#ifdef HAVE_FCHMODAT
2177 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2178#else
2179 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2180#endif
2181
2182#ifdef HAVE_FCHOWNAT
2183 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2184#else
2185 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2186#endif
2187
2188#ifdef HAVE_FSTATAT
2189 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2190#else
2191 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2192#endif
2193
2194#ifdef HAVE_LINKAT
2195 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_MKDIRAT
2201 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_MKFIFOAT
2207 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2208#else
2209 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2210#endif
2211
2212#ifdef HAVE_MKNODAT
2213 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_OPENAT
2219 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_READLINKAT
2225 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_SYMLINKAT
2231 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_UNLINKAT
2237 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_FCHDIR
2243 #define PATH_HAVE_FCHDIR 1
2244#else
2245 #define PATH_HAVE_FCHDIR 0
2246#endif
2247
2248#ifdef HAVE_FCHMOD
2249 #define PATH_HAVE_FCHMOD 1
2250#else
2251 #define PATH_HAVE_FCHMOD 0
2252#endif
2253
2254#ifdef HAVE_FCHOWN
2255 #define PATH_HAVE_FCHOWN 1
2256#else
2257 #define PATH_HAVE_FCHOWN 0
2258#endif
2259
2260#ifdef HAVE_FDOPENDIR
2261 #define PATH_HAVE_FDOPENDIR 1
2262#else
2263 #define PATH_HAVE_FDOPENDIR 0
2264#endif
2265
2266#ifdef HAVE_FEXECVE
2267 #define PATH_HAVE_FEXECVE 1
2268#else
2269 #define PATH_HAVE_FEXECVE 0
2270#endif
2271
2272#ifdef HAVE_FPATHCONF
2273 #define PATH_HAVE_FPATHCONF 1
2274#else
2275 #define PATH_HAVE_FPATHCONF 0
2276#endif
2277
2278#ifdef HAVE_FSTATVFS
2279 #define PATH_HAVE_FSTATVFS 1
2280#else
2281 #define PATH_HAVE_FSTATVFS 0
2282#endif
2283
2284#ifdef HAVE_FTRUNCATE
2285 #define PATH_HAVE_FTRUNCATE 1
2286#else
2287 #define PATH_HAVE_FTRUNCATE 0
2288#endif
2289/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002290
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002291#ifdef MS_WINDOWS
2292 #undef PATH_HAVE_FTRUNCATE
2293 #define PATH_HAVE_FTRUNCATE 1
2294#endif
Larry Hastings31826802013-10-19 00:09:25 -07002295
Larry Hastings61272b72014-01-07 12:41:53 -08002296/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002297
2298class path_t_converter(CConverter):
2299
2300 type = "path_t"
2301 impl_by_reference = True
2302 parse_by_reference = True
2303
2304 converter = 'path_converter'
2305
2306 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002307 # right now path_t doesn't support default values.
2308 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002309 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002310 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002311
Larry Hastings2f936352014-08-05 14:04:04 +10002312 if self.c_default not in (None, 'Py_None'):
2313 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002314
2315 self.nullable = nullable
2316 self.allow_fd = allow_fd
2317
Larry Hastings7726ac92014-01-31 22:03:12 -08002318 def pre_render(self):
2319 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002320 if isinstance(value, str):
2321 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002322 return str(int(bool(value)))
2323
2324 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002325 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002326 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002327 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002328 strify(self.nullable),
2329 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002330 )
2331
2332 def cleanup(self):
2333 return "path_cleanup(&" + self.name + ");\n"
2334
2335
2336class dir_fd_converter(CConverter):
2337 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002338
Larry Hastings2f936352014-08-05 14:04:04 +10002339 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002340 if self.default in (unspecified, None):
2341 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002342 if isinstance(requires, str):
2343 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2344 else:
2345 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002346
Larry Hastings2f936352014-08-05 14:04:04 +10002347class fildes_converter(CConverter):
2348 type = 'int'
2349 converter = 'fildes_converter'
2350
2351class uid_t_converter(CConverter):
2352 type = "uid_t"
2353 converter = '_Py_Uid_Converter'
2354
2355class gid_t_converter(CConverter):
2356 type = "gid_t"
2357 converter = '_Py_Gid_Converter'
2358
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002359class dev_t_converter(CConverter):
2360 type = 'dev_t'
2361 converter = '_Py_Dev_Converter'
2362
2363class dev_t_return_converter(unsigned_long_return_converter):
2364 type = 'dev_t'
2365 conversion_fn = '_PyLong_FromDev'
2366 unsigned_cast = '(dev_t)'
2367
Larry Hastings2f936352014-08-05 14:04:04 +10002368class FSConverter_converter(CConverter):
2369 type = 'PyObject *'
2370 converter = 'PyUnicode_FSConverter'
2371 def converter_init(self):
2372 if self.default is not unspecified:
2373 fail("FSConverter_converter does not support default values")
2374 self.c_default = 'NULL'
2375
2376 def cleanup(self):
2377 return "Py_XDECREF(" + self.name + ");\n"
2378
2379class pid_t_converter(CConverter):
2380 type = 'pid_t'
2381 format_unit = '" _Py_PARSE_PID "'
2382
2383class idtype_t_converter(int_converter):
2384 type = 'idtype_t'
2385
2386class id_t_converter(CConverter):
2387 type = 'id_t'
2388 format_unit = '" _Py_PARSE_PID "'
2389
Benjamin Petersonca470632016-09-06 13:47:26 -07002390class intptr_t_converter(CConverter):
2391 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002392 format_unit = '" _Py_PARSE_INTPTR "'
2393
2394class Py_off_t_converter(CConverter):
2395 type = 'Py_off_t'
2396 converter = 'Py_off_t_converter'
2397
2398class Py_off_t_return_converter(long_return_converter):
2399 type = 'Py_off_t'
2400 conversion_fn = 'PyLong_FromPy_off_t'
2401
2402class path_confname_converter(CConverter):
2403 type="int"
2404 converter="conv_path_confname"
2405
2406class confstr_confname_converter(path_confname_converter):
2407 converter='conv_confstr_confname'
2408
2409class sysconf_confname_converter(path_confname_converter):
2410 converter="conv_sysconf_confname"
2411
2412class sched_param_converter(CConverter):
2413 type = 'struct sched_param'
2414 converter = 'convert_sched_param'
2415 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002416
Larry Hastings61272b72014-01-07 12:41:53 -08002417[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002418/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002419
Larry Hastings61272b72014-01-07 12:41:53 -08002420/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002421
Larry Hastings2a727912014-01-16 11:32:01 -08002422os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002423
2424 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002425 Path to be examined; can be string, bytes, path-like object or
2426 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002427
2428 *
2429
Larry Hastings2f936352014-08-05 14:04:04 +10002430 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002431 If not None, it should be a file descriptor open to a directory,
2432 and path should be a relative string; path will then be relative to
2433 that directory.
2434
2435 follow_symlinks: bool = True
2436 If False, and the last element of the path is a symbolic link,
2437 stat will examine the symbolic link itself instead of the file
2438 the link points to.
2439
2440Perform a stat system call on the given path.
2441
2442dir_fd and follow_symlinks may not be implemented
2443 on your platform. If they are unavailable, using them will raise a
2444 NotImplementedError.
2445
2446It's an error to use dir_fd or follow_symlinks when specifying path as
2447 an open file descriptor.
2448
Larry Hastings61272b72014-01-07 12:41:53 -08002449[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002450
Larry Hastings31826802013-10-19 00:09:25 -07002451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002452os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002453/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002454{
2455 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2456}
2457
Larry Hastings2f936352014-08-05 14:04:04 +10002458
2459/*[clinic input]
2460os.lstat
2461
2462 path : path_t
2463
2464 *
2465
2466 dir_fd : dir_fd(requires='fstatat') = None
2467
2468Perform a stat system call on the given path, without following symbolic links.
2469
2470Like stat(), but do not follow symbolic links.
2471Equivalent to stat(path, follow_symlinks=False).
2472[clinic start generated code]*/
2473
Larry Hastings2f936352014-08-05 14:04:04 +10002474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002475os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2476/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002477{
2478 int follow_symlinks = 0;
2479 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2480}
Larry Hastings31826802013-10-19 00:09:25 -07002481
Larry Hastings2f936352014-08-05 14:04:04 +10002482
Larry Hastings61272b72014-01-07 12:41:53 -08002483/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002484os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002485
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002486 path: path_t
2487 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002488
2489 mode: int
2490 Operating-system mode bitfield. Can be F_OK to test existence,
2491 or the inclusive-OR of R_OK, W_OK, and X_OK.
2492
2493 *
2494
Larry Hastings2f936352014-08-05 14:04:04 +10002495 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002496 If not None, it should be a file descriptor open to a directory,
2497 and path should be relative; path will then be relative to that
2498 directory.
2499
2500 effective_ids: bool = False
2501 If True, access will use the effective uid/gid instead of
2502 the real uid/gid.
2503
2504 follow_symlinks: bool = True
2505 If False, and the last element of the path is a symbolic link,
2506 access will examine the symbolic link itself instead of the file
2507 the link points to.
2508
2509Use the real uid/gid to test for access to a path.
2510
2511{parameters}
2512dir_fd, effective_ids, and follow_symlinks may not be implemented
2513 on your platform. If they are unavailable, using them will raise a
2514 NotImplementedError.
2515
2516Note that most operations will use the effective uid/gid, therefore this
2517 routine can be used in a suid/sgid environment to test if the invoking user
2518 has the specified access to the path.
2519
Larry Hastings61272b72014-01-07 12:41:53 -08002520[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002521
Larry Hastings2f936352014-08-05 14:04:04 +10002522static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002523os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002524 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002525/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002526{
Larry Hastings2f936352014-08-05 14:04:04 +10002527 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002528
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002529#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002530 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002531#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002533#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002534
Larry Hastings9cf065c2012-06-22 16:30:09 -07002535#ifndef HAVE_FACCESSAT
2536 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002537 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002538
2539 if (effective_ids) {
2540 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002541 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542 }
2543#endif
2544
2545#ifdef MS_WINDOWS
2546 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002547 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002548 Py_END_ALLOW_THREADS
2549
2550 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002551 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002552 * * we didn't get a -1, and
2553 * * write access wasn't requested,
2554 * * or the file isn't read-only,
2555 * * or it's a directory.
2556 * (Directories cannot be read-only on Windows.)
2557 */
Larry Hastings2f936352014-08-05 14:04:04 +10002558 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002559 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002561 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562#else
2563
2564 Py_BEGIN_ALLOW_THREADS
2565#ifdef HAVE_FACCESSAT
2566 if ((dir_fd != DEFAULT_DIR_FD) ||
2567 effective_ids ||
2568 !follow_symlinks) {
2569 int flags = 0;
2570 if (!follow_symlinks)
2571 flags |= AT_SYMLINK_NOFOLLOW;
2572 if (effective_ids)
2573 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002574 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 }
2576 else
2577#endif
Larry Hastings31826802013-10-19 00:09:25 -07002578 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002579 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002580 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002581#endif
2582
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002584}
2585
Guido van Rossumd371ff11999-01-25 16:12:23 +00002586#ifndef F_OK
2587#define F_OK 0
2588#endif
2589#ifndef R_OK
2590#define R_OK 4
2591#endif
2592#ifndef W_OK
2593#define W_OK 2
2594#endif
2595#ifndef X_OK
2596#define X_OK 1
2597#endif
2598
Larry Hastings31826802013-10-19 00:09:25 -07002599
Guido van Rossumd371ff11999-01-25 16:12:23 +00002600#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002601/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002602os.ttyname -> DecodeFSDefault
2603
2604 fd: int
2605 Integer file descriptor handle.
2606
2607 /
2608
2609Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002610[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002611
Larry Hastings31826802013-10-19 00:09:25 -07002612static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002613os_ttyname_impl(PyObject *module, int fd)
2614/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002615{
2616 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002617
Larry Hastings31826802013-10-19 00:09:25 -07002618 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002619 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002620 posix_error();
2621 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002622}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002623#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002624
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002625#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002626/*[clinic input]
2627os.ctermid
2628
2629Return the name of the controlling terminal for this process.
2630[clinic start generated code]*/
2631
Larry Hastings2f936352014-08-05 14:04:04 +10002632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002633os_ctermid_impl(PyObject *module)
2634/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002635{
Victor Stinner8c62be82010-05-06 00:08:46 +00002636 char *ret;
2637 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002638
Greg Wardb48bc172000-03-01 21:51:56 +00002639#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002640 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002641#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002643#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002644 if (ret == NULL)
2645 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002646 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002647}
Larry Hastings2f936352014-08-05 14:04:04 +10002648#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002649
Larry Hastings2f936352014-08-05 14:04:04 +10002650
2651/*[clinic input]
2652os.chdir
2653
2654 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2655
2656Change the current working directory to the specified path.
2657
2658path may always be specified as a string.
2659On some platforms, path may also be specified as an open file descriptor.
2660 If this functionality is unavailable, using it raises an exception.
2661[clinic start generated code]*/
2662
Larry Hastings2f936352014-08-05 14:04:04 +10002663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002664os_chdir_impl(PyObject *module, path_t *path)
2665/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002666{
2667 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002668
2669 Py_BEGIN_ALLOW_THREADS
2670#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002671 /* on unix, success = 0, on windows, success = !0 */
2672 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002673#else
2674#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002675 if (path->fd != -1)
2676 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002677 else
2678#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002679 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002680#endif
2681 Py_END_ALLOW_THREADS
2682
2683 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002684 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002685 }
2686
Larry Hastings2f936352014-08-05 14:04:04 +10002687 Py_RETURN_NONE;
2688}
2689
2690
2691#ifdef HAVE_FCHDIR
2692/*[clinic input]
2693os.fchdir
2694
2695 fd: fildes
2696
2697Change to the directory of the given file descriptor.
2698
2699fd must be opened on a directory, not a file.
2700Equivalent to os.chdir(fd).
2701
2702[clinic start generated code]*/
2703
Fred Drake4d1e64b2002-04-15 19:40:07 +00002704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002705os_fchdir_impl(PyObject *module, int fd)
2706/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002707{
Larry Hastings2f936352014-08-05 14:04:04 +10002708 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002709}
2710#endif /* HAVE_FCHDIR */
2711
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002712
Larry Hastings2f936352014-08-05 14:04:04 +10002713/*[clinic input]
2714os.chmod
2715
2716 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2717 Path to be modified. May always be specified as a str or bytes.
2718 On some platforms, path may also be specified as an open file descriptor.
2719 If this functionality is unavailable, using it raises an exception.
2720
2721 mode: int
2722 Operating-system mode bitfield.
2723
2724 *
2725
2726 dir_fd : dir_fd(requires='fchmodat') = None
2727 If not None, it should be a file descriptor open to a directory,
2728 and path should be relative; path will then be relative to that
2729 directory.
2730
2731 follow_symlinks: bool = True
2732 If False, and the last element of the path is a symbolic link,
2733 chmod will modify the symbolic link itself instead of the file
2734 the link points to.
2735
2736Change the access permissions of a file.
2737
2738It is an error to use dir_fd or follow_symlinks when specifying path as
2739 an open file descriptor.
2740dir_fd and follow_symlinks may not be implemented on your platform.
2741 If they are unavailable, using them will raise a NotImplementedError.
2742
2743[clinic start generated code]*/
2744
Larry Hastings2f936352014-08-05 14:04:04 +10002745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002746os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002747 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002748/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002749{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002750 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002751
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002752#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002753 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002754#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002755
Larry Hastings9cf065c2012-06-22 16:30:09 -07002756#ifdef HAVE_FCHMODAT
2757 int fchmodat_nofollow_unsupported = 0;
2758#endif
2759
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2761 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002762 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763#endif
2764
2765#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002766 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002767 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002768 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002769 result = 0;
2770 else {
2771 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002772 attr &= ~FILE_ATTRIBUTE_READONLY;
2773 else
2774 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002775 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002776 }
2777 Py_END_ALLOW_THREADS
2778
2779 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002780 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 }
2782#else /* MS_WINDOWS */
2783 Py_BEGIN_ALLOW_THREADS
2784#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002785 if (path->fd != -1)
2786 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787 else
2788#endif
2789#ifdef HAVE_LCHMOD
2790 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002791 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792 else
2793#endif
2794#ifdef HAVE_FCHMODAT
2795 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2796 /*
2797 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2798 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002799 * and then says it isn't implemented yet.
2800 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801 *
2802 * Once it is supported, os.chmod will automatically
2803 * support dir_fd and follow_symlinks=False. (Hopefully.)
2804 * Until then, we need to be careful what exception we raise.
2805 */
Larry Hastings2f936352014-08-05 14:04:04 +10002806 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2808 /*
2809 * But wait! We can't throw the exception without allowing threads,
2810 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2811 */
2812 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002813 result &&
2814 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2815 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002816 }
2817 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002818#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002819 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820 Py_END_ALLOW_THREADS
2821
2822 if (result) {
2823#ifdef HAVE_FCHMODAT
2824 if (fchmodat_nofollow_unsupported) {
2825 if (dir_fd != DEFAULT_DIR_FD)
2826 dir_fd_and_follow_symlinks_invalid("chmod",
2827 dir_fd, follow_symlinks);
2828 else
2829 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002830 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 }
2832 else
2833#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002834 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 }
2836#endif
2837
Larry Hastings2f936352014-08-05 14:04:04 +10002838 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002839}
2840
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841
Christian Heimes4e30a842007-11-30 22:12:06 +00002842#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002843/*[clinic input]
2844os.fchmod
2845
2846 fd: int
2847 mode: int
2848
2849Change the access permissions of the file given by file descriptor fd.
2850
2851Equivalent to os.chmod(fd, mode).
2852[clinic start generated code]*/
2853
Larry Hastings2f936352014-08-05 14:04:04 +10002854static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002855os_fchmod_impl(PyObject *module, int fd, int mode)
2856/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002857{
2858 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002859 int async_err = 0;
2860
2861 do {
2862 Py_BEGIN_ALLOW_THREADS
2863 res = fchmod(fd, mode);
2864 Py_END_ALLOW_THREADS
2865 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2866 if (res != 0)
2867 return (!async_err) ? posix_error() : NULL;
2868
Victor Stinner8c62be82010-05-06 00:08:46 +00002869 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002870}
2871#endif /* HAVE_FCHMOD */
2872
Larry Hastings2f936352014-08-05 14:04:04 +10002873
Christian Heimes4e30a842007-11-30 22:12:06 +00002874#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002875/*[clinic input]
2876os.lchmod
2877
2878 path: path_t
2879 mode: int
2880
2881Change the access permissions of a file, without following symbolic links.
2882
2883If path is a symlink, this affects the link itself rather than the target.
2884Equivalent to chmod(path, mode, follow_symlinks=False)."
2885[clinic start generated code]*/
2886
Larry Hastings2f936352014-08-05 14:04:04 +10002887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002888os_lchmod_impl(PyObject *module, path_t *path, int mode)
2889/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002890{
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002892 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002893 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002894 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002895 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002896 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002897 return NULL;
2898 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002900}
2901#endif /* HAVE_LCHMOD */
2902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903
Thomas Wouterscf297e42007-02-23 15:07:44 +00002904#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002905/*[clinic input]
2906os.chflags
2907
2908 path: path_t
2909 flags: unsigned_long(bitwise=True)
2910 follow_symlinks: bool=True
2911
2912Set file flags.
2913
2914If follow_symlinks is False, and the last element of the path is a symbolic
2915 link, chflags will change flags on the symbolic link itself instead of the
2916 file the link points to.
2917follow_symlinks may not be implemented on your platform. If it is
2918unavailable, using it will raise a NotImplementedError.
2919
2920[clinic start generated code]*/
2921
Larry Hastings2f936352014-08-05 14:04:04 +10002922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002923os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002924 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002925/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002926{
2927 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002928
2929#ifndef HAVE_LCHFLAGS
2930 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002931 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002932#endif
2933
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002935#ifdef HAVE_LCHFLAGS
2936 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002937 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002938 else
2939#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002940 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002942
Larry Hastings2f936352014-08-05 14:04:04 +10002943 if (result)
2944 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002945
Larry Hastings2f936352014-08-05 14:04:04 +10002946 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002947}
2948#endif /* HAVE_CHFLAGS */
2949
Larry Hastings2f936352014-08-05 14:04:04 +10002950
Thomas Wouterscf297e42007-02-23 15:07:44 +00002951#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002952/*[clinic input]
2953os.lchflags
2954
2955 path: path_t
2956 flags: unsigned_long(bitwise=True)
2957
2958Set file flags.
2959
2960This function will not follow symbolic links.
2961Equivalent to chflags(path, flags, follow_symlinks=False).
2962[clinic start generated code]*/
2963
Larry Hastings2f936352014-08-05 14:04:04 +10002964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002965os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2966/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002967{
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002970 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002972 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002973 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002974 }
Victor Stinner292c8352012-10-30 02:17:38 +01002975 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002976}
2977#endif /* HAVE_LCHFLAGS */
2978
Larry Hastings2f936352014-08-05 14:04:04 +10002979
Martin v. Löwis244edc82001-10-04 22:44:26 +00002980#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002981/*[clinic input]
2982os.chroot
2983 path: path_t
2984
2985Change root directory to path.
2986
2987[clinic start generated code]*/
2988
Larry Hastings2f936352014-08-05 14:04:04 +10002989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002990os_chroot_impl(PyObject *module, path_t *path)
2991/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002992{
2993 int res;
2994 Py_BEGIN_ALLOW_THREADS
2995 res = chroot(path->narrow);
2996 Py_END_ALLOW_THREADS
2997 if (res < 0)
2998 return path_error(path);
2999 Py_RETURN_NONE;
3000}
3001#endif /* HAVE_CHROOT */
3002
Martin v. Löwis244edc82001-10-04 22:44:26 +00003003
Guido van Rossum21142a01999-01-08 21:05:37 +00003004#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003005/*[clinic input]
3006os.fsync
3007
3008 fd: fildes
3009
3010Force write of fd to disk.
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_fsync_impl(PyObject *module, int fd)
3015/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
3017 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003018}
3019#endif /* HAVE_FSYNC */
3020
Larry Hastings2f936352014-08-05 14:04:04 +10003021
Ross Lagerwall7807c352011-03-17 20:20:30 +02003022#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003023/*[clinic input]
3024os.sync
3025
3026Force write of everything to disk.
3027[clinic start generated code]*/
3028
Larry Hastings2f936352014-08-05 14:04:04 +10003029static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003030os_sync_impl(PyObject *module)
3031/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003032{
3033 Py_BEGIN_ALLOW_THREADS
3034 sync();
3035 Py_END_ALLOW_THREADS
3036 Py_RETURN_NONE;
3037}
Larry Hastings2f936352014-08-05 14:04:04 +10003038#endif /* HAVE_SYNC */
3039
Ross Lagerwall7807c352011-03-17 20:20:30 +02003040
Guido van Rossum21142a01999-01-08 21:05:37 +00003041#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003042#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003043extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3044#endif
3045
Larry Hastings2f936352014-08-05 14:04:04 +10003046/*[clinic input]
3047os.fdatasync
3048
3049 fd: fildes
3050
3051Force write of fd to disk without forcing update of metadata.
3052[clinic start generated code]*/
3053
Larry Hastings2f936352014-08-05 14:04:04 +10003054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003055os_fdatasync_impl(PyObject *module, int fd)
3056/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003057{
3058 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003059}
3060#endif /* HAVE_FDATASYNC */
3061
3062
Fredrik Lundh10723342000-07-10 16:38:09 +00003063#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003064/*[clinic input]
3065os.chown
3066
3067 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3068 Path to be examined; can be string, bytes, or open-file-descriptor int.
3069
3070 uid: uid_t
3071
3072 gid: gid_t
3073
3074 *
3075
3076 dir_fd : dir_fd(requires='fchownat') = None
3077 If not None, it should be a file descriptor open to a directory,
3078 and path should be relative; path will then be relative to that
3079 directory.
3080
3081 follow_symlinks: bool = True
3082 If False, and the last element of the path is a symbolic link,
3083 stat will examine the symbolic link itself instead of the file
3084 the link points to.
3085
3086Change the owner and group id of path to the numeric uid and gid.\
3087
3088path may always be specified as a string.
3089On some platforms, path may also be specified as an open file descriptor.
3090 If this functionality is unavailable, using it raises an exception.
3091If dir_fd is not None, it should be a file descriptor open to a directory,
3092 and path should be relative; path will then be relative to that directory.
3093If follow_symlinks is False, and the last element of the path is a symbolic
3094 link, chown will modify the symbolic link itself instead of the file the
3095 link points to.
3096It is an error to use dir_fd or follow_symlinks when specifying path as
3097 an open file descriptor.
3098dir_fd and follow_symlinks may not be implemented on your platform.
3099 If they are unavailable, using them will raise a NotImplementedError.
3100
3101[clinic start generated code]*/
3102
Larry Hastings2f936352014-08-05 14:04:04 +10003103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003104os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003105 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003106/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003107{
3108 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003109
3110#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3111 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003112 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003113#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003114 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3115 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3116 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003117
3118#ifdef __APPLE__
3119 /*
3120 * This is for Mac OS X 10.3, which doesn't have lchown.
3121 * (But we still have an lchown symbol because of weak-linking.)
3122 * It doesn't have fchownat either. So there's no possibility
3123 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003124 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003125 if ((!follow_symlinks) && (lchown == NULL)) {
3126 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003127 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003128 }
3129#endif
3130
Victor Stinner8c62be82010-05-06 00:08:46 +00003131 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003132#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003133 if (path->fd != -1)
3134 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135 else
3136#endif
3137#ifdef HAVE_LCHOWN
3138 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003139 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003140 else
3141#endif
3142#ifdef HAVE_FCHOWNAT
3143 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003144 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003145 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3146 else
3147#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003148 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003150
Larry Hastings2f936352014-08-05 14:04:04 +10003151 if (result)
3152 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153
Larry Hastings2f936352014-08-05 14:04:04 +10003154 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003155}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003156#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003157
Larry Hastings2f936352014-08-05 14:04:04 +10003158
Christian Heimes4e30a842007-11-30 22:12:06 +00003159#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003160/*[clinic input]
3161os.fchown
3162
3163 fd: int
3164 uid: uid_t
3165 gid: gid_t
3166
3167Change the owner and group id of the file specified by file descriptor.
3168
3169Equivalent to os.chown(fd, uid, gid).
3170
3171[clinic start generated code]*/
3172
Larry Hastings2f936352014-08-05 14:04:04 +10003173static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003174os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3175/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003176{
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003178 int async_err = 0;
3179
3180 do {
3181 Py_BEGIN_ALLOW_THREADS
3182 res = fchown(fd, uid, gid);
3183 Py_END_ALLOW_THREADS
3184 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3185 if (res != 0)
3186 return (!async_err) ? posix_error() : NULL;
3187
Victor Stinner8c62be82010-05-06 00:08:46 +00003188 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003189}
3190#endif /* HAVE_FCHOWN */
3191
Larry Hastings2f936352014-08-05 14:04:04 +10003192
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003193#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003194/*[clinic input]
3195os.lchown
3196
3197 path : path_t
3198 uid: uid_t
3199 gid: gid_t
3200
3201Change the owner and group id of path to the numeric uid and gid.
3202
3203This function will not follow symbolic links.
3204Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3205[clinic start generated code]*/
3206
Larry Hastings2f936352014-08-05 14:04:04 +10003207static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003208os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3209/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003210{
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003213 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003214 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003215 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003216 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003217 }
Larry Hastings2f936352014-08-05 14:04:04 +10003218 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003219}
3220#endif /* HAVE_LCHOWN */
3221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003222
Barry Warsaw53699e91996-12-10 23:23:01 +00003223static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003224posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003225{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003226 char *buf, *tmpbuf;
3227 char *cwd;
3228 const size_t chunk = 1024;
3229 size_t buflen = 0;
3230 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003231
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003232#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003233 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003234 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 wchar_t *wbuf2 = wbuf;
3236 PyObject *resobj;
3237 DWORD len;
3238 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003239 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 /* If the buffer is large enough, len does not include the
3241 terminating \0. If the buffer is too small, len includes
3242 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003243 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003244 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003245 if (wbuf2)
3246 len = GetCurrentDirectoryW(len, wbuf2);
3247 }
3248 Py_END_ALLOW_THREADS
3249 if (!wbuf2) {
3250 PyErr_NoMemory();
3251 return NULL;
3252 }
3253 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003254 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003255 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003256 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 }
3258 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003259 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003260 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 return resobj;
3262 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003263
3264 if (win32_warn_bytes_api())
3265 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003266#endif
3267
Victor Stinner4403d7d2015-04-25 00:16:10 +02003268 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003270 do {
3271 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003272#ifdef MS_WINDOWS
3273 if (buflen > INT_MAX) {
3274 PyErr_NoMemory();
3275 break;
3276 }
3277#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003278 tmpbuf = PyMem_RawRealloc(buf, buflen);
3279 if (tmpbuf == NULL)
3280 break;
3281
3282 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003283#ifdef MS_WINDOWS
3284 cwd = getcwd(buf, (int)buflen);
3285#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003286 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003287#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003288 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003290
3291 if (cwd == NULL) {
3292 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003294 }
3295
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003297 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3298 else
3299 obj = PyUnicode_DecodeFSDefault(buf);
3300 PyMem_RawFree(buf);
3301
3302 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003303}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003304
Larry Hastings2f936352014-08-05 14:04:04 +10003305
3306/*[clinic input]
3307os.getcwd
3308
3309Return a unicode string representing the current working directory.
3310[clinic start generated code]*/
3311
Larry Hastings2f936352014-08-05 14:04:04 +10003312static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003313os_getcwd_impl(PyObject *module)
3314/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003315{
3316 return posix_getcwd(0);
3317}
3318
Larry Hastings2f936352014-08-05 14:04:04 +10003319
3320/*[clinic input]
3321os.getcwdb
3322
3323Return a bytes string representing the current working directory.
3324[clinic start generated code]*/
3325
Larry Hastings2f936352014-08-05 14:04:04 +10003326static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003327os_getcwdb_impl(PyObject *module)
3328/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003329{
3330 return posix_getcwd(1);
3331}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003332
Larry Hastings2f936352014-08-05 14:04:04 +10003333
Larry Hastings9cf065c2012-06-22 16:30:09 -07003334#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3335#define HAVE_LINK 1
3336#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003337
Guido van Rossumb6775db1994-08-01 11:34:53 +00003338#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003339/*[clinic input]
3340
3341os.link
3342
3343 src : path_t
3344 dst : path_t
3345 *
3346 src_dir_fd : dir_fd = None
3347 dst_dir_fd : dir_fd = None
3348 follow_symlinks: bool = True
3349
3350Create a hard link to a file.
3351
3352If either src_dir_fd or dst_dir_fd is not None, it should be a file
3353 descriptor open to a directory, and the respective path string (src or dst)
3354 should be relative; the path will then be relative to that directory.
3355If follow_symlinks is False, and the last element of src is a symbolic
3356 link, link will create a link to the symbolic link itself instead of the
3357 file the link points to.
3358src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3359 platform. If they are unavailable, using them will raise a
3360 NotImplementedError.
3361[clinic start generated code]*/
3362
Larry Hastings2f936352014-08-05 14:04:04 +10003363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003364os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003365 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003366/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003367{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003369 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003370#else
3371 int result;
3372#endif
3373
Larry Hastings9cf065c2012-06-22 16:30:09 -07003374#ifndef HAVE_LINKAT
3375 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3376 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003377 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378 }
3379#endif
3380
Steve Dowercc16be82016-09-08 10:35:16 -07003381#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003382 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383 PyErr_SetString(PyExc_NotImplementedError,
3384 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003385 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 }
Steve Dowercc16be82016-09-08 10:35:16 -07003387#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003388
Brian Curtin1b9df392010-11-24 20:24:31 +00003389#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003390 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003391 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003393
Larry Hastings2f936352014-08-05 14:04:04 +10003394 if (!result)
3395 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396#else
3397 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003398#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003399 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3400 (dst_dir_fd != DEFAULT_DIR_FD) ||
3401 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003402 result = linkat(src_dir_fd, src->narrow,
3403 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3405 else
Steve Dowercc16be82016-09-08 10:35:16 -07003406#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003407 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003409
Larry Hastings2f936352014-08-05 14:04:04 +10003410 if (result)
3411 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003412#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413
Larry Hastings2f936352014-08-05 14:04:04 +10003414 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003415}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416#endif
3417
Brian Curtin1b9df392010-11-24 20:24:31 +00003418
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003419#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003420static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003421_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003422{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 PyObject *v;
3424 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3425 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003426 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003428 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430
Steve Dowercc16be82016-09-08 10:35:16 -07003431 WIN32_FIND_DATAW wFileData;
3432 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003433
Steve Dowercc16be82016-09-08 10:35:16 -07003434 if (!path->wide) { /* Default arg: "." */
3435 po_wchars = L".";
3436 len = 1;
3437 } else {
3438 po_wchars = path->wide;
3439 len = wcslen(path->wide);
3440 }
3441 /* The +5 is so we can append "\\*.*\0" */
3442 wnamebuf = PyMem_New(wchar_t, len + 5);
3443 if (!wnamebuf) {
3444 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 }
Steve Dowercc16be82016-09-08 10:35:16 -07003447 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003449 wchar_t wch = wnamebuf[len-1];
3450 if (wch != SEP && wch != ALTSEP && wch != L':')
3451 wnamebuf[len++] = SEP;
3452 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003453 }
Steve Dowercc16be82016-09-08 10:35:16 -07003454 if ((list = PyList_New(0)) == NULL) {
3455 goto exit;
3456 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003457 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003458 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003459 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 if (hFindFile == INVALID_HANDLE_VALUE) {
3461 int error = GetLastError();
3462 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 goto exit;
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 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003467 }
3468 do {
3469 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003470 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3471 wcscmp(wFileData.cFileName, L"..") != 0) {
3472 v = PyUnicode_FromWideChar(wFileData.cFileName,
3473 wcslen(wFileData.cFileName));
3474 if (path->narrow && v) {
3475 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3476 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 Py_DECREF(list);
3479 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 break;
3481 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003483 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484 Py_DECREF(list);
3485 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 break;
3487 }
3488 Py_DECREF(v);
3489 }
3490 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003491 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 Py_END_ALLOW_THREADS
3493 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3494 it got to the end of the directory. */
3495 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003497 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 }
3500 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003501
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502exit:
3503 if (hFindFile != INVALID_HANDLE_VALUE) {
3504 if (FindClose(hFindFile) == FALSE) {
3505 if (list != NULL) {
3506 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003507 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 }
3509 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003511 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003512
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003514} /* end of _listdir_windows_no_opendir */
3515
3516#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3517
3518static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003519_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003520{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003521 PyObject *v;
3522 DIR *dirp = NULL;
3523 struct dirent *ep;
3524 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003525#ifdef HAVE_FDOPENDIR
3526 int fd = -1;
3527#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003528
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003533 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003534 if (fd == -1)
3535 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536
Larry Hastingsfdaea062012-06-25 04:42:23 -07003537 return_str = 1;
3538
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 Py_BEGIN_ALLOW_THREADS
3540 dirp = fdopendir(fd);
3541 Py_END_ALLOW_THREADS
3542 }
3543 else
3544#endif
3545 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003546 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003547 if (path->narrow) {
3548 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003549 /* only return bytes if they specified a bytes-like object */
3550 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003551 }
3552 else {
3553 name = ".";
3554 return_str = 1;
3555 }
3556
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 Py_BEGIN_ALLOW_THREADS
3558 dirp = opendir(name);
3559 Py_END_ALLOW_THREADS
3560 }
3561
3562 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003563 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003564#ifdef HAVE_FDOPENDIR
3565 if (fd != -1) {
3566 Py_BEGIN_ALLOW_THREADS
3567 close(fd);
3568 Py_END_ALLOW_THREADS
3569 }
3570#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 goto exit;
3572 }
3573 if ((list = PyList_New(0)) == NULL) {
3574 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 }
3576 for (;;) {
3577 errno = 0;
3578 Py_BEGIN_ALLOW_THREADS
3579 ep = readdir(dirp);
3580 Py_END_ALLOW_THREADS
3581 if (ep == NULL) {
3582 if (errno == 0) {
3583 break;
3584 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003586 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 }
3589 }
3590 if (ep->d_name[0] == '.' &&
3591 (NAMLEN(ep) == 1 ||
3592 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3593 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003594 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003595 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3596 else
3597 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 break;
3601 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 break;
3606 }
3607 Py_DECREF(v);
3608 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003609
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610exit:
3611 if (dirp != NULL) {
3612 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003613#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614 if (fd > -1)
3615 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003616#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 closedir(dirp);
3618 Py_END_ALLOW_THREADS
3619 }
3620
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003622} /* end of _posix_listdir */
3623#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003624
Larry Hastings2f936352014-08-05 14:04:04 +10003625
3626/*[clinic input]
3627os.listdir
3628
3629 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3630
3631Return a list containing the names of the files in the directory.
3632
3633path can be specified as either str or bytes. If path is bytes,
3634 the filenames returned will also be bytes; in all other circumstances
3635 the filenames returned will be str.
3636If path is None, uses the path='.'.
3637On some platforms, path may also be specified as an open file descriptor;\
3638 the file descriptor must refer to a directory.
3639 If this functionality is unavailable, using it raises NotImplementedError.
3640
3641The list is in arbitrary order. It does not include the special
3642entries '.' and '..' even if they are present in the directory.
3643
3644
3645[clinic start generated code]*/
3646
Larry Hastings2f936352014-08-05 14:04:04 +10003647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003648os_listdir_impl(PyObject *module, path_t *path)
3649/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003650{
3651#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3652 return _listdir_windows_no_opendir(path, NULL);
3653#else
3654 return _posix_listdir(path, NULL);
3655#endif
3656}
3657
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003658#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003659/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003660/*[clinic input]
3661os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003662
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003663 path: path_t
3664 /
3665
3666[clinic start generated code]*/
3667
3668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003669os__getfullpathname_impl(PyObject *module, path_t *path)
3670/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003671{
Steve Dowercc16be82016-09-08 10:35:16 -07003672 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3673 wchar_t *wtemp;
3674 DWORD result;
3675 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003676
Steve Dowercc16be82016-09-08 10:35:16 -07003677 result = GetFullPathNameW(path->wide,
3678 Py_ARRAY_LENGTH(woutbuf),
3679 woutbuf, &wtemp);
3680 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3681 woutbufp = PyMem_New(wchar_t, result);
3682 if (!woutbufp)
3683 return PyErr_NoMemory();
3684 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003685 }
Steve Dowercc16be82016-09-08 10:35:16 -07003686 if (result) {
3687 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3688 if (path->narrow)
3689 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3690 } else
3691 v = win32_error_object("GetFullPathNameW", path->object);
3692 if (woutbufp != woutbuf)
3693 PyMem_Free(woutbufp);
3694 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003695}
Brian Curtind40e6f72010-07-08 21:39:08 +00003696
Brian Curtind25aef52011-06-13 15:16:04 -05003697
Larry Hastings2f936352014-08-05 14:04:04 +10003698/*[clinic input]
3699os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003700
Larry Hastings2f936352014-08-05 14:04:04 +10003701 path: unicode
3702 /
3703
3704A helper function for samepath on windows.
3705[clinic start generated code]*/
3706
Larry Hastings2f936352014-08-05 14:04:04 +10003707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003708os__getfinalpathname_impl(PyObject *module, PyObject *path)
3709/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003710{
3711 HANDLE hFile;
3712 int buf_size;
3713 wchar_t *target_path;
3714 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003715 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003716 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003717
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03003718 path_wchar = _PyUnicode_AsUnicode(path);
Larry Hastings2f936352014-08-05 14:04:04 +10003719 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003720 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003721
Brian Curtind40e6f72010-07-08 21:39:08 +00003722 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003723 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003724 0, /* desired access */
3725 0, /* share mode */
3726 NULL, /* security attributes */
3727 OPEN_EXISTING,
3728 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3729 FILE_FLAG_BACKUP_SEMANTICS,
3730 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003731
Victor Stinnereb5657a2011-09-30 01:44:27 +02003732 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003733 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003734
3735 /* We have a good handle to the target, use it to determine the
3736 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003737 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003738
3739 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003740 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003741
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003742 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003743 if(!target_path)
3744 return PyErr_NoMemory();
3745
Steve Dower2ea51c92015-03-20 21:49:12 -07003746 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3747 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003748 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003749 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003750
3751 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003752 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003753
3754 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003755 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003756 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003757 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003758}
Brian Curtin62857742010-09-06 17:07:27 +00003759
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003760/*[clinic input]
3761os._isdir
3762
3763 path: path_t
3764 /
3765
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003766Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003767[clinic start generated code]*/
3768
Brian Curtin9c669cc2011-06-08 18:17:18 -05003769static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003770os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003771/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003772{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003773 DWORD attributes;
3774
Steve Dowerb22a6772016-07-17 20:49:38 -07003775 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003776 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003777 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003778
Brian Curtin9c669cc2011-06-08 18:17:18 -05003779 if (attributes == INVALID_FILE_ATTRIBUTES)
3780 Py_RETURN_FALSE;
3781
Brian Curtin9c669cc2011-06-08 18:17:18 -05003782 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3783 Py_RETURN_TRUE;
3784 else
3785 Py_RETURN_FALSE;
3786}
Tim Golden6b528062013-08-01 12:44:00 +01003787
Tim Golden6b528062013-08-01 12:44:00 +01003788
Larry Hastings2f936352014-08-05 14:04:04 +10003789/*[clinic input]
3790os._getvolumepathname
3791
3792 path: unicode
3793
3794A helper function for ismount on Win32.
3795[clinic start generated code]*/
3796
Larry Hastings2f936352014-08-05 14:04:04 +10003797static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003798os__getvolumepathname_impl(PyObject *module, PyObject *path)
3799/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003800{
3801 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003802 const wchar_t *path_wchar;
3803 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003804 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003805 BOOL ret;
3806
Larry Hastings2f936352014-08-05 14:04:04 +10003807 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3808 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003809 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003810 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003811
3812 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003813 buflen = Py_MAX(buflen, MAX_PATH);
3814
Victor Stinner850a18e2017-10-24 16:53:32 -07003815 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003816 PyErr_SetString(PyExc_OverflowError, "path too long");
3817 return NULL;
3818 }
3819
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003820 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003821 if (mountpath == NULL)
3822 return PyErr_NoMemory();
3823
3824 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003825 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003826 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003827 Py_END_ALLOW_THREADS
3828
3829 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003830 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003831 goto exit;
3832 }
3833 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3834
3835exit:
3836 PyMem_Free(mountpath);
3837 return result;
3838}
Tim Golden6b528062013-08-01 12:44:00 +01003839
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003840#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003841
Larry Hastings2f936352014-08-05 14:04:04 +10003842
3843/*[clinic input]
3844os.mkdir
3845
3846 path : path_t
3847
3848 mode: int = 0o777
3849
3850 *
3851
3852 dir_fd : dir_fd(requires='mkdirat') = None
3853
3854# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3855
3856Create a directory.
3857
3858If dir_fd is not None, it should be a file descriptor open to a directory,
3859 and path should be relative; path will then be relative to that directory.
3860dir_fd may not be implemented on your platform.
3861 If it is unavailable, using it will raise a NotImplementedError.
3862
3863The mode argument is ignored on Windows.
3864[clinic start generated code]*/
3865
Larry Hastings2f936352014-08-05 14:04:04 +10003866static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003867os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3868/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003869{
3870 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003871
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003872#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003874 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003875 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003876
Larry Hastings2f936352014-08-05 14:04:04 +10003877 if (!result)
3878 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003881#if HAVE_MKDIRAT
3882 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003883 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003884 else
3885#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003886#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003887 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003888#else
Larry Hastings2f936352014-08-05 14:04:04 +10003889 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003892 if (result < 0)
3893 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003894#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003895 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003896}
3897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003898
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003899/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3900#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003901#include <sys/resource.h>
3902#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003903
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003904
3905#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003906/*[clinic input]
3907os.nice
3908
3909 increment: int
3910 /
3911
3912Add increment to the priority of process and return the new priority.
3913[clinic start generated code]*/
3914
Larry Hastings2f936352014-08-05 14:04:04 +10003915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003916os_nice_impl(PyObject *module, int increment)
3917/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003918{
3919 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003920
Victor Stinner8c62be82010-05-06 00:08:46 +00003921 /* There are two flavours of 'nice': one that returns the new
3922 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003923 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003925
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 If we are of the nice family that returns the new priority, we
3927 need to clear errno before the call, and check if errno is filled
3928 before calling posix_error() on a returnvalue of -1, because the
3929 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003930
Victor Stinner8c62be82010-05-06 00:08:46 +00003931 errno = 0;
3932 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003933#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 if (value == 0)
3935 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003936#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003937 if (value == -1 && errno != 0)
3938 /* either nice() or getpriority() returned an error */
3939 return posix_error();
3940 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003941}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003942#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003943
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003944
3945#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003946/*[clinic input]
3947os.getpriority
3948
3949 which: int
3950 who: int
3951
3952Return program scheduling priority.
3953[clinic start generated code]*/
3954
Larry Hastings2f936352014-08-05 14:04:04 +10003955static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003956os_getpriority_impl(PyObject *module, int which, int who)
3957/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003958{
3959 int retval;
3960
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003961 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003962 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003963 if (errno != 0)
3964 return posix_error();
3965 return PyLong_FromLong((long)retval);
3966}
3967#endif /* HAVE_GETPRIORITY */
3968
3969
3970#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003971/*[clinic input]
3972os.setpriority
3973
3974 which: int
3975 who: int
3976 priority: int
3977
3978Set program scheduling priority.
3979[clinic start generated code]*/
3980
Larry Hastings2f936352014-08-05 14:04:04 +10003981static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003982os_setpriority_impl(PyObject *module, int which, int who, int priority)
3983/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003984{
3985 int retval;
3986
3987 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003988 if (retval == -1)
3989 return posix_error();
3990 Py_RETURN_NONE;
3991}
3992#endif /* HAVE_SETPRIORITY */
3993
3994
Barry Warsaw53699e91996-12-10 23:23:01 +00003995static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003996internal_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 +00003997{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003998 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004000
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004001#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004003 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004004#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004006#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007
Larry Hastings9cf065c2012-06-22 16:30:09 -07004008 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4009 (dst_dir_fd != DEFAULT_DIR_FD);
4010#ifndef HAVE_RENAMEAT
4011 if (dir_fd_specified) {
4012 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004013 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004014 }
4015#endif
4016
Larry Hastings9cf065c2012-06-22 16:30:09 -07004017#ifdef MS_WINDOWS
4018 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004019 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004020 Py_END_ALLOW_THREADS
4021
Larry Hastings2f936352014-08-05 14:04:04 +10004022 if (!result)
4023 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004024
4025#else
Steve Dowercc16be82016-09-08 10:35:16 -07004026 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4027 PyErr_Format(PyExc_ValueError,
4028 "%s: src and dst must be the same type", function_name);
4029 return NULL;
4030 }
4031
Larry Hastings9cf065c2012-06-22 16:30:09 -07004032 Py_BEGIN_ALLOW_THREADS
4033#ifdef HAVE_RENAMEAT
4034 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004035 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004036 else
4037#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004038 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004039 Py_END_ALLOW_THREADS
4040
Larry Hastings2f936352014-08-05 14:04:04 +10004041 if (result)
4042 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004043#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004044 Py_RETURN_NONE;
4045}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046
Larry Hastings2f936352014-08-05 14:04:04 +10004047
4048/*[clinic input]
4049os.rename
4050
4051 src : path_t
4052 dst : path_t
4053 *
4054 src_dir_fd : dir_fd = None
4055 dst_dir_fd : dir_fd = None
4056
4057Rename a file or directory.
4058
4059If either src_dir_fd or dst_dir_fd is not None, it should be a file
4060 descriptor open to a directory, and the respective path string (src or dst)
4061 should be relative; the path will then be relative to that directory.
4062src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4063 If they are unavailable, using them will raise a NotImplementedError.
4064[clinic start generated code]*/
4065
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004067os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004068 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004069/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004070{
Larry Hastings2f936352014-08-05 14:04:04 +10004071 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004072}
4073
Larry Hastings2f936352014-08-05 14:04:04 +10004074
4075/*[clinic input]
4076os.replace = os.rename
4077
4078Rename a file or directory, overwriting the destination.
4079
4080If either src_dir_fd or dst_dir_fd is not None, it should be a file
4081 descriptor open to a directory, and the respective path string (src or dst)
4082 should be relative; the path will then be relative to that directory.
4083src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4084 If they are unavailable, using them will raise a NotImplementedError."
4085[clinic start generated code]*/
4086
Larry Hastings2f936352014-08-05 14:04:04 +10004087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004088os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4089 int dst_dir_fd)
4090/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004091{
4092 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4093}
4094
4095
4096/*[clinic input]
4097os.rmdir
4098
4099 path: path_t
4100 *
4101 dir_fd: dir_fd(requires='unlinkat') = None
4102
4103Remove a directory.
4104
4105If dir_fd is not None, it should be a file descriptor open to a directory,
4106 and path should be relative; path will then be relative to that directory.
4107dir_fd may not be implemented on your platform.
4108 If it is unavailable, using it will raise a NotImplementedError.
4109[clinic start generated code]*/
4110
Larry Hastings2f936352014-08-05 14:04:04 +10004111static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004112os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4113/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004114{
4115 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004116
4117 Py_BEGIN_ALLOW_THREADS
4118#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004119 /* Windows, success=1, UNIX, success=0 */
4120 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004121#else
4122#ifdef HAVE_UNLINKAT
4123 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004124 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004125 else
4126#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004127 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004128#endif
4129 Py_END_ALLOW_THREADS
4130
Larry Hastings2f936352014-08-05 14:04:04 +10004131 if (result)
4132 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004133
Larry Hastings2f936352014-08-05 14:04:04 +10004134 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004135}
4136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004137
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004138#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004139#ifdef MS_WINDOWS
4140/*[clinic input]
4141os.system -> long
4142
4143 command: Py_UNICODE
4144
4145Execute the command in a subshell.
4146[clinic start generated code]*/
4147
Larry Hastings2f936352014-08-05 14:04:04 +10004148static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004149os_system_impl(PyObject *module, Py_UNICODE *command)
4150/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004151{
4152 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004153 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004154 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004155 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004156 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004157 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004158 return result;
4159}
4160#else /* MS_WINDOWS */
4161/*[clinic input]
4162os.system -> long
4163
4164 command: FSConverter
4165
4166Execute the command in a subshell.
4167[clinic start generated code]*/
4168
Larry Hastings2f936352014-08-05 14:04:04 +10004169static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004170os_system_impl(PyObject *module, PyObject *command)
4171/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004172{
4173 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004174 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004175 Py_BEGIN_ALLOW_THREADS
4176 result = system(bytes);
4177 Py_END_ALLOW_THREADS
4178 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004179}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004180#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004181#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004182
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004183
Larry Hastings2f936352014-08-05 14:04:04 +10004184/*[clinic input]
4185os.umask
4186
4187 mask: int
4188 /
4189
4190Set the current numeric umask and return the previous umask.
4191[clinic start generated code]*/
4192
Larry Hastings2f936352014-08-05 14:04:04 +10004193static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004194os_umask_impl(PyObject *module, int mask)
4195/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004196{
4197 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004198 if (i < 0)
4199 return posix_error();
4200 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004201}
4202
Brian Curtind40e6f72010-07-08 21:39:08 +00004203#ifdef MS_WINDOWS
4204
4205/* override the default DeleteFileW behavior so that directory
4206symlinks can be removed with this function, the same as with
4207Unix symlinks */
4208BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4209{
4210 WIN32_FILE_ATTRIBUTE_DATA info;
4211 WIN32_FIND_DATAW find_data;
4212 HANDLE find_data_handle;
4213 int is_directory = 0;
4214 int is_link = 0;
4215
4216 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4217 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004218
Brian Curtind40e6f72010-07-08 21:39:08 +00004219 /* Get WIN32_FIND_DATA structure for the path to determine if
4220 it is a symlink */
4221 if(is_directory &&
4222 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4223 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4224
4225 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004226 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4227 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4228 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4229 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004230 FindClose(find_data_handle);
4231 }
4232 }
4233 }
4234
4235 if (is_directory && is_link)
4236 return RemoveDirectoryW(lpFileName);
4237
4238 return DeleteFileW(lpFileName);
4239}
4240#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004242
Larry Hastings2f936352014-08-05 14:04:04 +10004243/*[clinic input]
4244os.unlink
4245
4246 path: path_t
4247 *
4248 dir_fd: dir_fd(requires='unlinkat')=None
4249
4250Remove a file (same as remove()).
4251
4252If dir_fd is not None, it should be a file descriptor open to a directory,
4253 and path should be relative; path will then be relative to that directory.
4254dir_fd may not be implemented on your platform.
4255 If it is unavailable, using it will raise a NotImplementedError.
4256
4257[clinic start generated code]*/
4258
Larry Hastings2f936352014-08-05 14:04:04 +10004259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004260os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4261/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004262{
4263 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004264
4265 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004266 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004267#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004268 /* Windows, success=1, UNIX, success=0 */
4269 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004270#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004271#ifdef HAVE_UNLINKAT
4272 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004273 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004274 else
4275#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004276 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004277#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004278 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004279 Py_END_ALLOW_THREADS
4280
Larry Hastings2f936352014-08-05 14:04:04 +10004281 if (result)
4282 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004283
Larry Hastings2f936352014-08-05 14:04:04 +10004284 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004285}
4286
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004287
Larry Hastings2f936352014-08-05 14:04:04 +10004288/*[clinic input]
4289os.remove = os.unlink
4290
4291Remove a file (same as unlink()).
4292
4293If dir_fd is not None, it should be a file descriptor open to a directory,
4294 and path should be relative; path will then be relative to that directory.
4295dir_fd may not be implemented on your platform.
4296 If it is unavailable, using it will raise a NotImplementedError.
4297[clinic start generated code]*/
4298
Larry Hastings2f936352014-08-05 14:04:04 +10004299static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004300os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4301/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004302{
4303 return os_unlink_impl(module, path, dir_fd);
4304}
4305
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004306
Larry Hastings605a62d2012-06-24 04:33:36 -07004307static PyStructSequence_Field uname_result_fields[] = {
4308 {"sysname", "operating system name"},
4309 {"nodename", "name of machine on network (implementation-defined)"},
4310 {"release", "operating system release"},
4311 {"version", "operating system version"},
4312 {"machine", "hardware identifier"},
4313 {NULL}
4314};
4315
4316PyDoc_STRVAR(uname_result__doc__,
4317"uname_result: Result from os.uname().\n\n\
4318This object may be accessed either as a tuple of\n\
4319 (sysname, nodename, release, version, machine),\n\
4320or via the attributes sysname, nodename, release, version, and machine.\n\
4321\n\
4322See os.uname for more information.");
4323
4324static PyStructSequence_Desc uname_result_desc = {
4325 "uname_result", /* name */
4326 uname_result__doc__, /* doc */
4327 uname_result_fields,
4328 5
4329};
4330
4331static PyTypeObject UnameResultType;
4332
4333
4334#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004335/*[clinic input]
4336os.uname
4337
4338Return an object identifying the current operating system.
4339
4340The object behaves like a named tuple with the following fields:
4341 (sysname, nodename, release, version, machine)
4342
4343[clinic start generated code]*/
4344
Larry Hastings2f936352014-08-05 14:04:04 +10004345static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004346os_uname_impl(PyObject *module)
4347/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004348{
Victor Stinner8c62be82010-05-06 00:08:46 +00004349 struct utsname u;
4350 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004351 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004352
Victor Stinner8c62be82010-05-06 00:08:46 +00004353 Py_BEGIN_ALLOW_THREADS
4354 res = uname(&u);
4355 Py_END_ALLOW_THREADS
4356 if (res < 0)
4357 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004358
4359 value = PyStructSequence_New(&UnameResultType);
4360 if (value == NULL)
4361 return NULL;
4362
4363#define SET(i, field) \
4364 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004365 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004366 if (!o) { \
4367 Py_DECREF(value); \
4368 return NULL; \
4369 } \
4370 PyStructSequence_SET_ITEM(value, i, o); \
4371 } \
4372
4373 SET(0, u.sysname);
4374 SET(1, u.nodename);
4375 SET(2, u.release);
4376 SET(3, u.version);
4377 SET(4, u.machine);
4378
4379#undef SET
4380
4381 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004382}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004383#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004384
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004385
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386
4387typedef struct {
4388 int now;
4389 time_t atime_s;
4390 long atime_ns;
4391 time_t mtime_s;
4392 long mtime_ns;
4393} utime_t;
4394
4395/*
Victor Stinner484df002014-10-09 13:52:31 +02004396 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397 * they also intentionally leak the declaration of a pointer named "time"
4398 */
4399#define UTIME_TO_TIMESPEC \
4400 struct timespec ts[2]; \
4401 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004402 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403 time = NULL; \
4404 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004405 ts[0].tv_sec = ut->atime_s; \
4406 ts[0].tv_nsec = ut->atime_ns; \
4407 ts[1].tv_sec = ut->mtime_s; \
4408 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409 time = ts; \
4410 } \
4411
4412#define UTIME_TO_TIMEVAL \
4413 struct timeval tv[2]; \
4414 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004415 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004416 time = NULL; \
4417 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004418 tv[0].tv_sec = ut->atime_s; \
4419 tv[0].tv_usec = ut->atime_ns / 1000; \
4420 tv[1].tv_sec = ut->mtime_s; \
4421 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004422 time = tv; \
4423 } \
4424
4425#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004426 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004427 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004428 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004429 time = NULL; \
4430 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004431 u.actime = ut->atime_s; \
4432 u.modtime = ut->mtime_s; \
4433 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004434 }
4435
4436#define UTIME_TO_TIME_T \
4437 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004438 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004439 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004440 time = NULL; \
4441 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004442 timet[0] = ut->atime_s; \
4443 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004444 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004445 } \
4446
4447
Victor Stinner528a9ab2015-09-03 21:30:26 +02004448#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004449
4450static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004451utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004452{
4453#ifdef HAVE_UTIMENSAT
4454 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4455 UTIME_TO_TIMESPEC;
4456 return utimensat(dir_fd, path, time, flags);
4457#elif defined(HAVE_FUTIMESAT)
4458 UTIME_TO_TIMEVAL;
4459 /*
4460 * follow_symlinks will never be false here;
4461 * we only allow !follow_symlinks and dir_fd together
4462 * if we have utimensat()
4463 */
4464 assert(follow_symlinks);
4465 return futimesat(dir_fd, path, time);
4466#endif
4467}
4468
Larry Hastings2f936352014-08-05 14:04:04 +10004469 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4470#else
4471 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004472#endif
4473
Victor Stinner528a9ab2015-09-03 21:30:26 +02004474#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475
4476static int
Victor Stinner484df002014-10-09 13:52:31 +02004477utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004478{
4479#ifdef HAVE_FUTIMENS
4480 UTIME_TO_TIMESPEC;
4481 return futimens(fd, time);
4482#else
4483 UTIME_TO_TIMEVAL;
4484 return futimes(fd, time);
4485#endif
4486}
4487
Larry Hastings2f936352014-08-05 14:04:04 +10004488 #define PATH_UTIME_HAVE_FD 1
4489#else
4490 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004491#endif
4492
Victor Stinner5ebae872015-09-22 01:29:33 +02004493#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4494# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4495#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496
Victor Stinner4552ced2015-09-21 22:37:15 +02004497#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004498
4499static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004500utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004501{
4502#ifdef HAVE_UTIMENSAT
4503 UTIME_TO_TIMESPEC;
4504 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4505#else
4506 UTIME_TO_TIMEVAL;
4507 return lutimes(path, time);
4508#endif
4509}
4510
4511#endif
4512
4513#ifndef MS_WINDOWS
4514
4515static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004516utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517{
4518#ifdef HAVE_UTIMENSAT
4519 UTIME_TO_TIMESPEC;
4520 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4521#elif defined(HAVE_UTIMES)
4522 UTIME_TO_TIMEVAL;
4523 return utimes(path, time);
4524#elif defined(HAVE_UTIME_H)
4525 UTIME_TO_UTIMBUF;
4526 return utime(path, time);
4527#else
4528 UTIME_TO_TIME_T;
4529 return utime(path, time);
4530#endif
4531}
4532
4533#endif
4534
Larry Hastings76ad59b2012-05-03 00:30:07 -07004535static int
4536split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4537{
4538 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004539 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004540 divmod = PyNumber_Divmod(py_long, billion);
4541 if (!divmod)
4542 goto exit;
4543 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4544 if ((*s == -1) && PyErr_Occurred())
4545 goto exit;
4546 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004547 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004548 goto exit;
4549
4550 result = 1;
4551exit:
4552 Py_XDECREF(divmod);
4553 return result;
4554}
4555
Larry Hastings2f936352014-08-05 14:04:04 +10004556
4557/*[clinic input]
4558os.utime
4559
4560 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4561 times: object = NULL
4562 *
4563 ns: object = NULL
4564 dir_fd: dir_fd(requires='futimensat') = None
4565 follow_symlinks: bool=True
4566
Martin Panter0ff89092015-09-09 01:56:53 +00004567# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004568
4569Set the access and modified time of path.
4570
4571path may always be specified as a string.
4572On some platforms, path may also be specified as an open file descriptor.
4573 If this functionality is unavailable, using it raises an exception.
4574
4575If times is not None, it must be a tuple (atime, mtime);
4576 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004577If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004578 atime_ns and mtime_ns should be expressed as integer nanoseconds
4579 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004580If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004581Specifying tuples for both times and ns is an error.
4582
4583If dir_fd is not None, it should be a file descriptor open to a directory,
4584 and path should be relative; path will then be relative to that directory.
4585If follow_symlinks is False, and the last element of the path is a symbolic
4586 link, utime will modify the symbolic link itself instead of the file the
4587 link points to.
4588It is an error to use dir_fd or follow_symlinks when specifying path
4589 as an open file descriptor.
4590dir_fd and follow_symlinks may not be available on your platform.
4591 If they are unavailable, using them will raise a NotImplementedError.
4592
4593[clinic start generated code]*/
4594
Larry Hastings2f936352014-08-05 14:04:04 +10004595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004596os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4597 int dir_fd, int follow_symlinks)
4598/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004599{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600#ifdef MS_WINDOWS
4601 HANDLE hFile;
4602 FILETIME atime, mtime;
4603#else
4604 int result;
4605#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004606
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004608 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004609
Christian Heimesb3c87242013-08-01 00:08:16 +02004610 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004611
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612 if (times && (times != Py_None) && ns) {
4613 PyErr_SetString(PyExc_ValueError,
4614 "utime: you may specify either 'times'"
4615 " or 'ns' but not both");
4616 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004617 }
4618
4619 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004620 time_t a_sec, m_sec;
4621 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004622 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004623 PyErr_SetString(PyExc_TypeError,
4624 "utime: 'times' must be either"
4625 " a tuple of two ints or None");
4626 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004627 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004629 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004630 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004631 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004632 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004634 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004635 utime.atime_s = a_sec;
4636 utime.atime_ns = a_nsec;
4637 utime.mtime_s = m_sec;
4638 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004639 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004640 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004641 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 PyErr_SetString(PyExc_TypeError,
4643 "utime: 'ns' must be a tuple of two ints");
4644 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004645 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004647 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004649 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004650 &utime.mtime_s, &utime.mtime_ns)) {
4651 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004652 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653 }
4654 else {
4655 /* times and ns are both None/unspecified. use "now". */
4656 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004657 }
4658
Victor Stinner4552ced2015-09-21 22:37:15 +02004659#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004660 if (follow_symlinks_specified("utime", follow_symlinks))
4661 goto exit;
4662#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004663
Larry Hastings2f936352014-08-05 14:04:04 +10004664 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4665 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4666 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004667 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669#if !defined(HAVE_UTIMENSAT)
4670 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004671 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004672 "utime: cannot use dir_fd and follow_symlinks "
4673 "together on this platform");
4674 goto exit;
4675 }
4676#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004677
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004678#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004679 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004680 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4681 NULL, OPEN_EXISTING,
4682 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 Py_END_ALLOW_THREADS
4684 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004685 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004687 }
4688
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004690 GetSystemTimeAsFileTime(&mtime);
4691 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004692 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004693 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004694 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4695 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004696 }
4697 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4698 /* Avoid putting the file name into the error here,
4699 as that may confuse the user into believing that
4700 something is wrong with the file, when it also
4701 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004702 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004705#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004707
Victor Stinner4552ced2015-09-21 22:37:15 +02004708#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004710 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004711 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004712#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713
Victor Stinner528a9ab2015-09-03 21:30:26 +02004714#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004716 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717 else
4718#endif
4719
Victor Stinner528a9ab2015-09-03 21:30:26 +02004720#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004721 if (path->fd != -1)
4722 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004723 else
4724#endif
4725
Larry Hastings2f936352014-08-05 14:04:04 +10004726 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727
4728 Py_END_ALLOW_THREADS
4729
4730 if (result < 0) {
4731 /* see previous comment about not putting filename in error here */
4732 return_value = posix_error();
4733 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004736#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737
4738 Py_INCREF(Py_None);
4739 return_value = Py_None;
4740
4741exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742#ifdef MS_WINDOWS
4743 if (hFile != INVALID_HANDLE_VALUE)
4744 CloseHandle(hFile);
4745#endif
4746 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004747}
4748
Guido van Rossum3b066191991-06-04 19:40:25 +00004749/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004750
Larry Hastings2f936352014-08-05 14:04:04 +10004751
4752/*[clinic input]
4753os._exit
4754
4755 status: int
4756
4757Exit to the system with specified status, without normal exit processing.
4758[clinic start generated code]*/
4759
Larry Hastings2f936352014-08-05 14:04:04 +10004760static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004761os__exit_impl(PyObject *module, int status)
4762/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004763{
4764 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004765 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004766}
4767
Steve Dowercc16be82016-09-08 10:35:16 -07004768#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4769#define EXECV_CHAR wchar_t
4770#else
4771#define EXECV_CHAR char
4772#endif
4773
Martin v. Löwis114619e2002-10-07 06:44:21 +00004774#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4775static void
Steve Dowercc16be82016-09-08 10:35:16 -07004776free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004777{
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 Py_ssize_t i;
4779 for (i = 0; i < count; i++)
4780 PyMem_Free(array[i]);
4781 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004782}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004783
Berker Peksag81816462016-09-15 20:19:47 +03004784static int
4785fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004786{
Victor Stinner8c62be82010-05-06 00:08:46 +00004787 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004788 PyObject *ub;
4789 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004790#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004791 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004792 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004793 *out = PyUnicode_AsWideCharString(ub, &size);
4794 if (*out)
4795 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004796#else
Berker Peksag81816462016-09-15 20:19:47 +03004797 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004799 size = PyBytes_GET_SIZE(ub);
4800 *out = PyMem_Malloc(size + 1);
4801 if (*out) {
4802 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4803 result = 1;
4804 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004805 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004806#endif
Berker Peksag81816462016-09-15 20:19:47 +03004807 Py_DECREF(ub);
4808 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004809}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004810#endif
4811
Ross Lagerwall7807c352011-03-17 20:20:30 +02004812#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004813static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004814parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4815{
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 Py_ssize_t i, pos, envc;
4817 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004818 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004819 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004820
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 i = PyMapping_Size(env);
4822 if (i < 0)
4823 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004824 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004825 if (envlist == NULL) {
4826 PyErr_NoMemory();
4827 return NULL;
4828 }
4829 envc = 0;
4830 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004831 if (!keys)
4832 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004833 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004834 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 goto error;
4836 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4837 PyErr_Format(PyExc_TypeError,
4838 "env.keys() or env.values() is not a list");
4839 goto error;
4840 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004841
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 for (pos = 0; pos < i; pos++) {
4843 key = PyList_GetItem(keys, pos);
4844 val = PyList_GetItem(vals, pos);
4845 if (!key || !val)
4846 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004847
Berker Peksag81816462016-09-15 20:19:47 +03004848#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4849 if (!PyUnicode_FSDecoder(key, &key2))
4850 goto error;
4851 if (!PyUnicode_FSDecoder(val, &val2)) {
4852 Py_DECREF(key2);
4853 goto error;
4854 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004855 /* Search from index 1 because on Windows starting '=' is allowed for
4856 defining hidden environment variables. */
4857 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4858 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4859 {
4860 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004861 Py_DECREF(key2);
4862 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004863 goto error;
4864 }
Berker Peksag81816462016-09-15 20:19:47 +03004865 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4866#else
4867 if (!PyUnicode_FSConverter(key, &key2))
4868 goto error;
4869 if (!PyUnicode_FSConverter(val, &val2)) {
4870 Py_DECREF(key2);
4871 goto error;
4872 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004873 if (PyBytes_GET_SIZE(key2) == 0 ||
4874 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4875 {
4876 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004877 Py_DECREF(key2);
4878 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004879 goto error;
4880 }
Berker Peksag81816462016-09-15 20:19:47 +03004881 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4882 PyBytes_AS_STRING(val2));
4883#endif
4884 Py_DECREF(key2);
4885 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004886 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004887 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004888
4889 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4890 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 goto error;
4892 }
Berker Peksag81816462016-09-15 20:19:47 +03004893
Steve Dowercc16be82016-09-08 10:35:16 -07004894 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004895 }
4896 Py_DECREF(vals);
4897 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004898
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 envlist[envc] = 0;
4900 *envc_ptr = envc;
4901 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004902
4903error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004904 Py_XDECREF(keys);
4905 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004906 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004907 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004908}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004909
Steve Dowercc16be82016-09-08 10:35:16 -07004910static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004911parse_arglist(PyObject* argv, Py_ssize_t *argc)
4912{
4913 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004914 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004915 if (argvlist == NULL) {
4916 PyErr_NoMemory();
4917 return NULL;
4918 }
4919 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004920 PyObject* item = PySequence_ITEM(argv, i);
4921 if (item == NULL)
4922 goto fail;
4923 if (!fsconvert_strdup(item, &argvlist[i])) {
4924 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004925 goto fail;
4926 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004927 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004928 }
4929 argvlist[*argc] = NULL;
4930 return argvlist;
4931fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004932 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004933 free_string_array(argvlist, *argc);
4934 return NULL;
4935}
Steve Dowercc16be82016-09-08 10:35:16 -07004936
Ross Lagerwall7807c352011-03-17 20:20:30 +02004937#endif
4938
Larry Hastings2f936352014-08-05 14:04:04 +10004939
Ross Lagerwall7807c352011-03-17 20:20:30 +02004940#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004941/*[clinic input]
4942os.execv
4943
Steve Dowercc16be82016-09-08 10:35:16 -07004944 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004945 Path of executable file.
4946 argv: object
4947 Tuple or list of strings.
4948 /
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 *
Steve Dowercc16be82016-09-08 10:35:16 -07004954os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4955/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004956{
Steve Dowercc16be82016-09-08 10:35:16 -07004957 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004958 Py_ssize_t argc;
4959
4960 /* execv has two arguments: (path, argv), where
4961 argv is a list or tuple of strings. */
4962
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4964 PyErr_SetString(PyExc_TypeError,
4965 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004966 return NULL;
4967 }
4968 argc = PySequence_Size(argv);
4969 if (argc < 1) {
4970 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004971 return NULL;
4972 }
4973
4974 argvlist = parse_arglist(argv, &argc);
4975 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004976 return NULL;
4977 }
Steve Dowerbce26262016-11-19 19:17:26 -08004978 if (!argvlist[0][0]) {
4979 PyErr_SetString(PyExc_ValueError,
4980 "execv() arg 2 first element cannot be empty");
4981 free_string_array(argvlist, argc);
4982 return NULL;
4983 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004984
Steve Dowerbce26262016-11-19 19:17:26 -08004985 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004986#ifdef HAVE_WEXECV
4987 _wexecv(path->wide, argvlist);
4988#else
4989 execv(path->narrow, argvlist);
4990#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004991 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004992
4993 /* If we get here it's definitely an error */
4994
4995 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004996 return posix_error();
4997}
4998
Larry Hastings2f936352014-08-05 14:04:04 +10004999
5000/*[clinic input]
5001os.execve
5002
5003 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5004 Path of executable file.
5005 argv: object
5006 Tuple or list of strings.
5007 env: object
5008 Dictionary of strings mapping to strings.
5009
5010Execute an executable path with arguments, replacing current process.
5011[clinic start generated code]*/
5012
Larry Hastings2f936352014-08-05 14:04:04 +10005013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005014os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5015/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005016{
Steve Dowercc16be82016-09-08 10:35:16 -07005017 EXECV_CHAR **argvlist = NULL;
5018 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005020
Victor Stinner8c62be82010-05-06 00:08:46 +00005021 /* execve has three arguments: (path, argv, env), where
5022 argv is a list or tuple of strings and env is a dictionary
5023 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005024
Ross Lagerwall7807c352011-03-17 20:20:30 +02005025 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005026 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005027 "execve: argv must be a tuple or list");
5028 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005029 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005031 if (argc < 1) {
5032 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5033 return NULL;
5034 }
5035
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 if (!PyMapping_Check(env)) {
5037 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005038 "execve: environment must be a mapping object");
5039 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005041
Ross Lagerwall7807c352011-03-17 20:20:30 +02005042 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005043 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005044 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005045 }
Steve Dowerbce26262016-11-19 19:17:26 -08005046 if (!argvlist[0][0]) {
5047 PyErr_SetString(PyExc_ValueError,
5048 "execve: argv first element cannot be empty");
5049 goto fail;
5050 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005051
Victor Stinner8c62be82010-05-06 00:08:46 +00005052 envlist = parse_envlist(env, &envc);
5053 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005054 goto fail;
5055
Steve Dowerbce26262016-11-19 19:17:26 -08005056 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005057#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005058 if (path->fd > -1)
5059 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005060 else
5061#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005062#ifdef HAVE_WEXECV
5063 _wexecve(path->wide, argvlist, envlist);
5064#else
Larry Hastings2f936352014-08-05 14:04:04 +10005065 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005066#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005067 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005068
5069 /* If we get here it's definitely an error */
5070
Larry Hastings2f936352014-08-05 14:04:04 +10005071 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005072
Steve Dowercc16be82016-09-08 10:35:16 -07005073 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005074 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005075 if (argvlist)
5076 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005077 return NULL;
5078}
Steve Dowercc16be82016-09-08 10:35:16 -07005079
Larry Hastings9cf065c2012-06-22 16:30:09 -07005080#endif /* HAVE_EXECV */
5081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005082
Steve Dowercc16be82016-09-08 10:35:16 -07005083#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005084/*[clinic input]
5085os.spawnv
5086
5087 mode: int
5088 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005089 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005090 Path of executable file.
5091 argv: object
5092 Tuple or list of strings.
5093 /
5094
5095Execute the program specified by path in a new process.
5096[clinic start generated code]*/
5097
Larry Hastings2f936352014-08-05 14:04:04 +10005098static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005099os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5100/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005101{
Steve Dowercc16be82016-09-08 10:35:16 -07005102 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005103 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005105 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005107
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 /* spawnv has three arguments: (mode, path, argv), where
5109 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 if (PyList_Check(argv)) {
5112 argc = PyList_Size(argv);
5113 getitem = PyList_GetItem;
5114 }
5115 else if (PyTuple_Check(argv)) {
5116 argc = PyTuple_Size(argv);
5117 getitem = PyTuple_GetItem;
5118 }
5119 else {
5120 PyErr_SetString(PyExc_TypeError,
5121 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 return NULL;
5123 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005124 if (argc == 0) {
5125 PyErr_SetString(PyExc_ValueError,
5126 "spawnv() arg 2 cannot be empty");
5127 return NULL;
5128 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005129
Steve Dowercc16be82016-09-08 10:35:16 -07005130 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 return PyErr_NoMemory();
5133 }
5134 for (i = 0; i < argc; i++) {
5135 if (!fsconvert_strdup((*getitem)(argv, i),
5136 &argvlist[i])) {
5137 free_string_array(argvlist, i);
5138 PyErr_SetString(
5139 PyExc_TypeError,
5140 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 return NULL;
5142 }
Steve Dower93ff8722016-11-19 19:03:54 -08005143 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005144 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005145 PyErr_SetString(
5146 PyExc_ValueError,
5147 "spawnv() arg 2 first element cannot be empty");
5148 return NULL;
5149 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 }
5151 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005152
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (mode == _OLD_P_OVERLAY)
5154 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005155
Victor Stinner8c62be82010-05-06 00:08:46 +00005156 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005157 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005158#ifdef HAVE_WSPAWNV
5159 spawnval = _wspawnv(mode, path->wide, argvlist);
5160#else
5161 spawnval = _spawnv(mode, path->narrow, argvlist);
5162#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005163 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005165
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005167
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 if (spawnval == -1)
5169 return posix_error();
5170 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005171 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005172}
5173
5174
Larry Hastings2f936352014-08-05 14:04:04 +10005175/*[clinic input]
5176os.spawnve
5177
5178 mode: int
5179 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005180 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005181 Path of executable file.
5182 argv: object
5183 Tuple or list of strings.
5184 env: object
5185 Dictionary of strings mapping to strings.
5186 /
5187
5188Execute the program specified by path in a new process.
5189[clinic start generated code]*/
5190
Larry Hastings2f936352014-08-05 14:04:04 +10005191static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005192os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005193 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005194/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005195{
Steve Dowercc16be82016-09-08 10:35:16 -07005196 EXECV_CHAR **argvlist;
5197 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005199 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005200 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005202 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005203
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 /* spawnve has four arguments: (mode, path, argv, env), where
5205 argv is a list or tuple of strings and env is a dictionary
5206 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005207
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 if (PyList_Check(argv)) {
5209 argc = PyList_Size(argv);
5210 getitem = PyList_GetItem;
5211 }
5212 else if (PyTuple_Check(argv)) {
5213 argc = PyTuple_Size(argv);
5214 getitem = PyTuple_GetItem;
5215 }
5216 else {
5217 PyErr_SetString(PyExc_TypeError,
5218 "spawnve() arg 2 must be a tuple or list");
5219 goto fail_0;
5220 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005221 if (argc == 0) {
5222 PyErr_SetString(PyExc_ValueError,
5223 "spawnve() arg 2 cannot be empty");
5224 goto fail_0;
5225 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 if (!PyMapping_Check(env)) {
5227 PyErr_SetString(PyExc_TypeError,
5228 "spawnve() arg 3 must be a mapping object");
5229 goto fail_0;
5230 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005231
Steve Dowercc16be82016-09-08 10:35:16 -07005232 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005233 if (argvlist == NULL) {
5234 PyErr_NoMemory();
5235 goto fail_0;
5236 }
5237 for (i = 0; i < argc; i++) {
5238 if (!fsconvert_strdup((*getitem)(argv, i),
5239 &argvlist[i]))
5240 {
5241 lastarg = i;
5242 goto fail_1;
5243 }
Steve Dowerbce26262016-11-19 19:17:26 -08005244 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005245 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005246 PyErr_SetString(
5247 PyExc_ValueError,
5248 "spawnv() arg 2 first element cannot be empty");
5249 goto fail_1;
5250 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 }
5252 lastarg = argc;
5253 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005254
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 envlist = parse_envlist(env, &envc);
5256 if (envlist == NULL)
5257 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005258
Victor Stinner8c62be82010-05-06 00:08:46 +00005259 if (mode == _OLD_P_OVERLAY)
5260 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005261
Victor Stinner8c62be82010-05-06 00:08:46 +00005262 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005263 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005264#ifdef HAVE_WSPAWNV
5265 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5266#else
5267 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5268#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005269 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005271
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 if (spawnval == -1)
5273 (void) posix_error();
5274 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005275 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005276
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 while (--envc >= 0)
5278 PyMem_DEL(envlist[envc]);
5279 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005280 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005281 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005282 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005284}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005285
Guido van Rossuma1065681999-01-25 23:20:23 +00005286#endif /* HAVE_SPAWNV */
5287
5288
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005289#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005290
5291/* Helper function to validate arguments.
5292 Returns 0 on success. non-zero on failure with a TypeError raised.
5293 If obj is non-NULL it must be callable. */
5294static int
5295check_null_or_callable(PyObject *obj, const char* obj_name)
5296{
5297 if (obj && !PyCallable_Check(obj)) {
5298 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5299 obj_name, Py_TYPE(obj)->tp_name);
5300 return -1;
5301 }
5302 return 0;
5303}
5304
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005305/*[clinic input]
5306os.register_at_fork
5307
Gregory P. Smith163468a2017-05-29 10:03:41 -07005308 *
5309 before: object=NULL
5310 A callable to be called in the parent before the fork() syscall.
5311 after_in_child: object=NULL
5312 A callable to be called in the child after fork().
5313 after_in_parent: object=NULL
5314 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005315
Gregory P. Smith163468a2017-05-29 10:03:41 -07005316Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005317
Gregory P. Smith163468a2017-05-29 10:03:41 -07005318'before' callbacks are called in reverse order.
5319'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005320
5321[clinic start generated code]*/
5322
5323static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005324os_register_at_fork_impl(PyObject *module, PyObject *before,
5325 PyObject *after_in_child, PyObject *after_in_parent)
5326/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005327{
5328 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005329
Gregory P. Smith163468a2017-05-29 10:03:41 -07005330 if (!before && !after_in_child && !after_in_parent) {
5331 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5332 return NULL;
5333 }
5334 if (check_null_or_callable(before, "before") ||
5335 check_null_or_callable(after_in_child, "after_in_child") ||
5336 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005337 return NULL;
5338 }
5339 interp = PyThreadState_Get()->interp;
5340
Gregory P. Smith163468a2017-05-29 10:03:41 -07005341 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005342 return NULL;
5343 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005344 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005345 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005346 }
5347 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5348 return NULL;
5349 }
5350 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005351}
5352#endif /* HAVE_FORK */
5353
5354
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005355#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005356/*[clinic input]
5357os.fork1
5358
5359Fork a child process with a single multiplexed (i.e., not bound) thread.
5360
5361Return 0 to child process and PID of child to parent process.
5362[clinic start generated code]*/
5363
Larry Hastings2f936352014-08-05 14:04:04 +10005364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005365os_fork1_impl(PyObject *module)
5366/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005367{
Victor Stinner8c62be82010-05-06 00:08:46 +00005368 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005369
5370 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 pid = fork1();
5372 if (pid == 0) {
5373 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005374 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 } else {
5376 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005377 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 }
5379 if (pid == -1)
5380 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005381 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005382}
Larry Hastings2f936352014-08-05 14:04:04 +10005383#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005384
5385
Guido van Rossumad0ee831995-03-01 10:34:45 +00005386#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005387/*[clinic input]
5388os.fork
5389
5390Fork a child process.
5391
5392Return 0 to child process and PID of child to parent process.
5393[clinic start generated code]*/
5394
Larry Hastings2f936352014-08-05 14:04:04 +10005395static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005396os_fork_impl(PyObject *module)
5397/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005398{
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005400
5401 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 pid = fork();
5403 if (pid == 0) {
5404 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005405 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 } else {
5407 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005408 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005409 }
5410 if (pid == -1)
5411 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005412 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005413}
Larry Hastings2f936352014-08-05 14:04:04 +10005414#endif /* HAVE_FORK */
5415
Guido van Rossum85e3b011991-06-03 12:42:10 +00005416
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005417#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005418#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005419/*[clinic input]
5420os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005421
Larry Hastings2f936352014-08-05 14:04:04 +10005422 policy: int
5423
5424Get the maximum scheduling priority for policy.
5425[clinic start generated code]*/
5426
Larry Hastings2f936352014-08-05 14:04:04 +10005427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005428os_sched_get_priority_max_impl(PyObject *module, int policy)
5429/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005430{
5431 int max;
5432
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005433 max = sched_get_priority_max(policy);
5434 if (max < 0)
5435 return posix_error();
5436 return PyLong_FromLong(max);
5437}
5438
Larry Hastings2f936352014-08-05 14:04:04 +10005439
5440/*[clinic input]
5441os.sched_get_priority_min
5442
5443 policy: int
5444
5445Get the minimum scheduling priority for policy.
5446[clinic start generated code]*/
5447
Larry Hastings2f936352014-08-05 14:04:04 +10005448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005449os_sched_get_priority_min_impl(PyObject *module, int policy)
5450/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005451{
5452 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005453 if (min < 0)
5454 return posix_error();
5455 return PyLong_FromLong(min);
5456}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005457#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5458
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005459
Larry Hastings2f936352014-08-05 14:04:04 +10005460#ifdef HAVE_SCHED_SETSCHEDULER
5461/*[clinic input]
5462os.sched_getscheduler
5463 pid: pid_t
5464 /
5465
5466Get the scheduling policy for the process identifiedy by pid.
5467
5468Passing 0 for pid returns the scheduling policy for the calling process.
5469[clinic start generated code]*/
5470
Larry Hastings2f936352014-08-05 14:04:04 +10005471static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005472os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5473/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005474{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475 int policy;
5476
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005477 policy = sched_getscheduler(pid);
5478 if (policy < 0)
5479 return posix_error();
5480 return PyLong_FromLong(policy);
5481}
Larry Hastings2f936352014-08-05 14:04:04 +10005482#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005483
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005484
5485#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005486/*[clinic input]
5487class os.sched_param "PyObject *" "&SchedParamType"
5488
5489@classmethod
5490os.sched_param.__new__
5491
5492 sched_priority: object
5493 A scheduling parameter.
5494
5495Current has only one field: sched_priority");
5496[clinic start generated code]*/
5497
Larry Hastings2f936352014-08-05 14:04:04 +10005498static PyObject *
5499os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005500/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005501{
5502 PyObject *res;
5503
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005504 res = PyStructSequence_New(type);
5505 if (!res)
5506 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005507 Py_INCREF(sched_priority);
5508 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005509 return res;
5510}
5511
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005512
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005513PyDoc_VAR(os_sched_param__doc__);
5514
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005515static PyStructSequence_Field sched_param_fields[] = {
5516 {"sched_priority", "the scheduling priority"},
5517 {0}
5518};
5519
5520static PyStructSequence_Desc sched_param_desc = {
5521 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005522 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005523 sched_param_fields,
5524 1
5525};
5526
5527static int
5528convert_sched_param(PyObject *param, struct sched_param *res)
5529{
5530 long priority;
5531
5532 if (Py_TYPE(param) != &SchedParamType) {
5533 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5534 return 0;
5535 }
5536 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5537 if (priority == -1 && PyErr_Occurred())
5538 return 0;
5539 if (priority > INT_MAX || priority < INT_MIN) {
5540 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5541 return 0;
5542 }
5543 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5544 return 1;
5545}
Larry Hastings2f936352014-08-05 14:04:04 +10005546#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005548
5549#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005550/*[clinic input]
5551os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005552
Larry Hastings2f936352014-08-05 14:04:04 +10005553 pid: pid_t
5554 policy: int
5555 param: sched_param
5556 /
5557
5558Set the scheduling policy for the process identified by pid.
5559
5560If pid is 0, the calling process is changed.
5561param is an instance of sched_param.
5562[clinic start generated code]*/
5563
Larry Hastings2f936352014-08-05 14:04:04 +10005564static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005565os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005566 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005567/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005568{
Jesus Cea9c822272011-09-10 01:40:52 +02005569 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005570 ** sched_setscheduler() returns 0 in Linux, but the previous
5571 ** scheduling policy under Solaris/Illumos, and others.
5572 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005573 */
Larry Hastings2f936352014-08-05 14:04:04 +10005574 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005575 return posix_error();
5576 Py_RETURN_NONE;
5577}
Larry Hastings2f936352014-08-05 14:04:04 +10005578#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005580
5581#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005582/*[clinic input]
5583os.sched_getparam
5584 pid: pid_t
5585 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005586
Larry Hastings2f936352014-08-05 14:04:04 +10005587Returns scheduling parameters for the process identified by pid.
5588
5589If pid is 0, returns parameters for the calling process.
5590Return value is an instance of sched_param.
5591[clinic start generated code]*/
5592
Larry Hastings2f936352014-08-05 14:04:04 +10005593static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005594os_sched_getparam_impl(PyObject *module, pid_t pid)
5595/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005596{
5597 struct sched_param param;
5598 PyObject *result;
5599 PyObject *priority;
5600
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005601 if (sched_getparam(pid, &param))
5602 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005603 result = PyStructSequence_New(&SchedParamType);
5604 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005605 return NULL;
5606 priority = PyLong_FromLong(param.sched_priority);
5607 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005608 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005609 return NULL;
5610 }
Larry Hastings2f936352014-08-05 14:04:04 +10005611 PyStructSequence_SET_ITEM(result, 0, priority);
5612 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005613}
5614
Larry Hastings2f936352014-08-05 14:04:04 +10005615
5616/*[clinic input]
5617os.sched_setparam
5618 pid: pid_t
5619 param: sched_param
5620 /
5621
5622Set scheduling parameters for the process identified by pid.
5623
5624If pid is 0, sets parameters for the calling process.
5625param should be an instance of sched_param.
5626[clinic start generated code]*/
5627
Larry Hastings2f936352014-08-05 14:04:04 +10005628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005629os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005630 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005631/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005632{
5633 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005634 return posix_error();
5635 Py_RETURN_NONE;
5636}
Larry Hastings2f936352014-08-05 14:04:04 +10005637#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005638
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005639
5640#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005641/*[clinic input]
5642os.sched_rr_get_interval -> double
5643 pid: pid_t
5644 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005645
Larry Hastings2f936352014-08-05 14:04:04 +10005646Return the round-robin quantum for the process identified by pid, in seconds.
5647
5648Value returned is a float.
5649[clinic start generated code]*/
5650
Larry Hastings2f936352014-08-05 14:04:04 +10005651static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005652os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5653/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005654{
5655 struct timespec interval;
5656 if (sched_rr_get_interval(pid, &interval)) {
5657 posix_error();
5658 return -1.0;
5659 }
5660 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5661}
5662#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005663
Larry Hastings2f936352014-08-05 14:04:04 +10005664
5665/*[clinic input]
5666os.sched_yield
5667
5668Voluntarily relinquish the CPU.
5669[clinic start generated code]*/
5670
Larry Hastings2f936352014-08-05 14:04:04 +10005671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005672os_sched_yield_impl(PyObject *module)
5673/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005674{
5675 if (sched_yield())
5676 return posix_error();
5677 Py_RETURN_NONE;
5678}
5679
Benjamin Peterson2740af82011-08-02 17:41:34 -05005680#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005681/* The minimum number of CPUs allocated in a cpu_set_t */
5682static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005683
Larry Hastings2f936352014-08-05 14:04:04 +10005684/*[clinic input]
5685os.sched_setaffinity
5686 pid: pid_t
5687 mask : object
5688 /
5689
5690Set the CPU affinity of the process identified by pid to mask.
5691
5692mask should be an iterable of integers identifying CPUs.
5693[clinic start generated code]*/
5694
Larry Hastings2f936352014-08-05 14:04:04 +10005695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005696os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5697/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005698{
Antoine Pitrou84869872012-08-04 16:16:35 +02005699 int ncpus;
5700 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005701 cpu_set_t *cpu_set = NULL;
5702 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005703
Larry Hastings2f936352014-08-05 14:04:04 +10005704 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005705 if (iterator == NULL)
5706 return NULL;
5707
5708 ncpus = NCPUS_START;
5709 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005710 cpu_set = CPU_ALLOC(ncpus);
5711 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005712 PyErr_NoMemory();
5713 goto error;
5714 }
Larry Hastings2f936352014-08-05 14:04:04 +10005715 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005716
5717 while ((item = PyIter_Next(iterator))) {
5718 long cpu;
5719 if (!PyLong_Check(item)) {
5720 PyErr_Format(PyExc_TypeError,
5721 "expected an iterator of ints, "
5722 "but iterator yielded %R",
5723 Py_TYPE(item));
5724 Py_DECREF(item);
5725 goto error;
5726 }
5727 cpu = PyLong_AsLong(item);
5728 Py_DECREF(item);
5729 if (cpu < 0) {
5730 if (!PyErr_Occurred())
5731 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5732 goto error;
5733 }
5734 if (cpu > INT_MAX - 1) {
5735 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5736 goto error;
5737 }
5738 if (cpu >= ncpus) {
5739 /* Grow CPU mask to fit the CPU number */
5740 int newncpus = ncpus;
5741 cpu_set_t *newmask;
5742 size_t newsetsize;
5743 while (newncpus <= cpu) {
5744 if (newncpus > INT_MAX / 2)
5745 newncpus = cpu + 1;
5746 else
5747 newncpus = newncpus * 2;
5748 }
5749 newmask = CPU_ALLOC(newncpus);
5750 if (newmask == NULL) {
5751 PyErr_NoMemory();
5752 goto error;
5753 }
5754 newsetsize = CPU_ALLOC_SIZE(newncpus);
5755 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005756 memcpy(newmask, cpu_set, setsize);
5757 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005758 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005759 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005760 ncpus = newncpus;
5761 }
Larry Hastings2f936352014-08-05 14:04:04 +10005762 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005763 }
5764 Py_CLEAR(iterator);
5765
Larry Hastings2f936352014-08-05 14:04:04 +10005766 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005767 posix_error();
5768 goto error;
5769 }
Larry Hastings2f936352014-08-05 14:04:04 +10005770 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005771 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005772
5773error:
Larry Hastings2f936352014-08-05 14:04:04 +10005774 if (cpu_set)
5775 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005776 Py_XDECREF(iterator);
5777 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005778}
5779
Larry Hastings2f936352014-08-05 14:04:04 +10005780
5781/*[clinic input]
5782os.sched_getaffinity
5783 pid: pid_t
5784 /
5785
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005786Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005787
5788The affinity is returned as a set of CPU identifiers.
5789[clinic start generated code]*/
5790
Larry Hastings2f936352014-08-05 14:04:04 +10005791static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005792os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005793/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005794{
Antoine Pitrou84869872012-08-04 16:16:35 +02005795 int cpu, ncpus, count;
5796 size_t setsize;
5797 cpu_set_t *mask = NULL;
5798 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005799
Antoine Pitrou84869872012-08-04 16:16:35 +02005800 ncpus = NCPUS_START;
5801 while (1) {
5802 setsize = CPU_ALLOC_SIZE(ncpus);
5803 mask = CPU_ALLOC(ncpus);
5804 if (mask == NULL)
5805 return PyErr_NoMemory();
5806 if (sched_getaffinity(pid, setsize, mask) == 0)
5807 break;
5808 CPU_FREE(mask);
5809 if (errno != EINVAL)
5810 return posix_error();
5811 if (ncpus > INT_MAX / 2) {
5812 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5813 "a large enough CPU set");
5814 return NULL;
5815 }
5816 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005817 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005818
5819 res = PySet_New(NULL);
5820 if (res == NULL)
5821 goto error;
5822 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5823 if (CPU_ISSET_S(cpu, setsize, mask)) {
5824 PyObject *cpu_num = PyLong_FromLong(cpu);
5825 --count;
5826 if (cpu_num == NULL)
5827 goto error;
5828 if (PySet_Add(res, cpu_num)) {
5829 Py_DECREF(cpu_num);
5830 goto error;
5831 }
5832 Py_DECREF(cpu_num);
5833 }
5834 }
5835 CPU_FREE(mask);
5836 return res;
5837
5838error:
5839 if (mask)
5840 CPU_FREE(mask);
5841 Py_XDECREF(res);
5842 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005843}
5844
Benjamin Peterson2740af82011-08-02 17:41:34 -05005845#endif /* HAVE_SCHED_SETAFFINITY */
5846
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005847#endif /* HAVE_SCHED_H */
5848
Larry Hastings2f936352014-08-05 14:04:04 +10005849
Neal Norwitzb59798b2003-03-21 01:43:31 +00005850/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005851/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5852#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005853#define DEV_PTY_FILE "/dev/ptc"
5854#define HAVE_DEV_PTMX
5855#else
5856#define DEV_PTY_FILE "/dev/ptmx"
5857#endif
5858
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005859#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005860#ifdef HAVE_PTY_H
5861#include <pty.h>
5862#else
5863#ifdef HAVE_LIBUTIL_H
5864#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005865#else
5866#ifdef HAVE_UTIL_H
5867#include <util.h>
5868#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005869#endif /* HAVE_LIBUTIL_H */
5870#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005871#ifdef HAVE_STROPTS_H
5872#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005873#endif
5874#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005875
Larry Hastings2f936352014-08-05 14:04:04 +10005876
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005877#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005878/*[clinic input]
5879os.openpty
5880
5881Open a pseudo-terminal.
5882
5883Return a tuple of (master_fd, slave_fd) containing open file descriptors
5884for both the master and slave ends.
5885[clinic start generated code]*/
5886
Larry Hastings2f936352014-08-05 14:04:04 +10005887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005888os_openpty_impl(PyObject *module)
5889/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005890{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005891 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005892#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005893 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005894#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005895#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005896 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005897#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005899#endif
5900#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005901
Thomas Wouters70c21a12000-07-14 14:28:33 +00005902#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005904 goto posix_error;
5905
5906 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5907 goto error;
5908 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5909 goto error;
5910
Neal Norwitzb59798b2003-03-21 01:43:31 +00005911#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5913 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005914 goto posix_error;
5915 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5916 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005917
Victor Stinnerdaf45552013-08-28 00:53:59 +02005918 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005920 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005921
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005922#else
Victor Stinner000de532013-11-25 23:19:58 +01005923 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005924 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005925 goto posix_error;
5926
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005928
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 /* change permission of slave */
5930 if (grantpt(master_fd) < 0) {
5931 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005932 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005934
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 /* unlock slave */
5936 if (unlockpt(master_fd) < 0) {
5937 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005938 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005939 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005940
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005942
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 slave_name = ptsname(master_fd); /* get name of slave */
5944 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005945 goto posix_error;
5946
5947 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005948 if (slave_fd == -1)
5949 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005950
5951 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5952 goto posix_error;
5953
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005954#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5956 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005957#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005959#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005960#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005961#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005962
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005964
Victor Stinnerdaf45552013-08-28 00:53:59 +02005965posix_error:
5966 posix_error();
5967error:
5968 if (master_fd != -1)
5969 close(master_fd);
5970 if (slave_fd != -1)
5971 close(slave_fd);
5972 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005973}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005974#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005975
Larry Hastings2f936352014-08-05 14:04:04 +10005976
Fred Drake8cef4cf2000-06-28 16:40:38 +00005977#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005978/*[clinic input]
5979os.forkpty
5980
5981Fork a new process with a new pseudo-terminal as controlling tty.
5982
5983Returns a tuple of (pid, master_fd).
5984Like fork(), return pid of 0 to the child process,
5985and pid of child to the parent process.
5986To both, return fd of newly opened pseudo-terminal.
5987[clinic start generated code]*/
5988
Larry Hastings2f936352014-08-05 14:04:04 +10005989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005990os_forkpty_impl(PyObject *module)
5991/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005992{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005993 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005995
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005996 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 pid = forkpty(&master_fd, NULL, NULL, NULL);
5998 if (pid == 0) {
5999 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006000 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 } else {
6002 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006003 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 }
6005 if (pid == -1)
6006 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006007 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006008}
Larry Hastings2f936352014-08-05 14:04:04 +10006009#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006010
Ross Lagerwall7807c352011-03-17 20:20:30 +02006011
Guido van Rossumad0ee831995-03-01 10:34:45 +00006012#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006013/*[clinic input]
6014os.getegid
6015
6016Return the current process's effective group id.
6017[clinic start generated code]*/
6018
Larry Hastings2f936352014-08-05 14:04:04 +10006019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006020os_getegid_impl(PyObject *module)
6021/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006022{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006023 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006024}
Larry Hastings2f936352014-08-05 14:04:04 +10006025#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006027
Guido van Rossumad0ee831995-03-01 10:34:45 +00006028#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006029/*[clinic input]
6030os.geteuid
6031
6032Return the current process's effective user id.
6033[clinic start generated code]*/
6034
Larry Hastings2f936352014-08-05 14:04:04 +10006035static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006036os_geteuid_impl(PyObject *module)
6037/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006038{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006039 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006040}
Larry Hastings2f936352014-08-05 14:04:04 +10006041#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006043
Guido van Rossumad0ee831995-03-01 10:34:45 +00006044#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006045/*[clinic input]
6046os.getgid
6047
6048Return the current process's group id.
6049[clinic start generated code]*/
6050
Larry Hastings2f936352014-08-05 14:04:04 +10006051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006052os_getgid_impl(PyObject *module)
6053/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006054{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006055 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006056}
Larry Hastings2f936352014-08-05 14:04:04 +10006057#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006059
Berker Peksag39404992016-09-15 20:45:16 +03006060#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006061/*[clinic input]
6062os.getpid
6063
6064Return the current process id.
6065[clinic start generated code]*/
6066
Larry Hastings2f936352014-08-05 14:04:04 +10006067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006068os_getpid_impl(PyObject *module)
6069/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006070{
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006072}
Berker Peksag39404992016-09-15 20:45:16 +03006073#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006074
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006075#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006076
6077/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006078PyDoc_STRVAR(posix_getgrouplist__doc__,
6079"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6080Returns a list of groups to which a user belongs.\n\n\
6081 user: username to lookup\n\
6082 group: base group id of the user");
6083
6084static PyObject *
6085posix_getgrouplist(PyObject *self, PyObject *args)
6086{
6087#ifdef NGROUPS_MAX
6088#define MAX_GROUPS NGROUPS_MAX
6089#else
6090 /* defined to be 16 on Solaris7, so this should be a small number */
6091#define MAX_GROUPS 64
6092#endif
6093
6094 const char *user;
6095 int i, ngroups;
6096 PyObject *list;
6097#ifdef __APPLE__
6098 int *groups, basegid;
6099#else
6100 gid_t *groups, basegid;
6101#endif
6102 ngroups = MAX_GROUPS;
6103
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006104#ifdef __APPLE__
6105 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006106 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006107#else
6108 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6109 _Py_Gid_Converter, &basegid))
6110 return NULL;
6111#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006112
6113#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006114 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006115#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006116 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006117#endif
6118 if (groups == NULL)
6119 return PyErr_NoMemory();
6120
6121 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6122 PyMem_Del(groups);
6123 return posix_error();
6124 }
6125
6126 list = PyList_New(ngroups);
6127 if (list == NULL) {
6128 PyMem_Del(groups);
6129 return NULL;
6130 }
6131
6132 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006133#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006134 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006135#else
6136 PyObject *o = _PyLong_FromGid(groups[i]);
6137#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006138 if (o == NULL) {
6139 Py_DECREF(list);
6140 PyMem_Del(groups);
6141 return NULL;
6142 }
6143 PyList_SET_ITEM(list, i, o);
6144 }
6145
6146 PyMem_Del(groups);
6147
6148 return list;
6149}
Larry Hastings2f936352014-08-05 14:04:04 +10006150#endif /* HAVE_GETGROUPLIST */
6151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006152
Fred Drakec9680921999-12-13 16:37:25 +00006153#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006154/*[clinic input]
6155os.getgroups
6156
6157Return list of supplemental group IDs for the process.
6158[clinic start generated code]*/
6159
Larry Hastings2f936352014-08-05 14:04:04 +10006160static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006161os_getgroups_impl(PyObject *module)
6162/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006163{
6164 PyObject *result = NULL;
6165
Fred Drakec9680921999-12-13 16:37:25 +00006166#ifdef NGROUPS_MAX
6167#define MAX_GROUPS NGROUPS_MAX
6168#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006169 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006170#define MAX_GROUPS 64
6171#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006173
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006174 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006175 * This is a helper variable to store the intermediate result when
6176 * that happens.
6177 *
6178 * To keep the code readable the OSX behaviour is unconditional,
6179 * according to the POSIX spec this should be safe on all unix-y
6180 * systems.
6181 */
6182 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006184
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006185#ifdef __APPLE__
6186 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6187 * there are more groups than can fit in grouplist. Therefore, on OS X
6188 * always first call getgroups with length 0 to get the actual number
6189 * of groups.
6190 */
6191 n = getgroups(0, NULL);
6192 if (n < 0) {
6193 return posix_error();
6194 } else if (n <= MAX_GROUPS) {
6195 /* groups will fit in existing array */
6196 alt_grouplist = grouplist;
6197 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006198 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006199 if (alt_grouplist == NULL) {
6200 errno = EINVAL;
6201 return posix_error();
6202 }
6203 }
6204
6205 n = getgroups(n, alt_grouplist);
6206 if (n == -1) {
6207 if (alt_grouplist != grouplist) {
6208 PyMem_Free(alt_grouplist);
6209 }
6210 return posix_error();
6211 }
6212#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006213 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006214 if (n < 0) {
6215 if (errno == EINVAL) {
6216 n = getgroups(0, NULL);
6217 if (n == -1) {
6218 return posix_error();
6219 }
6220 if (n == 0) {
6221 /* Avoid malloc(0) */
6222 alt_grouplist = grouplist;
6223 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006224 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006225 if (alt_grouplist == NULL) {
6226 errno = EINVAL;
6227 return posix_error();
6228 }
6229 n = getgroups(n, alt_grouplist);
6230 if (n == -1) {
6231 PyMem_Free(alt_grouplist);
6232 return posix_error();
6233 }
6234 }
6235 } else {
6236 return posix_error();
6237 }
6238 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006239#endif
6240
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006241 result = PyList_New(n);
6242 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006243 int i;
6244 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006245 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006246 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006247 Py_DECREF(result);
6248 result = NULL;
6249 break;
Fred Drakec9680921999-12-13 16:37:25 +00006250 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006251 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006252 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006253 }
6254
6255 if (alt_grouplist != grouplist) {
6256 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006258
Fred Drakec9680921999-12-13 16:37:25 +00006259 return result;
6260}
Larry Hastings2f936352014-08-05 14:04:04 +10006261#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006262
Antoine Pitroub7572f02009-12-02 20:46:48 +00006263#ifdef HAVE_INITGROUPS
6264PyDoc_STRVAR(posix_initgroups__doc__,
6265"initgroups(username, gid) -> None\n\n\
6266Call the system initgroups() to initialize the group access list with all of\n\
6267the groups of which the specified username is a member, plus the specified\n\
6268group id.");
6269
Larry Hastings2f936352014-08-05 14:04:04 +10006270/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006271static PyObject *
6272posix_initgroups(PyObject *self, PyObject *args)
6273{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006274 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006275 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006276 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006277#ifdef __APPLE__
6278 int gid;
6279#else
6280 gid_t gid;
6281#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006282
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006283#ifdef __APPLE__
6284 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6285 PyUnicode_FSConverter, &oname,
6286 &gid))
6287#else
6288 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6289 PyUnicode_FSConverter, &oname,
6290 _Py_Gid_Converter, &gid))
6291#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006293 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006294
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006295 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006296 Py_DECREF(oname);
6297 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006298 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006299
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006300 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006301}
Larry Hastings2f936352014-08-05 14:04:04 +10006302#endif /* HAVE_INITGROUPS */
6303
Antoine Pitroub7572f02009-12-02 20:46:48 +00006304
Martin v. Löwis606edc12002-06-13 21:09:11 +00006305#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006306/*[clinic input]
6307os.getpgid
6308
6309 pid: pid_t
6310
6311Call the system call getpgid(), and return the result.
6312[clinic start generated code]*/
6313
Larry Hastings2f936352014-08-05 14:04:04 +10006314static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006315os_getpgid_impl(PyObject *module, pid_t pid)
6316/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006317{
6318 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006319 if (pgid < 0)
6320 return posix_error();
6321 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006322}
6323#endif /* HAVE_GETPGID */
6324
6325
Guido van Rossumb6775db1994-08-01 11:34:53 +00006326#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006327/*[clinic input]
6328os.getpgrp
6329
6330Return the current process group id.
6331[clinic start generated code]*/
6332
Larry Hastings2f936352014-08-05 14:04:04 +10006333static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006334os_getpgrp_impl(PyObject *module)
6335/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006336{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006337#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006339#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006341#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006342}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006343#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006345
Guido van Rossumb6775db1994-08-01 11:34:53 +00006346#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006347/*[clinic input]
6348os.setpgrp
6349
6350Make the current process the leader of its process group.
6351[clinic start generated code]*/
6352
Larry Hastings2f936352014-08-05 14:04:04 +10006353static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006354os_setpgrp_impl(PyObject *module)
6355/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006356{
Guido van Rossum64933891994-10-20 21:56:42 +00006357#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006359#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006360 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006361#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006363 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006364}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006365#endif /* HAVE_SETPGRP */
6366
Guido van Rossumad0ee831995-03-01 10:34:45 +00006367#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006368
6369#ifdef MS_WINDOWS
6370#include <tlhelp32.h>
6371
6372static PyObject*
6373win32_getppid()
6374{
6375 HANDLE snapshot;
6376 pid_t mypid;
6377 PyObject* result = NULL;
6378 BOOL have_record;
6379 PROCESSENTRY32 pe;
6380
6381 mypid = getpid(); /* This function never fails */
6382
6383 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6384 if (snapshot == INVALID_HANDLE_VALUE)
6385 return PyErr_SetFromWindowsErr(GetLastError());
6386
6387 pe.dwSize = sizeof(pe);
6388 have_record = Process32First(snapshot, &pe);
6389 while (have_record) {
6390 if (mypid == (pid_t)pe.th32ProcessID) {
6391 /* We could cache the ulong value in a static variable. */
6392 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6393 break;
6394 }
6395
6396 have_record = Process32Next(snapshot, &pe);
6397 }
6398
6399 /* If our loop exits and our pid was not found (result will be NULL)
6400 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6401 * error anyway, so let's raise it. */
6402 if (!result)
6403 result = PyErr_SetFromWindowsErr(GetLastError());
6404
6405 CloseHandle(snapshot);
6406
6407 return result;
6408}
6409#endif /*MS_WINDOWS*/
6410
Larry Hastings2f936352014-08-05 14:04:04 +10006411
6412/*[clinic input]
6413os.getppid
6414
6415Return the parent's process id.
6416
6417If the parent process has already exited, Windows machines will still
6418return its id; others systems will return the id of the 'init' process (1).
6419[clinic start generated code]*/
6420
Larry Hastings2f936352014-08-05 14:04:04 +10006421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006422os_getppid_impl(PyObject *module)
6423/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006424{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006425#ifdef MS_WINDOWS
6426 return win32_getppid();
6427#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006429#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006430}
6431#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006432
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006433
Fred Drake12c6e2d1999-12-14 21:25:03 +00006434#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006435/*[clinic input]
6436os.getlogin
6437
6438Return the actual login name.
6439[clinic start generated code]*/
6440
Larry Hastings2f936352014-08-05 14:04:04 +10006441static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006442os_getlogin_impl(PyObject *module)
6443/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006444{
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006446#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006447 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006448 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006449
6450 if (GetUserNameW(user_name, &num_chars)) {
6451 /* num_chars is the number of unicode chars plus null terminator */
6452 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006453 }
6454 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006455 result = PyErr_SetFromWindowsErr(GetLastError());
6456#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006457 char *name;
6458 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006459
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 errno = 0;
6461 name = getlogin();
6462 if (name == NULL) {
6463 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006464 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006465 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006466 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 }
6468 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006469 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006471#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006472 return result;
6473}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006474#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006475
Larry Hastings2f936352014-08-05 14:04:04 +10006476
Guido van Rossumad0ee831995-03-01 10:34:45 +00006477#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006478/*[clinic input]
6479os.getuid
6480
6481Return the current process's user id.
6482[clinic start generated code]*/
6483
Larry Hastings2f936352014-08-05 14:04:04 +10006484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006485os_getuid_impl(PyObject *module)
6486/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006487{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006488 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006489}
Larry Hastings2f936352014-08-05 14:04:04 +10006490#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006491
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006492
Brian Curtineb24d742010-04-12 17:16:38 +00006493#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006494#define HAVE_KILL
6495#endif /* MS_WINDOWS */
6496
6497#ifdef HAVE_KILL
6498/*[clinic input]
6499os.kill
6500
6501 pid: pid_t
6502 signal: Py_ssize_t
6503 /
6504
6505Kill a process with a signal.
6506[clinic start generated code]*/
6507
Larry Hastings2f936352014-08-05 14:04:04 +10006508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006509os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6510/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006511#ifndef MS_WINDOWS
6512{
6513 if (kill(pid, (int)signal) == -1)
6514 return posix_error();
6515 Py_RETURN_NONE;
6516}
6517#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006518{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006519 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006520 DWORD sig = (DWORD)signal;
6521 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006522 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006523
Victor Stinner8c62be82010-05-06 00:08:46 +00006524 /* Console processes which share a common console can be sent CTRL+C or
6525 CTRL+BREAK events, provided they handle said events. */
6526 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006527 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 err = GetLastError();
6529 PyErr_SetFromWindowsErr(err);
6530 }
6531 else
6532 Py_RETURN_NONE;
6533 }
Brian Curtineb24d742010-04-12 17:16:38 +00006534
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6536 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006537 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 if (handle == NULL) {
6539 err = GetLastError();
6540 return PyErr_SetFromWindowsErr(err);
6541 }
Brian Curtineb24d742010-04-12 17:16:38 +00006542
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 if (TerminateProcess(handle, sig) == 0) {
6544 err = GetLastError();
6545 result = PyErr_SetFromWindowsErr(err);
6546 } else {
6547 Py_INCREF(Py_None);
6548 result = Py_None;
6549 }
Brian Curtineb24d742010-04-12 17:16:38 +00006550
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 CloseHandle(handle);
6552 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006553}
Larry Hastings2f936352014-08-05 14:04:04 +10006554#endif /* !MS_WINDOWS */
6555#endif /* HAVE_KILL */
6556
6557
6558#ifdef HAVE_KILLPG
6559/*[clinic input]
6560os.killpg
6561
6562 pgid: pid_t
6563 signal: int
6564 /
6565
6566Kill a process group with a signal.
6567[clinic start generated code]*/
6568
Larry Hastings2f936352014-08-05 14:04:04 +10006569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006570os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6571/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006572{
6573 /* XXX some man pages make the `pgid` parameter an int, others
6574 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6575 take the same type. Moreover, pid_t is always at least as wide as
6576 int (else compilation of this module fails), which is safe. */
6577 if (killpg(pgid, signal) == -1)
6578 return posix_error();
6579 Py_RETURN_NONE;
6580}
6581#endif /* HAVE_KILLPG */
6582
Brian Curtineb24d742010-04-12 17:16:38 +00006583
Guido van Rossumc0125471996-06-28 18:55:32 +00006584#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006585#ifdef HAVE_SYS_LOCK_H
6586#include <sys/lock.h>
6587#endif
6588
Larry Hastings2f936352014-08-05 14:04:04 +10006589/*[clinic input]
6590os.plock
6591 op: int
6592 /
6593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006595[clinic start generated code]*/
6596
Larry Hastings2f936352014-08-05 14:04:04 +10006597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006598os_plock_impl(PyObject *module, int op)
6599/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006600{
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 if (plock(op) == -1)
6602 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006603 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006604}
Larry Hastings2f936352014-08-05 14:04:04 +10006605#endif /* HAVE_PLOCK */
6606
Guido van Rossumc0125471996-06-28 18:55:32 +00006607
Guido van Rossumb6775db1994-08-01 11:34:53 +00006608#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006609/*[clinic input]
6610os.setuid
6611
6612 uid: uid_t
6613 /
6614
6615Set the current process's user id.
6616[clinic start generated code]*/
6617
Larry Hastings2f936352014-08-05 14:04:04 +10006618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006619os_setuid_impl(PyObject *module, uid_t uid)
6620/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006621{
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 if (setuid(uid) < 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_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006627
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006628
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006629#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006630/*[clinic input]
6631os.seteuid
6632
6633 euid: uid_t
6634 /
6635
6636Set the current process's effective user id.
6637[clinic start generated code]*/
6638
Larry Hastings2f936352014-08-05 14:04:04 +10006639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006640os_seteuid_impl(PyObject *module, uid_t euid)
6641/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006642{
6643 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006645 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006646}
6647#endif /* HAVE_SETEUID */
6648
Larry Hastings2f936352014-08-05 14:04:04 +10006649
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006650#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006651/*[clinic input]
6652os.setegid
6653
6654 egid: gid_t
6655 /
6656
6657Set the current process's effective group id.
6658[clinic start generated code]*/
6659
Larry Hastings2f936352014-08-05 14:04:04 +10006660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006661os_setegid_impl(PyObject *module, gid_t egid)
6662/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006663{
6664 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006666 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006667}
6668#endif /* HAVE_SETEGID */
6669
Larry Hastings2f936352014-08-05 14:04:04 +10006670
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006671#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006672/*[clinic input]
6673os.setreuid
6674
6675 ruid: uid_t
6676 euid: uid_t
6677 /
6678
6679Set the current process's real and effective user ids.
6680[clinic start generated code]*/
6681
Larry Hastings2f936352014-08-05 14:04:04 +10006682static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006683os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6684/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006685{
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 if (setreuid(ruid, euid) < 0) {
6687 return posix_error();
6688 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006689 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006691}
6692#endif /* HAVE_SETREUID */
6693
Larry Hastings2f936352014-08-05 14:04:04 +10006694
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006695#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006696/*[clinic input]
6697os.setregid
6698
6699 rgid: gid_t
6700 egid: gid_t
6701 /
6702
6703Set the current process's real and effective group ids.
6704[clinic start generated code]*/
6705
Larry Hastings2f936352014-08-05 14:04:04 +10006706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006707os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6708/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006709{
6710 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006712 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006713}
6714#endif /* HAVE_SETREGID */
6715
Larry Hastings2f936352014-08-05 14:04:04 +10006716
Guido van Rossumb6775db1994-08-01 11:34:53 +00006717#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006718/*[clinic input]
6719os.setgid
6720 gid: gid_t
6721 /
6722
6723Set the current process's group id.
6724[clinic start generated code]*/
6725
Larry Hastings2f936352014-08-05 14:04:04 +10006726static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006727os_setgid_impl(PyObject *module, gid_t gid)
6728/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006729{
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 if (setgid(gid) < 0)
6731 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006732 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006733}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006734#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006735
Larry Hastings2f936352014-08-05 14:04:04 +10006736
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006737#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006738/*[clinic input]
6739os.setgroups
6740
6741 groups: object
6742 /
6743
6744Set the groups of the current process to list.
6745[clinic start generated code]*/
6746
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006748os_setgroups(PyObject *module, PyObject *groups)
6749/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006750{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006751 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006753
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 if (!PySequence_Check(groups)) {
6755 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6756 return NULL;
6757 }
6758 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006759 if (len < 0) {
6760 return NULL;
6761 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 if (len > MAX_GROUPS) {
6763 PyErr_SetString(PyExc_ValueError, "too many groups");
6764 return NULL;
6765 }
6766 for(i = 0; i < len; i++) {
6767 PyObject *elem;
6768 elem = PySequence_GetItem(groups, i);
6769 if (!elem)
6770 return NULL;
6771 if (!PyLong_Check(elem)) {
6772 PyErr_SetString(PyExc_TypeError,
6773 "groups must be integers");
6774 Py_DECREF(elem);
6775 return NULL;
6776 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006777 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 Py_DECREF(elem);
6779 return NULL;
6780 }
6781 }
6782 Py_DECREF(elem);
6783 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006784
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 if (setgroups(len, grouplist) < 0)
6786 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006787 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006788}
6789#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006790
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006791#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6792static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006793wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006794{
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 PyObject *result;
6796 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006797 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006798
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 if (pid == -1)
6800 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006801
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 if (struct_rusage == NULL) {
6803 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6804 if (m == NULL)
6805 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006806 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 Py_DECREF(m);
6808 if (struct_rusage == NULL)
6809 return NULL;
6810 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006811
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6813 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6814 if (!result)
6815 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006816
6817#ifndef doubletime
6818#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6819#endif
6820
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006822 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006824 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6827 SET_INT(result, 2, ru->ru_maxrss);
6828 SET_INT(result, 3, ru->ru_ixrss);
6829 SET_INT(result, 4, ru->ru_idrss);
6830 SET_INT(result, 5, ru->ru_isrss);
6831 SET_INT(result, 6, ru->ru_minflt);
6832 SET_INT(result, 7, ru->ru_majflt);
6833 SET_INT(result, 8, ru->ru_nswap);
6834 SET_INT(result, 9, ru->ru_inblock);
6835 SET_INT(result, 10, ru->ru_oublock);
6836 SET_INT(result, 11, ru->ru_msgsnd);
6837 SET_INT(result, 12, ru->ru_msgrcv);
6838 SET_INT(result, 13, ru->ru_nsignals);
6839 SET_INT(result, 14, ru->ru_nvcsw);
6840 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006841#undef SET_INT
6842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 if (PyErr_Occurred()) {
6844 Py_DECREF(result);
6845 return NULL;
6846 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006847
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849}
6850#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6851
Larry Hastings2f936352014-08-05 14:04:04 +10006852
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006853#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006854/*[clinic input]
6855os.wait3
6856
6857 options: int
6858Wait for completion of a child process.
6859
6860Returns a tuple of information about the child process:
6861 (pid, status, rusage)
6862[clinic start generated code]*/
6863
Larry Hastings2f936352014-08-05 14:04:04 +10006864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006865os_wait3_impl(PyObject *module, int options)
6866/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006867{
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006870 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 WAIT_TYPE status;
6872 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006874 do {
6875 Py_BEGIN_ALLOW_THREADS
6876 pid = wait3(&status, options, &ru);
6877 Py_END_ALLOW_THREADS
6878 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6879 if (pid < 0)
6880 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006881
Victor Stinner4195b5c2012-02-08 23:03:19 +01006882 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006883}
6884#endif /* HAVE_WAIT3 */
6885
Larry Hastings2f936352014-08-05 14:04:04 +10006886
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006887#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006888/*[clinic input]
6889
6890os.wait4
6891
6892 pid: pid_t
6893 options: int
6894
6895Wait for completion of a specific child process.
6896
6897Returns a tuple of information about the child process:
6898 (pid, status, rusage)
6899[clinic start generated code]*/
6900
Larry Hastings2f936352014-08-05 14:04:04 +10006901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006902os_wait4_impl(PyObject *module, pid_t pid, int options)
6903/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006904{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006905 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006906 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006907 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 WAIT_TYPE status;
6909 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006910
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006911 do {
6912 Py_BEGIN_ALLOW_THREADS
6913 res = wait4(pid, &status, options, &ru);
6914 Py_END_ALLOW_THREADS
6915 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6916 if (res < 0)
6917 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006918
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006919 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920}
6921#endif /* HAVE_WAIT4 */
6922
Larry Hastings2f936352014-08-05 14:04:04 +10006923
Ross Lagerwall7807c352011-03-17 20:20:30 +02006924#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006925/*[clinic input]
6926os.waitid
6927
6928 idtype: idtype_t
6929 Must be one of be P_PID, P_PGID or P_ALL.
6930 id: id_t
6931 The id to wait on.
6932 options: int
6933 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6934 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6935 /
6936
6937Returns the result of waiting for a process or processes.
6938
6939Returns either waitid_result or None if WNOHANG is specified and there are
6940no children in a waitable state.
6941[clinic start generated code]*/
6942
Larry Hastings2f936352014-08-05 14:04:04 +10006943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006944os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6945/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006946{
6947 PyObject *result;
6948 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006949 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006950 siginfo_t si;
6951 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006952
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006953 do {
6954 Py_BEGIN_ALLOW_THREADS
6955 res = waitid(idtype, id, &si, options);
6956 Py_END_ALLOW_THREADS
6957 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6958 if (res < 0)
6959 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006960
6961 if (si.si_pid == 0)
6962 Py_RETURN_NONE;
6963
6964 result = PyStructSequence_New(&WaitidResultType);
6965 if (!result)
6966 return NULL;
6967
6968 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006969 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006970 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6971 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6972 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6973 if (PyErr_Occurred()) {
6974 Py_DECREF(result);
6975 return NULL;
6976 }
6977
6978 return result;
6979}
Larry Hastings2f936352014-08-05 14:04:04 +10006980#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006981
Larry Hastings2f936352014-08-05 14:04:04 +10006982
6983#if defined(HAVE_WAITPID)
6984/*[clinic input]
6985os.waitpid
6986 pid: pid_t
6987 options: int
6988 /
6989
6990Wait for completion of a given child process.
6991
6992Returns a tuple of information regarding the child process:
6993 (pid, status)
6994
6995The options argument is ignored on Windows.
6996[clinic start generated code]*/
6997
Larry Hastings2f936352014-08-05 14:04:04 +10006998static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006999os_waitpid_impl(PyObject *module, pid_t pid, int options)
7000/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007001{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007002 pid_t res;
7003 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 WAIT_TYPE status;
7005 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007006
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007007 do {
7008 Py_BEGIN_ALLOW_THREADS
7009 res = waitpid(pid, &status, options);
7010 Py_END_ALLOW_THREADS
7011 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7012 if (res < 0)
7013 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007014
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007015 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007016}
Tim Petersab034fa2002-02-01 11:27:43 +00007017#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007018/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007019/*[clinic input]
7020os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007021 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007022 options: int
7023 /
7024
7025Wait for completion of a given process.
7026
7027Returns a tuple of information regarding the process:
7028 (pid, status << 8)
7029
7030The options argument is ignored on Windows.
7031[clinic start generated code]*/
7032
Larry Hastings2f936352014-08-05 14:04:04 +10007033static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007034os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007035/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007036{
7037 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007038 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007039 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007040
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007041 do {
7042 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007043 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007044 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007045 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007046 Py_END_ALLOW_THREADS
7047 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007048 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007049 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007050
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007052 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007053}
Larry Hastings2f936352014-08-05 14:04:04 +10007054#endif
7055
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007056
Guido van Rossumad0ee831995-03-01 10:34:45 +00007057#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007058/*[clinic input]
7059os.wait
7060
7061Wait for completion of a child process.
7062
7063Returns a tuple of information about the child process:
7064 (pid, status)
7065[clinic start generated code]*/
7066
Larry Hastings2f936352014-08-05 14:04:04 +10007067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007068os_wait_impl(PyObject *module)
7069/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007070{
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007072 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 WAIT_TYPE status;
7074 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007075
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007076 do {
7077 Py_BEGIN_ALLOW_THREADS
7078 pid = wait(&status);
7079 Py_END_ALLOW_THREADS
7080 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7081 if (pid < 0)
7082 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007083
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007085}
Larry Hastings2f936352014-08-05 14:04:04 +10007086#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007087
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007088
Larry Hastings9cf065c2012-06-22 16:30:09 -07007089#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7090PyDoc_STRVAR(readlink__doc__,
7091"readlink(path, *, dir_fd=None) -> path\n\n\
7092Return a string representing the path to which the symbolic link points.\n\
7093\n\
7094If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7095 and path should be relative; path will then be relative to that directory.\n\
7096dir_fd may not be implemented on your platform.\n\
7097 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007098#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007099
Guido van Rossumb6775db1994-08-01 11:34:53 +00007100#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007101
Larry Hastings2f936352014-08-05 14:04:04 +10007102/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007103static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007104posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106 path_t path;
7107 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007108 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007109 ssize_t length;
7110 PyObject *return_value = NULL;
7111 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007112
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007114 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7116 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007117 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007119
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007121#ifdef HAVE_READLINKAT
7122 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007123 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007124 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007126 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007127 Py_END_ALLOW_THREADS
7128
7129 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007130 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131 goto exit;
7132 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007133 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134
7135 if (PyUnicode_Check(path.object))
7136 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7137 else
7138 return_value = PyBytes_FromStringAndSize(buffer, length);
7139exit:
7140 path_cleanup(&path);
7141 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007142}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143
Guido van Rossumb6775db1994-08-01 11:34:53 +00007144#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007145
Larry Hastings2f936352014-08-05 14:04:04 +10007146#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7147
7148static PyObject *
7149win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7150{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007151 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007152 DWORD n_bytes_returned;
7153 DWORD io_result;
7154 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007155 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007156 HANDLE reparse_point_handle;
7157
Martin Panter70214ad2016-08-04 02:38:59 +00007158 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7159 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007160 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007161
7162 static char *keywords[] = {"path", "dir_fd", NULL};
7163
7164 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7165 &po,
7166 dir_fd_unavailable, &dir_fd
7167 ))
7168 return NULL;
7169
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007170 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007171 if (path == NULL)
7172 return NULL;
7173
7174 /* First get a handle to the reparse point */
7175 Py_BEGIN_ALLOW_THREADS
7176 reparse_point_handle = CreateFileW(
7177 path,
7178 0,
7179 0,
7180 0,
7181 OPEN_EXISTING,
7182 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7183 0);
7184 Py_END_ALLOW_THREADS
7185
7186 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7187 return win32_error_object("readlink", po);
7188
7189 Py_BEGIN_ALLOW_THREADS
7190 /* New call DeviceIoControl to read the reparse point */
7191 io_result = DeviceIoControl(
7192 reparse_point_handle,
7193 FSCTL_GET_REPARSE_POINT,
7194 0, 0, /* in buffer */
7195 target_buffer, sizeof(target_buffer),
7196 &n_bytes_returned,
7197 0 /* we're not using OVERLAPPED_IO */
7198 );
7199 CloseHandle(reparse_point_handle);
7200 Py_END_ALLOW_THREADS
7201
7202 if (io_result==0)
7203 return win32_error_object("readlink", po);
7204
7205 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7206 {
7207 PyErr_SetString(PyExc_ValueError,
7208 "not a symbolic link");
7209 return NULL;
7210 }
7211 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7212 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7213
7214 result = PyUnicode_FromWideChar(print_name,
7215 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7216 return result;
7217}
7218
7219#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7220
7221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007222
Larry Hastings9cf065c2012-06-22 16:30:09 -07007223#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007224
7225#if defined(MS_WINDOWS)
7226
7227/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007228static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007229
Larry Hastings9cf065c2012-06-22 16:30:09 -07007230static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007231check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007232{
7233 HINSTANCE hKernel32;
7234 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007235 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007236 return 1;
7237 hKernel32 = GetModuleHandleW(L"KERNEL32");
7238 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7239 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007240 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007241}
7242
Victor Stinner31b3b922013-06-05 01:49:17 +02007243/* Remove the last portion of the path */
7244static void
7245_dirnameW(WCHAR *path)
7246{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007247 WCHAR *ptr;
7248
7249 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007250 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007251 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007252 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007253 }
7254 *ptr = 0;
7255}
7256
Victor Stinner31b3b922013-06-05 01:49:17 +02007257/* Is this path absolute? */
7258static int
7259_is_absW(const WCHAR *path)
7260{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007261 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7262
7263}
7264
Victor Stinner31b3b922013-06-05 01:49:17 +02007265/* join root and rest with a backslash */
7266static void
7267_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7268{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007269 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007270
Victor Stinner31b3b922013-06-05 01:49:17 +02007271 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007272 wcscpy(dest_path, rest);
7273 return;
7274 }
7275
7276 root_len = wcslen(root);
7277
7278 wcscpy(dest_path, root);
7279 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007280 dest_path[root_len] = L'\\';
7281 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007282 }
7283 wcscpy(dest_path+root_len, rest);
7284}
7285
Victor Stinner31b3b922013-06-05 01:49:17 +02007286/* Return True if the path at src relative to dest is a directory */
7287static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007288_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007290 WIN32_FILE_ATTRIBUTE_DATA src_info;
7291 WCHAR dest_parent[MAX_PATH];
7292 WCHAR src_resolved[MAX_PATH] = L"";
7293
7294 /* dest_parent = os.path.dirname(dest) */
7295 wcscpy(dest_parent, dest);
7296 _dirnameW(dest_parent);
7297 /* src_resolved = os.path.join(dest_parent, src) */
7298 _joinW(src_resolved, dest_parent, src);
7299 return (
7300 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7301 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7302 );
7303}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007304#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007305
Larry Hastings2f936352014-08-05 14:04:04 +10007306
7307/*[clinic input]
7308os.symlink
7309 src: path_t
7310 dst: path_t
7311 target_is_directory: bool = False
7312 *
7313 dir_fd: dir_fd(requires='symlinkat')=None
7314
7315# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7316
7317Create a symbolic link pointing to src named dst.
7318
7319target_is_directory is required on Windows if the target is to be
7320 interpreted as a directory. (On Windows, symlink requires
7321 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7322 target_is_directory is ignored on non-Windows platforms.
7323
7324If dir_fd is not None, it should be a file descriptor open to a directory,
7325 and path should be relative; path will then be relative to that directory.
7326dir_fd may not be implemented on your platform.
7327 If it is unavailable, using it will raise a NotImplementedError.
7328
7329[clinic start generated code]*/
7330
Larry Hastings2f936352014-08-05 14:04:04 +10007331static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007332os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007333 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007334/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007335{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007336#ifdef MS_WINDOWS
7337 DWORD result;
7338#else
7339 int result;
7340#endif
7341
Larry Hastings9cf065c2012-06-22 16:30:09 -07007342#ifdef MS_WINDOWS
7343 if (!check_CreateSymbolicLink()) {
7344 PyErr_SetString(PyExc_NotImplementedError,
7345 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007346 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007347 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007348 if (!win32_can_symlink) {
7349 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007350 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007351 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007352#endif
7353
Larry Hastings2f936352014-08-05 14:04:04 +10007354 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007355 PyErr_SetString(PyExc_ValueError,
7356 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007357 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007358 }
7359
7360#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007361
Larry Hastings9cf065c2012-06-22 16:30:09 -07007362 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007363 /* if src is a directory, ensure target_is_directory==1 */
7364 target_is_directory |= _check_dirW(src->wide, dst->wide);
7365 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7366 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007367 Py_END_ALLOW_THREADS
7368
Larry Hastings2f936352014-08-05 14:04:04 +10007369 if (!result)
7370 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007371
7372#else
7373
7374 Py_BEGIN_ALLOW_THREADS
7375#if HAVE_SYMLINKAT
7376 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007377 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378 else
7379#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007380 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007381 Py_END_ALLOW_THREADS
7382
Larry Hastings2f936352014-08-05 14:04:04 +10007383 if (result)
7384 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007385#endif
7386
Larry Hastings2f936352014-08-05 14:04:04 +10007387 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007388}
7389#endif /* HAVE_SYMLINK */
7390
Larry Hastings9cf065c2012-06-22 16:30:09 -07007391
Brian Curtind40e6f72010-07-08 21:39:08 +00007392
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007393
Larry Hastings605a62d2012-06-24 04:33:36 -07007394static PyStructSequence_Field times_result_fields[] = {
7395 {"user", "user time"},
7396 {"system", "system time"},
7397 {"children_user", "user time of children"},
7398 {"children_system", "system time of children"},
7399 {"elapsed", "elapsed time since an arbitrary point in the past"},
7400 {NULL}
7401};
7402
7403PyDoc_STRVAR(times_result__doc__,
7404"times_result: Result from os.times().\n\n\
7405This object may be accessed either as a tuple of\n\
7406 (user, system, children_user, children_system, elapsed),\n\
7407or via the attributes user, system, children_user, children_system,\n\
7408and elapsed.\n\
7409\n\
7410See os.times for more information.");
7411
7412static PyStructSequence_Desc times_result_desc = {
7413 "times_result", /* name */
7414 times_result__doc__, /* doc */
7415 times_result_fields,
7416 5
7417};
7418
7419static PyTypeObject TimesResultType;
7420
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007421#ifdef MS_WINDOWS
7422#define HAVE_TIMES /* mandatory, for the method table */
7423#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007424
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007425#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007426
7427static PyObject *
7428build_times_result(double user, double system,
7429 double children_user, double children_system,
7430 double elapsed)
7431{
7432 PyObject *value = PyStructSequence_New(&TimesResultType);
7433 if (value == NULL)
7434 return NULL;
7435
7436#define SET(i, field) \
7437 { \
7438 PyObject *o = PyFloat_FromDouble(field); \
7439 if (!o) { \
7440 Py_DECREF(value); \
7441 return NULL; \
7442 } \
7443 PyStructSequence_SET_ITEM(value, i, o); \
7444 } \
7445
7446 SET(0, user);
7447 SET(1, system);
7448 SET(2, children_user);
7449 SET(3, children_system);
7450 SET(4, elapsed);
7451
7452#undef SET
7453
7454 return value;
7455}
7456
Larry Hastings605a62d2012-06-24 04:33:36 -07007457
Larry Hastings2f936352014-08-05 14:04:04 +10007458#ifndef MS_WINDOWS
7459#define NEED_TICKS_PER_SECOND
7460static long ticks_per_second = -1;
7461#endif /* MS_WINDOWS */
7462
7463/*[clinic input]
7464os.times
7465
7466Return a collection containing process timing information.
7467
7468The object returned behaves like a named tuple with these fields:
7469 (utime, stime, cutime, cstime, elapsed_time)
7470All fields are floating point numbers.
7471[clinic start generated code]*/
7472
Larry Hastings2f936352014-08-05 14:04:04 +10007473static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007474os_times_impl(PyObject *module)
7475/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007476#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007477{
Victor Stinner8c62be82010-05-06 00:08:46 +00007478 FILETIME create, exit, kernel, user;
7479 HANDLE hProc;
7480 hProc = GetCurrentProcess();
7481 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7482 /* The fields of a FILETIME structure are the hi and lo part
7483 of a 64-bit value expressed in 100 nanosecond units.
7484 1e7 is one second in such units; 1e-7 the inverse.
7485 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7486 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007487 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007488 (double)(user.dwHighDateTime*429.4967296 +
7489 user.dwLowDateTime*1e-7),
7490 (double)(kernel.dwHighDateTime*429.4967296 +
7491 kernel.dwLowDateTime*1e-7),
7492 (double)0,
7493 (double)0,
7494 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007495}
Larry Hastings2f936352014-08-05 14:04:04 +10007496#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007497{
Larry Hastings2f936352014-08-05 14:04:04 +10007498
7499
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007500 struct tms t;
7501 clock_t c;
7502 errno = 0;
7503 c = times(&t);
7504 if (c == (clock_t) -1)
7505 return posix_error();
7506 return build_times_result(
7507 (double)t.tms_utime / ticks_per_second,
7508 (double)t.tms_stime / ticks_per_second,
7509 (double)t.tms_cutime / ticks_per_second,
7510 (double)t.tms_cstime / ticks_per_second,
7511 (double)c / ticks_per_second);
7512}
Larry Hastings2f936352014-08-05 14:04:04 +10007513#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007514#endif /* HAVE_TIMES */
7515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007516
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007517#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007518/*[clinic input]
7519os.getsid
7520
7521 pid: pid_t
7522 /
7523
7524Call the system call getsid(pid) and return the result.
7525[clinic start generated code]*/
7526
Larry Hastings2f936352014-08-05 14:04:04 +10007527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007528os_getsid_impl(PyObject *module, pid_t pid)
7529/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007530{
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 sid = getsid(pid);
7533 if (sid < 0)
7534 return posix_error();
7535 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007536}
7537#endif /* HAVE_GETSID */
7538
7539
Guido van Rossumb6775db1994-08-01 11:34:53 +00007540#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007541/*[clinic input]
7542os.setsid
7543
7544Call the system call setsid().
7545[clinic start generated code]*/
7546
Larry Hastings2f936352014-08-05 14:04:04 +10007547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007548os_setsid_impl(PyObject *module)
7549/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007550{
Victor Stinner8c62be82010-05-06 00:08:46 +00007551 if (setsid() < 0)
7552 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007553 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007554}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007555#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007556
Larry Hastings2f936352014-08-05 14:04:04 +10007557
Guido van Rossumb6775db1994-08-01 11:34:53 +00007558#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007559/*[clinic input]
7560os.setpgid
7561
7562 pid: pid_t
7563 pgrp: pid_t
7564 /
7565
7566Call the system call setpgid(pid, pgrp).
7567[clinic start generated code]*/
7568
Larry Hastings2f936352014-08-05 14:04:04 +10007569static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007570os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7571/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007572{
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 if (setpgid(pid, pgrp) < 0)
7574 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007575 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007576}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007577#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007578
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007579
Guido van Rossumb6775db1994-08-01 11:34:53 +00007580#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007581/*[clinic input]
7582os.tcgetpgrp
7583
7584 fd: int
7585 /
7586
7587Return the process group associated with the terminal specified by fd.
7588[clinic start generated code]*/
7589
Larry Hastings2f936352014-08-05 14:04:04 +10007590static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007591os_tcgetpgrp_impl(PyObject *module, int fd)
7592/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007593{
7594 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007595 if (pgid < 0)
7596 return posix_error();
7597 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007598}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007599#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007600
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007601
Guido van Rossumb6775db1994-08-01 11:34:53 +00007602#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007603/*[clinic input]
7604os.tcsetpgrp
7605
7606 fd: int
7607 pgid: pid_t
7608 /
7609
7610Set the process group associated with the terminal specified by fd.
7611[clinic start generated code]*/
7612
Larry Hastings2f936352014-08-05 14:04:04 +10007613static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007614os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7615/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007616{
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 if (tcsetpgrp(fd, pgid) < 0)
7618 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007619 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007620}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007621#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007622
Guido van Rossum687dd131993-05-17 08:34:16 +00007623/* Functions acting on file descriptors */
7624
Victor Stinnerdaf45552013-08-28 00:53:59 +02007625#ifdef O_CLOEXEC
7626extern int _Py_open_cloexec_works;
7627#endif
7628
Larry Hastings2f936352014-08-05 14:04:04 +10007629
7630/*[clinic input]
7631os.open -> int
7632 path: path_t
7633 flags: int
7634 mode: int = 0o777
7635 *
7636 dir_fd: dir_fd(requires='openat') = None
7637
7638# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7639
7640Open a file for low level IO. Returns a file descriptor (integer).
7641
7642If dir_fd is not None, it should be a file descriptor open to a directory,
7643 and path should be relative; path will then be relative to that directory.
7644dir_fd may not be implemented on your platform.
7645 If it is unavailable, using it will raise a NotImplementedError.
7646[clinic start generated code]*/
7647
Larry Hastings2f936352014-08-05 14:04:04 +10007648static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007649os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7650/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007651{
7652 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007653 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007654
Victor Stinnerdaf45552013-08-28 00:53:59 +02007655#ifdef O_CLOEXEC
7656 int *atomic_flag_works = &_Py_open_cloexec_works;
7657#elif !defined(MS_WINDOWS)
7658 int *atomic_flag_works = NULL;
7659#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007660
Victor Stinnerdaf45552013-08-28 00:53:59 +02007661#ifdef MS_WINDOWS
7662 flags |= O_NOINHERIT;
7663#elif defined(O_CLOEXEC)
7664 flags |= O_CLOEXEC;
7665#endif
7666
Steve Dower8fc89802015-04-12 00:26:27 -04007667 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007668 do {
7669 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007670#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007671 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007672#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007673#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007674 if (dir_fd != DEFAULT_DIR_FD)
7675 fd = openat(dir_fd, path->narrow, flags, mode);
7676 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007677#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007678 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007679#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007680 Py_END_ALLOW_THREADS
7681 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007682 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007683
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007684 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007685 if (!async_err)
7686 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007687 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007688 }
7689
Victor Stinnerdaf45552013-08-28 00:53:59 +02007690#ifndef MS_WINDOWS
7691 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7692 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007693 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007694 }
7695#endif
7696
Larry Hastings2f936352014-08-05 14:04:04 +10007697 return fd;
7698}
7699
7700
7701/*[clinic input]
7702os.close
7703
7704 fd: int
7705
7706Close a file descriptor.
7707[clinic start generated code]*/
7708
Barry Warsaw53699e91996-12-10 23:23:01 +00007709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007710os_close_impl(PyObject *module, int fd)
7711/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007712{
Larry Hastings2f936352014-08-05 14:04:04 +10007713 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007714 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7715 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7716 * for more details.
7717 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007718 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007719 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007720 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007721 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 Py_END_ALLOW_THREADS
7723 if (res < 0)
7724 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007725 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007726}
7727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007728
Larry Hastings2f936352014-08-05 14:04:04 +10007729/*[clinic input]
7730os.closerange
7731
7732 fd_low: int
7733 fd_high: int
7734 /
7735
7736Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7737[clinic start generated code]*/
7738
Larry Hastings2f936352014-08-05 14:04:04 +10007739static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007740os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7741/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007742{
7743 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007745 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007746 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007747 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007748 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 Py_END_ALLOW_THREADS
7750 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007751}
7752
7753
Larry Hastings2f936352014-08-05 14:04:04 +10007754/*[clinic input]
7755os.dup -> int
7756
7757 fd: int
7758 /
7759
7760Return a duplicate of a file descriptor.
7761[clinic start generated code]*/
7762
Larry Hastings2f936352014-08-05 14:04:04 +10007763static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007764os_dup_impl(PyObject *module, int fd)
7765/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007766{
7767 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007768}
7769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007770
Larry Hastings2f936352014-08-05 14:04:04 +10007771/*[clinic input]
7772os.dup2
7773 fd: int
7774 fd2: int
7775 inheritable: bool=True
7776
7777Duplicate file descriptor.
7778[clinic start generated code]*/
7779
Larry Hastings2f936352014-08-05 14:04:04 +10007780static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007781os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7782/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007783{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007784 int res;
7785#if defined(HAVE_DUP3) && \
7786 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7787 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7788 int dup3_works = -1;
7789#endif
7790
Steve Dower940f33a2016-09-08 11:21:54 -07007791 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007793
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007794 /* dup2() can fail with EINTR if the target FD is already open, because it
7795 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7796 * upon close(), and therefore below.
7797 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007798#ifdef MS_WINDOWS
7799 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007800 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007802 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007803 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 if (res < 0)
7805 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007806
7807 /* Character files like console cannot be make non-inheritable */
7808 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7809 close(fd2);
7810 return NULL;
7811 }
7812
7813#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7814 Py_BEGIN_ALLOW_THREADS
7815 if (!inheritable)
7816 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7817 else
7818 res = dup2(fd, fd2);
7819 Py_END_ALLOW_THREADS
7820 if (res < 0)
7821 return posix_error();
7822
7823#else
7824
7825#ifdef HAVE_DUP3
7826 if (!inheritable && dup3_works != 0) {
7827 Py_BEGIN_ALLOW_THREADS
7828 res = dup3(fd, fd2, O_CLOEXEC);
7829 Py_END_ALLOW_THREADS
7830 if (res < 0) {
7831 if (dup3_works == -1)
7832 dup3_works = (errno != ENOSYS);
7833 if (dup3_works)
7834 return posix_error();
7835 }
7836 }
7837
7838 if (inheritable || dup3_works == 0)
7839 {
7840#endif
7841 Py_BEGIN_ALLOW_THREADS
7842 res = dup2(fd, fd2);
7843 Py_END_ALLOW_THREADS
7844 if (res < 0)
7845 return posix_error();
7846
7847 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7848 close(fd2);
7849 return NULL;
7850 }
7851#ifdef HAVE_DUP3
7852 }
7853#endif
7854
7855#endif
7856
Larry Hastings2f936352014-08-05 14:04:04 +10007857 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007858}
7859
Larry Hastings2f936352014-08-05 14:04:04 +10007860
Ross Lagerwall7807c352011-03-17 20:20:30 +02007861#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007862/*[clinic input]
7863os.lockf
7864
7865 fd: int
7866 An open file descriptor.
7867 command: int
7868 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7869 length: Py_off_t
7870 The number of bytes to lock, starting at the current position.
7871 /
7872
7873Apply, test or remove a POSIX lock on an open file descriptor.
7874
7875[clinic start generated code]*/
7876
Larry Hastings2f936352014-08-05 14:04:04 +10007877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007878os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7879/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007880{
7881 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007882
7883 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007884 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007885 Py_END_ALLOW_THREADS
7886
7887 if (res < 0)
7888 return posix_error();
7889
7890 Py_RETURN_NONE;
7891}
Larry Hastings2f936352014-08-05 14:04:04 +10007892#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007894
Larry Hastings2f936352014-08-05 14:04:04 +10007895/*[clinic input]
7896os.lseek -> Py_off_t
7897
7898 fd: int
7899 position: Py_off_t
7900 how: int
7901 /
7902
7903Set the position of a file descriptor. Return the new position.
7904
7905Return the new cursor position in number of bytes
7906relative to the beginning of the file.
7907[clinic start generated code]*/
7908
Larry Hastings2f936352014-08-05 14:04:04 +10007909static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007910os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7911/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007912{
7913 Py_off_t result;
7914
Guido van Rossum687dd131993-05-17 08:34:16 +00007915#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7917 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007918 case 0: how = SEEK_SET; break;
7919 case 1: how = SEEK_CUR; break;
7920 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007922#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007923
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007925 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007926
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007928 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007929#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007930 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007931#else
Larry Hastings2f936352014-08-05 14:04:04 +10007932 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007933#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007934 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007935 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007936 if (result < 0)
7937 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007938
Larry Hastings2f936352014-08-05 14:04:04 +10007939 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007940}
7941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007942
Larry Hastings2f936352014-08-05 14:04:04 +10007943/*[clinic input]
7944os.read
7945 fd: int
7946 length: Py_ssize_t
7947 /
7948
7949Read from a file descriptor. Returns a bytes object.
7950[clinic start generated code]*/
7951
Larry Hastings2f936352014-08-05 14:04:04 +10007952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007953os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7954/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007955{
Victor Stinner8c62be82010-05-06 00:08:46 +00007956 Py_ssize_t n;
7957 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007958
7959 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 errno = EINVAL;
7961 return posix_error();
7962 }
Larry Hastings2f936352014-08-05 14:04:04 +10007963
7964#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007965 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007966 if (length > INT_MAX)
7967 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007968#endif
7969
7970 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 if (buffer == NULL)
7972 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007973
Victor Stinner66aab0c2015-03-19 22:53:20 +01007974 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7975 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007977 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 }
Larry Hastings2f936352014-08-05 14:04:04 +10007979
7980 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007982
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007984}
7985
Ross Lagerwall7807c352011-03-17 20:20:30 +02007986#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7987 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007988static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007989iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007990{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007991 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007992 Py_ssize_t blen, total = 0;
7993
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007994 *iov = PyMem_New(struct iovec, cnt);
7995 if (*iov == NULL) {
7996 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007997 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007998 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007999
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008000 *buf = PyMem_New(Py_buffer, cnt);
8001 if (*buf == NULL) {
8002 PyMem_Del(*iov);
8003 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008004 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008005 }
8006
8007 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008008 PyObject *item = PySequence_GetItem(seq, i);
8009 if (item == NULL)
8010 goto fail;
8011 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8012 Py_DECREF(item);
8013 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008014 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008015 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008016 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008017 blen = (*buf)[i].len;
8018 (*iov)[i].iov_len = blen;
8019 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008020 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008021 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008022
8023fail:
8024 PyMem_Del(*iov);
8025 for (j = 0; j < i; j++) {
8026 PyBuffer_Release(&(*buf)[j]);
8027 }
8028 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008029 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008030}
8031
8032static void
8033iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8034{
8035 int i;
8036 PyMem_Del(iov);
8037 for (i = 0; i < cnt; i++) {
8038 PyBuffer_Release(&buf[i]);
8039 }
8040 PyMem_Del(buf);
8041}
8042#endif
8043
Larry Hastings2f936352014-08-05 14:04:04 +10008044
Ross Lagerwall7807c352011-03-17 20:20:30 +02008045#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008046/*[clinic input]
8047os.readv -> Py_ssize_t
8048
8049 fd: int
8050 buffers: object
8051 /
8052
8053Read from a file descriptor fd into an iterable of buffers.
8054
8055The buffers should be mutable buffers accepting bytes.
8056readv will transfer data into each buffer until it is full
8057and then move on to the next buffer in the sequence to hold
8058the rest of the data.
8059
8060readv returns the total number of bytes read,
8061which may be less than the total capacity of all the buffers.
8062[clinic start generated code]*/
8063
Larry Hastings2f936352014-08-05 14:04:04 +10008064static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008065os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8066/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008067{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008068 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008069 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008070 struct iovec *iov;
8071 Py_buffer *buf;
8072
Larry Hastings2f936352014-08-05 14:04:04 +10008073 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008074 PyErr_SetString(PyExc_TypeError,
8075 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008076 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008077 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008078
Larry Hastings2f936352014-08-05 14:04:04 +10008079 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008080 if (cnt < 0)
8081 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008082
8083 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8084 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008085
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008086 do {
8087 Py_BEGIN_ALLOW_THREADS
8088 n = readv(fd, iov, cnt);
8089 Py_END_ALLOW_THREADS
8090 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008091
8092 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008093 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008094 if (!async_err)
8095 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008096 return -1;
8097 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008098
Larry Hastings2f936352014-08-05 14:04:04 +10008099 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008100}
Larry Hastings2f936352014-08-05 14:04:04 +10008101#endif /* HAVE_READV */
8102
Ross Lagerwall7807c352011-03-17 20:20:30 +02008103
8104#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008105/*[clinic input]
8106# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8107os.pread
8108
8109 fd: int
8110 length: int
8111 offset: Py_off_t
8112 /
8113
8114Read a number of bytes from a file descriptor starting at a particular offset.
8115
8116Read length bytes from file descriptor fd, starting at offset bytes from
8117the beginning of the file. The file offset remains unchanged.
8118[clinic start generated code]*/
8119
Larry Hastings2f936352014-08-05 14:04:04 +10008120static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008121os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8122/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008123{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008124 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008125 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008126 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008127
Larry Hastings2f936352014-08-05 14:04:04 +10008128 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008129 errno = EINVAL;
8130 return posix_error();
8131 }
Larry Hastings2f936352014-08-05 14:04:04 +10008132 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133 if (buffer == NULL)
8134 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008135
8136 do {
8137 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008138 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008139 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008140 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008141 Py_END_ALLOW_THREADS
8142 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8143
Ross Lagerwall7807c352011-03-17 20:20:30 +02008144 if (n < 0) {
8145 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008146 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008147 }
Larry Hastings2f936352014-08-05 14:04:04 +10008148 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008149 _PyBytes_Resize(&buffer, n);
8150 return buffer;
8151}
Larry Hastings2f936352014-08-05 14:04:04 +10008152#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008153
Larry Hastings2f936352014-08-05 14:04:04 +10008154
8155/*[clinic input]
8156os.write -> Py_ssize_t
8157
8158 fd: int
8159 data: Py_buffer
8160 /
8161
8162Write a bytes object to a file descriptor.
8163[clinic start generated code]*/
8164
Larry Hastings2f936352014-08-05 14:04:04 +10008165static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008166os_write_impl(PyObject *module, int fd, Py_buffer *data)
8167/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008168{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008169 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008170}
8171
8172#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008173PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008174"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008175sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008176 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008177Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008178
Larry Hastings2f936352014-08-05 14:04:04 +10008179/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008180static PyObject *
8181posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8182{
8183 int in, out;
8184 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008185 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008186 off_t offset;
8187
8188#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8189#ifndef __APPLE__
8190 Py_ssize_t len;
8191#endif
8192 PyObject *headers = NULL, *trailers = NULL;
8193 Py_buffer *hbuf, *tbuf;
8194 off_t sbytes;
8195 struct sf_hdtr sf;
8196 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008197 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008198 static char *keywords[] = {"out", "in",
8199 "offset", "count",
8200 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008201
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008202 sf.headers = NULL;
8203 sf.trailers = NULL;
8204
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008205#ifdef __APPLE__
8206 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008207 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008208#else
8209 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008210 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008211#endif
8212 &headers, &trailers, &flags))
8213 return NULL;
8214 if (headers != NULL) {
8215 if (!PySequence_Check(headers)) {
8216 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008217 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008218 return NULL;
8219 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008220 Py_ssize_t i = PySequence_Size(headers);
8221 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008222 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008223 if (i > INT_MAX) {
8224 PyErr_SetString(PyExc_OverflowError,
8225 "sendfile() header is too large");
8226 return NULL;
8227 }
8228 if (i > 0) {
8229 sf.hdr_cnt = (int)i;
8230 i = iov_setup(&(sf.headers), &hbuf,
8231 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8232 if (i < 0)
8233 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008234#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008235 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008236#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008237 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008238 }
8239 }
8240 if (trailers != NULL) {
8241 if (!PySequence_Check(trailers)) {
8242 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008243 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008244 return NULL;
8245 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008246 Py_ssize_t i = PySequence_Size(trailers);
8247 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008248 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008249 if (i > INT_MAX) {
8250 PyErr_SetString(PyExc_OverflowError,
8251 "sendfile() trailer is too large");
8252 return NULL;
8253 }
8254 if (i > 0) {
8255 sf.trl_cnt = (int)i;
8256 i = iov_setup(&(sf.trailers), &tbuf,
8257 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8258 if (i < 0)
8259 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008260#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008261 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008262#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008263 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008264 }
8265 }
8266
Steve Dower8fc89802015-04-12 00:26:27 -04008267 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008268 do {
8269 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008270#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008271 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008273 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008274#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008275 Py_END_ALLOW_THREADS
8276 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008277 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008278
8279 if (sf.headers != NULL)
8280 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8281 if (sf.trailers != NULL)
8282 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8283
8284 if (ret < 0) {
8285 if ((errno == EAGAIN) || (errno == EBUSY)) {
8286 if (sbytes != 0) {
8287 // some data has been sent
8288 goto done;
8289 }
8290 else {
8291 // no data has been sent; upper application is supposed
8292 // to retry on EAGAIN or EBUSY
8293 return posix_error();
8294 }
8295 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008296 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008297 }
8298 goto done;
8299
8300done:
8301 #if !defined(HAVE_LARGEFILE_SUPPORT)
8302 return Py_BuildValue("l", sbytes);
8303 #else
8304 return Py_BuildValue("L", sbytes);
8305 #endif
8306
8307#else
8308 Py_ssize_t count;
8309 PyObject *offobj;
8310 static char *keywords[] = {"out", "in",
8311 "offset", "count", NULL};
8312 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8313 keywords, &out, &in, &offobj, &count))
8314 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008315#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008316 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008317 do {
8318 Py_BEGIN_ALLOW_THREADS
8319 ret = sendfile(out, in, NULL, count);
8320 Py_END_ALLOW_THREADS
8321 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008323 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008324 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325 }
8326#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008327 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008328 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008329
8330 do {
8331 Py_BEGIN_ALLOW_THREADS
8332 ret = sendfile(out, in, &offset, count);
8333 Py_END_ALLOW_THREADS
8334 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008336 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008337 return Py_BuildValue("n", ret);
8338#endif
8339}
Larry Hastings2f936352014-08-05 14:04:04 +10008340#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008341
Larry Hastings2f936352014-08-05 14:04:04 +10008342
8343/*[clinic input]
8344os.fstat
8345
8346 fd : int
8347
8348Perform a stat system call on the given file descriptor.
8349
8350Like stat(), but for an open file descriptor.
8351Equivalent to os.stat(fd).
8352[clinic start generated code]*/
8353
Larry Hastings2f936352014-08-05 14:04:04 +10008354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008355os_fstat_impl(PyObject *module, int fd)
8356/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008357{
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 STRUCT_STAT st;
8359 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008360 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008361
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008362 do {
8363 Py_BEGIN_ALLOW_THREADS
8364 res = FSTAT(fd, &st);
8365 Py_END_ALLOW_THREADS
8366 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008367 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008368#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008369 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008370#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008371 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008372#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 }
Tim Peters5aa91602002-01-30 05:46:57 +00008374
Victor Stinner4195b5c2012-02-08 23:03:19 +01008375 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008376}
8377
Larry Hastings2f936352014-08-05 14:04:04 +10008378
8379/*[clinic input]
8380os.isatty -> bool
8381 fd: int
8382 /
8383
8384Return True if the fd is connected to a terminal.
8385
8386Return True if the file descriptor is an open file descriptor
8387connected to the slave end of a terminal.
8388[clinic start generated code]*/
8389
Larry Hastings2f936352014-08-05 14:04:04 +10008390static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008391os_isatty_impl(PyObject *module, int fd)
8392/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008393{
Steve Dower8fc89802015-04-12 00:26:27 -04008394 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008395 _Py_BEGIN_SUPPRESS_IPH
8396 return_value = isatty(fd);
8397 _Py_END_SUPPRESS_IPH
8398 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008399}
8400
8401
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008402#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008403/*[clinic input]
8404os.pipe
8405
8406Create a pipe.
8407
8408Returns a tuple of two file descriptors:
8409 (read_fd, write_fd)
8410[clinic start generated code]*/
8411
Larry Hastings2f936352014-08-05 14:04:04 +10008412static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008413os_pipe_impl(PyObject *module)
8414/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008415{
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008417#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008419 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008421#else
8422 int res;
8423#endif
8424
8425#ifdef MS_WINDOWS
8426 attr.nLength = sizeof(attr);
8427 attr.lpSecurityDescriptor = NULL;
8428 attr.bInheritHandle = FALSE;
8429
8430 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008431 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008432 ok = CreatePipe(&read, &write, &attr, 0);
8433 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008434 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8435 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008436 if (fds[0] == -1 || fds[1] == -1) {
8437 CloseHandle(read);
8438 CloseHandle(write);
8439 ok = 0;
8440 }
8441 }
Steve Dowerc3630612016-11-19 18:41:16 -08008442 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008443 Py_END_ALLOW_THREADS
8444
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008446 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008447#else
8448
8449#ifdef HAVE_PIPE2
8450 Py_BEGIN_ALLOW_THREADS
8451 res = pipe2(fds, O_CLOEXEC);
8452 Py_END_ALLOW_THREADS
8453
8454 if (res != 0 && errno == ENOSYS)
8455 {
8456#endif
8457 Py_BEGIN_ALLOW_THREADS
8458 res = pipe(fds);
8459 Py_END_ALLOW_THREADS
8460
8461 if (res == 0) {
8462 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8463 close(fds[0]);
8464 close(fds[1]);
8465 return NULL;
8466 }
8467 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8468 close(fds[0]);
8469 close(fds[1]);
8470 return NULL;
8471 }
8472 }
8473#ifdef HAVE_PIPE2
8474 }
8475#endif
8476
8477 if (res != 0)
8478 return PyErr_SetFromErrno(PyExc_OSError);
8479#endif /* !MS_WINDOWS */
8480 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008481}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008482#endif /* HAVE_PIPE */
8483
Larry Hastings2f936352014-08-05 14:04:04 +10008484
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008485#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008486/*[clinic input]
8487os.pipe2
8488
8489 flags: int
8490 /
8491
8492Create a pipe with flags set atomically.
8493
8494Returns a tuple of two file descriptors:
8495 (read_fd, write_fd)
8496
8497flags can be constructed by ORing together one or more of these values:
8498O_NONBLOCK, O_CLOEXEC.
8499[clinic start generated code]*/
8500
Larry Hastings2f936352014-08-05 14:04:04 +10008501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008502os_pipe2_impl(PyObject *module, int flags)
8503/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008504{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008505 int fds[2];
8506 int res;
8507
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008508 res = pipe2(fds, flags);
8509 if (res != 0)
8510 return posix_error();
8511 return Py_BuildValue("(ii)", fds[0], fds[1]);
8512}
8513#endif /* HAVE_PIPE2 */
8514
Larry Hastings2f936352014-08-05 14:04:04 +10008515
Ross Lagerwall7807c352011-03-17 20:20:30 +02008516#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008517/*[clinic input]
8518os.writev -> Py_ssize_t
8519 fd: int
8520 buffers: object
8521 /
8522
8523Iterate over buffers, and write the contents of each to a file descriptor.
8524
8525Returns the total number of bytes written.
8526buffers must be a sequence of bytes-like objects.
8527[clinic start generated code]*/
8528
Larry Hastings2f936352014-08-05 14:04:04 +10008529static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008530os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8531/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008532{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008533 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008534 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008535 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008536 struct iovec *iov;
8537 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008538
8539 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008540 PyErr_SetString(PyExc_TypeError,
8541 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008542 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008543 }
Larry Hastings2f936352014-08-05 14:04:04 +10008544 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008545 if (cnt < 0)
8546 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008547
Larry Hastings2f936352014-08-05 14:04:04 +10008548 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8549 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008550 }
8551
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008552 do {
8553 Py_BEGIN_ALLOW_THREADS
8554 result = writev(fd, iov, cnt);
8555 Py_END_ALLOW_THREADS
8556 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008557
8558 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008559 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008560 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008561
Georg Brandl306336b2012-06-24 12:55:33 +02008562 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008563}
Larry Hastings2f936352014-08-05 14:04:04 +10008564#endif /* HAVE_WRITEV */
8565
8566
8567#ifdef HAVE_PWRITE
8568/*[clinic input]
8569os.pwrite -> Py_ssize_t
8570
8571 fd: int
8572 buffer: Py_buffer
8573 offset: Py_off_t
8574 /
8575
8576Write bytes to a file descriptor starting at a particular offset.
8577
8578Write buffer to fd, starting at offset bytes from the beginning of
8579the file. Returns the number of bytes writte. Does not change the
8580current file offset.
8581[clinic start generated code]*/
8582
Larry Hastings2f936352014-08-05 14:04:04 +10008583static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008584os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8585/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008586{
8587 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008588 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008589
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008590 do {
8591 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008592 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008593 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008594 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008595 Py_END_ALLOW_THREADS
8596 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008597
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008598 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008599 posix_error();
8600 return size;
8601}
8602#endif /* HAVE_PWRITE */
8603
8604
8605#ifdef HAVE_MKFIFO
8606/*[clinic input]
8607os.mkfifo
8608
8609 path: path_t
8610 mode: int=0o666
8611 *
8612 dir_fd: dir_fd(requires='mkfifoat')=None
8613
8614Create a "fifo" (a POSIX named pipe).
8615
8616If dir_fd is not None, it should be a file descriptor open to a directory,
8617 and path should be relative; path will then be relative to that directory.
8618dir_fd may not be implemented on your platform.
8619 If it is unavailable, using it will raise a NotImplementedError.
8620[clinic start generated code]*/
8621
Larry Hastings2f936352014-08-05 14:04:04 +10008622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008623os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8624/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008625{
8626 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008627 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008628
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008629 do {
8630 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008631#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008632 if (dir_fd != DEFAULT_DIR_FD)
8633 result = mkfifoat(dir_fd, path->narrow, mode);
8634 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008635#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008636 result = mkfifo(path->narrow, mode);
8637 Py_END_ALLOW_THREADS
8638 } while (result != 0 && errno == EINTR &&
8639 !(async_err = PyErr_CheckSignals()));
8640 if (result != 0)
8641 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008642
8643 Py_RETURN_NONE;
8644}
8645#endif /* HAVE_MKFIFO */
8646
8647
8648#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8649/*[clinic input]
8650os.mknod
8651
8652 path: path_t
8653 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008654 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008655 *
8656 dir_fd: dir_fd(requires='mknodat')=None
8657
8658Create a node in the file system.
8659
8660Create a node in the file system (file, device special file or named pipe)
8661at path. mode specifies both the permissions to use and the
8662type of node to be created, being combined (bitwise OR) with one of
8663S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8664device defines the newly created device special file (probably using
8665os.makedev()). Otherwise device is ignored.
8666
8667If dir_fd is not None, it should be a file descriptor open to a directory,
8668 and path should be relative; path will then be relative to that directory.
8669dir_fd may not be implemented on your platform.
8670 If it is unavailable, using it will raise a NotImplementedError.
8671[clinic start generated code]*/
8672
Larry Hastings2f936352014-08-05 14:04:04 +10008673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008674os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008675 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008676/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008677{
8678 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008679 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008680
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008681 do {
8682 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008683#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684 if (dir_fd != DEFAULT_DIR_FD)
8685 result = mknodat(dir_fd, path->narrow, mode, device);
8686 else
Larry Hastings2f936352014-08-05 14:04:04 +10008687#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008688 result = mknod(path->narrow, mode, device);
8689 Py_END_ALLOW_THREADS
8690 } while (result != 0 && errno == EINTR &&
8691 !(async_err = PyErr_CheckSignals()));
8692 if (result != 0)
8693 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008694
8695 Py_RETURN_NONE;
8696}
8697#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8698
8699
8700#ifdef HAVE_DEVICE_MACROS
8701/*[clinic input]
8702os.major -> unsigned_int
8703
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008704 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008705 /
8706
8707Extracts a device major number from a raw device number.
8708[clinic start generated code]*/
8709
Larry Hastings2f936352014-08-05 14:04:04 +10008710static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008711os_major_impl(PyObject *module, dev_t device)
8712/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008713{
8714 return major(device);
8715}
8716
8717
8718/*[clinic input]
8719os.minor -> unsigned_int
8720
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008721 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008722 /
8723
8724Extracts a device minor number from a raw device number.
8725[clinic start generated code]*/
8726
Larry Hastings2f936352014-08-05 14:04:04 +10008727static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008728os_minor_impl(PyObject *module, dev_t device)
8729/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008730{
8731 return minor(device);
8732}
8733
8734
8735/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008736os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008737
8738 major: int
8739 minor: int
8740 /
8741
8742Composes a raw device number from the major and minor device numbers.
8743[clinic start generated code]*/
8744
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008745static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008746os_makedev_impl(PyObject *module, int major, int minor)
8747/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008748{
8749 return makedev(major, minor);
8750}
8751#endif /* HAVE_DEVICE_MACROS */
8752
8753
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008754#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008755/*[clinic input]
8756os.ftruncate
8757
8758 fd: int
8759 length: Py_off_t
8760 /
8761
8762Truncate a file, specified by file descriptor, to a specific length.
8763[clinic start generated code]*/
8764
Larry Hastings2f936352014-08-05 14:04:04 +10008765static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008766os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8767/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008768{
8769 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008770 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008771
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008772 do {
8773 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008774 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008775#ifdef MS_WINDOWS
8776 result = _chsize_s(fd, length);
8777#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008778 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008779#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008780 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008781 Py_END_ALLOW_THREADS
8782 } while (result != 0 && errno == EINTR &&
8783 !(async_err = PyErr_CheckSignals()));
8784 if (result != 0)
8785 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008786 Py_RETURN_NONE;
8787}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008788#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008789
8790
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008791#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008792/*[clinic input]
8793os.truncate
8794 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8795 length: Py_off_t
8796
8797Truncate a file, specified by path, to a specific length.
8798
8799On some platforms, path may also be specified as an open file descriptor.
8800 If this functionality is unavailable, using it raises an exception.
8801[clinic start generated code]*/
8802
Larry Hastings2f936352014-08-05 14:04:04 +10008803static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008804os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8805/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008806{
8807 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008808#ifdef MS_WINDOWS
8809 int fd;
8810#endif
8811
8812 if (path->fd != -1)
8813 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008814
8815 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008816 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008817#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008818 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008819 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008820 result = -1;
8821 else {
8822 result = _chsize_s(fd, length);
8823 close(fd);
8824 if (result < 0)
8825 errno = result;
8826 }
8827#else
8828 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008829#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008830 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008831 Py_END_ALLOW_THREADS
8832 if (result < 0)
8833 return path_error(path);
8834
8835 Py_RETURN_NONE;
8836}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008837#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008838
Ross Lagerwall7807c352011-03-17 20:20:30 +02008839
Victor Stinnerd6b17692014-09-30 12:20:05 +02008840/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8841 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8842 defined, which is the case in Python on AIX. AIX bug report:
8843 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8844#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8845# define POSIX_FADVISE_AIX_BUG
8846#endif
8847
Victor Stinnerec39e262014-09-30 12:35:58 +02008848
Victor Stinnerd6b17692014-09-30 12:20:05 +02008849#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008850/*[clinic input]
8851os.posix_fallocate
8852
8853 fd: int
8854 offset: Py_off_t
8855 length: Py_off_t
8856 /
8857
8858Ensure a file has allocated at least a particular number of bytes on disk.
8859
8860Ensure that the file specified by fd encompasses a range of bytes
8861starting at offset bytes from the beginning and continuing for length bytes.
8862[clinic start generated code]*/
8863
Larry Hastings2f936352014-08-05 14:04:04 +10008864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008865os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008866 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008867/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008868{
8869 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008870 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008871
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008872 do {
8873 Py_BEGIN_ALLOW_THREADS
8874 result = posix_fallocate(fd, offset, length);
8875 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008876 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8877
8878 if (result == 0)
8879 Py_RETURN_NONE;
8880
8881 if (async_err)
8882 return NULL;
8883
8884 errno = result;
8885 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008886}
Victor Stinnerec39e262014-09-30 12:35:58 +02008887#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008888
Ross Lagerwall7807c352011-03-17 20:20:30 +02008889
Victor Stinnerd6b17692014-09-30 12:20:05 +02008890#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008891/*[clinic input]
8892os.posix_fadvise
8893
8894 fd: int
8895 offset: Py_off_t
8896 length: Py_off_t
8897 advice: int
8898 /
8899
8900Announce an intention to access data in a specific pattern.
8901
8902Announce an intention to access data in a specific pattern, thus allowing
8903the kernel to make optimizations.
8904The advice applies to the region of the file specified by fd starting at
8905offset and continuing for length bytes.
8906advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8907POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8908POSIX_FADV_DONTNEED.
8909[clinic start generated code]*/
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008912os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008913 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008914/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008915{
8916 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008917 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008918
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008919 do {
8920 Py_BEGIN_ALLOW_THREADS
8921 result = posix_fadvise(fd, offset, length, advice);
8922 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008923 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8924
8925 if (result == 0)
8926 Py_RETURN_NONE;
8927
8928 if (async_err)
8929 return NULL;
8930
8931 errno = result;
8932 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008933}
Victor Stinnerec39e262014-09-30 12:35:58 +02008934#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008935
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008936#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008937
Fred Drake762e2061999-08-26 17:23:54 +00008938/* Save putenv() parameters as values here, so we can collect them when they
8939 * get re-set with another call for the same key. */
8940static PyObject *posix_putenv_garbage;
8941
Larry Hastings2f936352014-08-05 14:04:04 +10008942static void
8943posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008944{
Larry Hastings2f936352014-08-05 14:04:04 +10008945 /* Install the first arg and newstr in posix_putenv_garbage;
8946 * this will cause previous value to be collected. This has to
8947 * happen after the real putenv() call because the old value
8948 * was still accessible until then. */
8949 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8950 /* really not much we can do; just leak */
8951 PyErr_Clear();
8952 else
8953 Py_DECREF(value);
8954}
8955
8956
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008957#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008958/*[clinic input]
8959os.putenv
8960
8961 name: unicode
8962 value: unicode
8963 /
8964
8965Change or add an environment variable.
8966[clinic start generated code]*/
8967
Larry Hastings2f936352014-08-05 14:04:04 +10008968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008969os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8970/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008971{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008972 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008973 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10008974
Serhiy Storchaka77703942017-06-25 07:33:01 +03008975 /* Search from index 1 because on Windows starting '=' is allowed for
8976 defining hidden environment variables. */
8977 if (PyUnicode_GET_LENGTH(name) == 0 ||
8978 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
8979 {
8980 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
8981 return NULL;
8982 }
Larry Hastings2f936352014-08-05 14:04:04 +10008983 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8984 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10008985 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008986 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008987
8988 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
8989 if (env == NULL)
8990 goto error;
8991 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01008992 PyErr_Format(PyExc_ValueError,
8993 "the environment variable is longer than %u characters",
8994 _MAX_ENV);
8995 goto error;
8996 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008997 if (wcslen(env) != (size_t)size) {
8998 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02008999 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009000 }
9001
Larry Hastings2f936352014-08-05 14:04:04 +10009002 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009004 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009005 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009006
Larry Hastings2f936352014-08-05 14:04:04 +10009007 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009008 Py_RETURN_NONE;
9009
9010error:
Larry Hastings2f936352014-08-05 14:04:04 +10009011 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009012 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009013}
Larry Hastings2f936352014-08-05 14:04:04 +10009014#else /* MS_WINDOWS */
9015/*[clinic input]
9016os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009017
Larry Hastings2f936352014-08-05 14:04:04 +10009018 name: FSConverter
9019 value: FSConverter
9020 /
9021
9022Change or add an environment variable.
9023[clinic start generated code]*/
9024
Larry Hastings2f936352014-08-05 14:04:04 +10009025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009026os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9027/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009028{
9029 PyObject *bytes = NULL;
9030 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009031 const char *name_string = PyBytes_AS_STRING(name);
9032 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009033
Serhiy Storchaka77703942017-06-25 07:33:01 +03009034 if (strchr(name_string, '=') != NULL) {
9035 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9036 return NULL;
9037 }
Larry Hastings2f936352014-08-05 14:04:04 +10009038 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9039 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009040 return NULL;
9041 }
9042
9043 env = PyBytes_AS_STRING(bytes);
9044 if (putenv(env)) {
9045 Py_DECREF(bytes);
9046 return posix_error();
9047 }
9048
9049 posix_putenv_garbage_setitem(name, bytes);
9050 Py_RETURN_NONE;
9051}
9052#endif /* MS_WINDOWS */
9053#endif /* HAVE_PUTENV */
9054
9055
9056#ifdef HAVE_UNSETENV
9057/*[clinic input]
9058os.unsetenv
9059 name: FSConverter
9060 /
9061
9062Delete an environment variable.
9063[clinic start generated code]*/
9064
Larry Hastings2f936352014-08-05 14:04:04 +10009065static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009066os_unsetenv_impl(PyObject *module, PyObject *name)
9067/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009068{
Victor Stinner984890f2011-11-24 13:53:38 +01009069#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009070 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009071#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009072
Victor Stinner984890f2011-11-24 13:53:38 +01009073#ifdef HAVE_BROKEN_UNSETENV
9074 unsetenv(PyBytes_AS_STRING(name));
9075#else
Victor Stinner65170952011-11-22 22:16:17 +01009076 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009077 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009078 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009079#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009080
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 /* Remove the key from posix_putenv_garbage;
9082 * this will cause it to be collected. This has to
9083 * happen after the real unsetenv() call because the
9084 * old value was still accessible until then.
9085 */
Victor Stinner65170952011-11-22 22:16:17 +01009086 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 /* really not much we can do; just leak */
9088 PyErr_Clear();
9089 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009090 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009091}
Larry Hastings2f936352014-08-05 14:04:04 +10009092#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009093
Larry Hastings2f936352014-08-05 14:04:04 +10009094
9095/*[clinic input]
9096os.strerror
9097
9098 code: int
9099 /
9100
9101Translate an error code to a message string.
9102[clinic start generated code]*/
9103
Larry Hastings2f936352014-08-05 14:04:04 +10009104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009105os_strerror_impl(PyObject *module, int code)
9106/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009107{
9108 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 if (message == NULL) {
9110 PyErr_SetString(PyExc_ValueError,
9111 "strerror() argument out of range");
9112 return NULL;
9113 }
Victor Stinner1b579672011-12-17 05:47:23 +01009114 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009115}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009116
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009117
Guido van Rossumc9641791998-08-04 15:26:23 +00009118#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009119#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009120/*[clinic input]
9121os.WCOREDUMP -> bool
9122
9123 status: int
9124 /
9125
9126Return True if the process returning status was dumped to a core file.
9127[clinic start generated code]*/
9128
Larry Hastings2f936352014-08-05 14:04:04 +10009129static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009130os_WCOREDUMP_impl(PyObject *module, int status)
9131/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009132{
9133 WAIT_TYPE wait_status;
9134 WAIT_STATUS_INT(wait_status) = status;
9135 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009136}
9137#endif /* WCOREDUMP */
9138
Larry Hastings2f936352014-08-05 14:04:04 +10009139
Fred Drake106c1a02002-04-23 15:58:02 +00009140#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009141/*[clinic input]
9142os.WIFCONTINUED -> bool
9143
9144 status: int
9145
9146Return True if a particular process was continued from a job control stop.
9147
9148Return True if the process returning status was continued from a
9149job control stop.
9150[clinic start generated code]*/
9151
Larry Hastings2f936352014-08-05 14:04:04 +10009152static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009153os_WIFCONTINUED_impl(PyObject *module, int status)
9154/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009155{
9156 WAIT_TYPE wait_status;
9157 WAIT_STATUS_INT(wait_status) = status;
9158 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009159}
9160#endif /* WIFCONTINUED */
9161
Larry Hastings2f936352014-08-05 14:04:04 +10009162
Guido van Rossumc9641791998-08-04 15:26:23 +00009163#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009164/*[clinic input]
9165os.WIFSTOPPED -> bool
9166
9167 status: int
9168
9169Return True if the process returning status was stopped.
9170[clinic start generated code]*/
9171
Larry Hastings2f936352014-08-05 14:04:04 +10009172static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009173os_WIFSTOPPED_impl(PyObject *module, int status)
9174/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009175{
9176 WAIT_TYPE wait_status;
9177 WAIT_STATUS_INT(wait_status) = status;
9178 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009179}
9180#endif /* WIFSTOPPED */
9181
Larry Hastings2f936352014-08-05 14:04:04 +10009182
Guido van Rossumc9641791998-08-04 15:26:23 +00009183#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009184/*[clinic input]
9185os.WIFSIGNALED -> bool
9186
9187 status: int
9188
9189Return True if the process returning status was terminated by a signal.
9190[clinic start generated code]*/
9191
Larry Hastings2f936352014-08-05 14:04:04 +10009192static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009193os_WIFSIGNALED_impl(PyObject *module, int status)
9194/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009195{
9196 WAIT_TYPE wait_status;
9197 WAIT_STATUS_INT(wait_status) = status;
9198 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009199}
9200#endif /* WIFSIGNALED */
9201
Larry Hastings2f936352014-08-05 14:04:04 +10009202
Guido van Rossumc9641791998-08-04 15:26:23 +00009203#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009204/*[clinic input]
9205os.WIFEXITED -> bool
9206
9207 status: int
9208
9209Return True if the process returning status exited via the exit() system call.
9210[clinic start generated code]*/
9211
Larry Hastings2f936352014-08-05 14:04:04 +10009212static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009213os_WIFEXITED_impl(PyObject *module, int status)
9214/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009215{
9216 WAIT_TYPE wait_status;
9217 WAIT_STATUS_INT(wait_status) = status;
9218 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009219}
9220#endif /* WIFEXITED */
9221
Larry Hastings2f936352014-08-05 14:04:04 +10009222
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009223#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009224/*[clinic input]
9225os.WEXITSTATUS -> int
9226
9227 status: int
9228
9229Return the process return code from status.
9230[clinic start generated code]*/
9231
Larry Hastings2f936352014-08-05 14:04:04 +10009232static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009233os_WEXITSTATUS_impl(PyObject *module, int status)
9234/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009235{
9236 WAIT_TYPE wait_status;
9237 WAIT_STATUS_INT(wait_status) = status;
9238 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009239}
9240#endif /* WEXITSTATUS */
9241
Larry Hastings2f936352014-08-05 14:04:04 +10009242
Guido van Rossumc9641791998-08-04 15:26:23 +00009243#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009244/*[clinic input]
9245os.WTERMSIG -> int
9246
9247 status: int
9248
9249Return the signal that terminated the process that provided the status value.
9250[clinic start generated code]*/
9251
Larry Hastings2f936352014-08-05 14:04:04 +10009252static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009253os_WTERMSIG_impl(PyObject *module, int status)
9254/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009255{
9256 WAIT_TYPE wait_status;
9257 WAIT_STATUS_INT(wait_status) = status;
9258 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009259}
9260#endif /* WTERMSIG */
9261
Larry Hastings2f936352014-08-05 14:04:04 +10009262
Guido van Rossumc9641791998-08-04 15:26:23 +00009263#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009264/*[clinic input]
9265os.WSTOPSIG -> int
9266
9267 status: int
9268
9269Return the signal that stopped the process that provided the status value.
9270[clinic start generated code]*/
9271
Larry Hastings2f936352014-08-05 14:04:04 +10009272static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009273os_WSTOPSIG_impl(PyObject *module, int status)
9274/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009275{
9276 WAIT_TYPE wait_status;
9277 WAIT_STATUS_INT(wait_status) = status;
9278 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009279}
9280#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009281#endif /* HAVE_SYS_WAIT_H */
9282
9283
Thomas Wouters477c8d52006-05-27 19:21:47 +00009284#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009285#ifdef _SCO_DS
9286/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9287 needed definitions in sys/statvfs.h */
9288#define _SVID3
9289#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009290#include <sys/statvfs.h>
9291
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009292static PyObject*
9293_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9295 if (v == NULL)
9296 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009297
9298#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9300 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9301 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9302 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9303 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9304 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9305 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9306 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9307 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9308 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009309#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9311 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9312 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009313 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009315 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009317 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009319 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009321 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009323 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9325 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009326#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009327 if (PyErr_Occurred()) {
9328 Py_DECREF(v);
9329 return NULL;
9330 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009331
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009333}
9334
Larry Hastings2f936352014-08-05 14:04:04 +10009335
9336/*[clinic input]
9337os.fstatvfs
9338 fd: int
9339 /
9340
9341Perform an fstatvfs system call on the given fd.
9342
9343Equivalent to statvfs(fd).
9344[clinic start generated code]*/
9345
Larry Hastings2f936352014-08-05 14:04:04 +10009346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009347os_fstatvfs_impl(PyObject *module, int fd)
9348/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009349{
9350 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009351 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009353
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009354 do {
9355 Py_BEGIN_ALLOW_THREADS
9356 result = fstatvfs(fd, &st);
9357 Py_END_ALLOW_THREADS
9358 } while (result != 0 && errno == EINTR &&
9359 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009360 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009361 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009362
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009364}
Larry Hastings2f936352014-08-05 14:04:04 +10009365#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009366
9367
Thomas Wouters477c8d52006-05-27 19:21:47 +00009368#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009369#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009370/*[clinic input]
9371os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009372
Larry Hastings2f936352014-08-05 14:04:04 +10009373 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9374
9375Perform a statvfs system call on the given path.
9376
9377path may always be specified as a string.
9378On some platforms, path may also be specified as an open file descriptor.
9379 If this functionality is unavailable, using it raises an exception.
9380[clinic start generated code]*/
9381
Larry Hastings2f936352014-08-05 14:04:04 +10009382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009383os_statvfs_impl(PyObject *module, path_t *path)
9384/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009385{
9386 int result;
9387 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009388
9389 Py_BEGIN_ALLOW_THREADS
9390#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009391 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009392#ifdef __APPLE__
9393 /* handle weak-linking on Mac OS X 10.3 */
9394 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009395 fd_specified("statvfs", path->fd);
9396 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009397 }
9398#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009399 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009400 }
9401 else
9402#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009403 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009404 Py_END_ALLOW_THREADS
9405
9406 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009407 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009408 }
9409
Larry Hastings2f936352014-08-05 14:04:04 +10009410 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009411}
Larry Hastings2f936352014-08-05 14:04:04 +10009412#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9413
Guido van Rossum94f6f721999-01-06 18:42:14 +00009414
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009415#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009416/*[clinic input]
9417os._getdiskusage
9418
9419 path: Py_UNICODE
9420
9421Return disk usage statistics about the given path as a (total, free) tuple.
9422[clinic start generated code]*/
9423
Larry Hastings2f936352014-08-05 14:04:04 +10009424static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009425os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9426/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009427{
9428 BOOL retval;
9429 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009430
9431 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009432 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009433 Py_END_ALLOW_THREADS
9434 if (retval == 0)
9435 return PyErr_SetFromWindowsErr(0);
9436
9437 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9438}
Larry Hastings2f936352014-08-05 14:04:04 +10009439#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009440
9441
Fred Drakec9680921999-12-13 16:37:25 +00009442/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9443 * It maps strings representing configuration variable names to
9444 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009445 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009446 * rarely-used constants. There are three separate tables that use
9447 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009448 *
9449 * This code is always included, even if none of the interfaces that
9450 * need it are included. The #if hackery needed to avoid it would be
9451 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009452 */
9453struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009454 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009455 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009456};
9457
Fred Drake12c6e2d1999-12-14 21:25:03 +00009458static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009459conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009460 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009461{
Christian Heimes217cfd12007-12-02 14:31:20 +00009462 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009463 int value = _PyLong_AsInt(arg);
9464 if (value == -1 && PyErr_Occurred())
9465 return 0;
9466 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009467 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009468 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009469 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009470 /* look up the value in the table using a binary search */
9471 size_t lo = 0;
9472 size_t mid;
9473 size_t hi = tablesize;
9474 int cmp;
9475 const char *confname;
9476 if (!PyUnicode_Check(arg)) {
9477 PyErr_SetString(PyExc_TypeError,
9478 "configuration names must be strings or integers");
9479 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009481 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009482 if (confname == NULL)
9483 return 0;
9484 while (lo < hi) {
9485 mid = (lo + hi) / 2;
9486 cmp = strcmp(confname, table[mid].name);
9487 if (cmp < 0)
9488 hi = mid;
9489 else if (cmp > 0)
9490 lo = mid + 1;
9491 else {
9492 *valuep = table[mid].value;
9493 return 1;
9494 }
9495 }
9496 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9497 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009499}
9500
9501
9502#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9503static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009504#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009506#endif
9507#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009509#endif
Fred Drakec9680921999-12-13 16:37:25 +00009510#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009512#endif
9513#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009515#endif
9516#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009518#endif
9519#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009521#endif
9522#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009524#endif
9525#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009527#endif
9528#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009530#endif
9531#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009533#endif
9534#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009536#endif
9537#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009555#ifdef _PC_ACL_ENABLED
9556 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9557#endif
9558#ifdef _PC_MIN_HOLE_SIZE
9559 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9560#endif
9561#ifdef _PC_ALLOC_SIZE_MIN
9562 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9563#endif
9564#ifdef _PC_REC_INCR_XFER_SIZE
9565 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9566#endif
9567#ifdef _PC_REC_MAX_XFER_SIZE
9568 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9569#endif
9570#ifdef _PC_REC_MIN_XFER_SIZE
9571 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9572#endif
9573#ifdef _PC_REC_XFER_ALIGN
9574 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9575#endif
9576#ifdef _PC_SYMLINK_MAX
9577 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9578#endif
9579#ifdef _PC_XATTR_ENABLED
9580 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9581#endif
9582#ifdef _PC_XATTR_EXISTS
9583 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9584#endif
9585#ifdef _PC_TIMESTAMP_RESOLUTION
9586 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9587#endif
Fred Drakec9680921999-12-13 16:37:25 +00009588};
9589
Fred Drakec9680921999-12-13 16:37:25 +00009590static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009591conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009592{
9593 return conv_confname(arg, valuep, posix_constants_pathconf,
9594 sizeof(posix_constants_pathconf)
9595 / sizeof(struct constdef));
9596}
9597#endif
9598
Larry Hastings2f936352014-08-05 14:04:04 +10009599
Fred Drakec9680921999-12-13 16:37:25 +00009600#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009601/*[clinic input]
9602os.fpathconf -> long
9603
9604 fd: int
9605 name: path_confname
9606 /
9607
9608Return the configuration limit name for the file descriptor fd.
9609
9610If there is no limit, return -1.
9611[clinic start generated code]*/
9612
Larry Hastings2f936352014-08-05 14:04:04 +10009613static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009614os_fpathconf_impl(PyObject *module, int fd, int name)
9615/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009616{
9617 long limit;
9618
9619 errno = 0;
9620 limit = fpathconf(fd, name);
9621 if (limit == -1 && errno != 0)
9622 posix_error();
9623
9624 return limit;
9625}
9626#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009627
9628
9629#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009630/*[clinic input]
9631os.pathconf -> long
9632 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9633 name: path_confname
9634
9635Return the configuration limit name for the file or directory path.
9636
9637If there is no limit, return -1.
9638On some platforms, path may also be specified as an open file descriptor.
9639 If this functionality is unavailable, using it raises an exception.
9640[clinic start generated code]*/
9641
Larry Hastings2f936352014-08-05 14:04:04 +10009642static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009643os_pathconf_impl(PyObject *module, path_t *path, int name)
9644/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009645{
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009647
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009649#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009650 if (path->fd != -1)
9651 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009652 else
9653#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009654 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 if (limit == -1 && errno != 0) {
9656 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009657 /* could be a path or name problem */
9658 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009659 else
Larry Hastings2f936352014-08-05 14:04:04 +10009660 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 }
Larry Hastings2f936352014-08-05 14:04:04 +10009662
9663 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009664}
Larry Hastings2f936352014-08-05 14:04:04 +10009665#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009666
9667#ifdef HAVE_CONFSTR
9668static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009669#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009671#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009672#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009674#endif
9675#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009677#endif
Fred Draked86ed291999-12-15 15:34:33 +00009678#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009680#endif
9681#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009683#endif
9684#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009686#endif
9687#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009689#endif
Fred Drakec9680921999-12-13 16:37:25 +00009690#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009692#endif
9693#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
9696#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009698#endif
9699#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
9702#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
9708#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
Fred Draked86ed291999-12-15 15:34:33 +00009714#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
Fred Drakec9680921999-12-13 16:37:25 +00009717#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
Fred Draked86ed291999-12-15 15:34:33 +00009720#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009722#endif
9723#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009725#endif
9726#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009728#endif
9729#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009731#endif
Fred Drakec9680921999-12-13 16:37:25 +00009732#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
Fred Draked86ed291999-12-15 15:34:33 +00009780#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009782#endif
9783#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009785#endif
9786#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009788#endif
9789#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009791#endif
9792#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009794#endif
9795#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009797#endif
9798#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009800#endif
9801#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009803#endif
9804#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009806#endif
9807#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009809#endif
9810#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009812#endif
9813#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009815#endif
9816#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009818#endif
Fred Drakec9680921999-12-13 16:37:25 +00009819};
9820
9821static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009822conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009823{
9824 return conv_confname(arg, valuep, posix_constants_confstr,
9825 sizeof(posix_constants_confstr)
9826 / sizeof(struct constdef));
9827}
9828
Larry Hastings2f936352014-08-05 14:04:04 +10009829
9830/*[clinic input]
9831os.confstr
9832
9833 name: confstr_confname
9834 /
9835
9836Return a string-valued system configuration variable.
9837[clinic start generated code]*/
9838
Larry Hastings2f936352014-08-05 14:04:04 +10009839static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009840os_confstr_impl(PyObject *module, int name)
9841/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009842{
9843 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009844 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009845 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009846
Victor Stinnercb043522010-09-10 23:49:04 +00009847 errno = 0;
9848 len = confstr(name, buffer, sizeof(buffer));
9849 if (len == 0) {
9850 if (errno) {
9851 posix_error();
9852 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009853 }
9854 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009855 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009856 }
9857 }
Victor Stinnercb043522010-09-10 23:49:04 +00009858
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009859 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009860 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009861 char *buf = PyMem_Malloc(len);
9862 if (buf == NULL)
9863 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009864 len2 = confstr(name, buf, len);
9865 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009866 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009867 PyMem_Free(buf);
9868 }
9869 else
9870 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009871 return result;
9872}
Larry Hastings2f936352014-08-05 14:04:04 +10009873#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009874
9875
9876#ifdef HAVE_SYSCONF
9877static struct constdef posix_constants_sysconf[] = {
9878#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
Fred Draked86ed291999-12-15 15:34:33 +00009908#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009910#endif
9911#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009913#endif
Fred Drakec9680921999-12-13 16:37:25 +00009914#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
Fred Drakec9680921999-12-13 16:37:25 +00009917#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
Fred Draked86ed291999-12-15 15:34:33 +00009932#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009934#endif
Fred Drakec9680921999-12-13 16:37:25 +00009935#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
Fred Draked86ed291999-12-15 15:34:33 +00009950#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009952#endif
Fred Drakec9680921999-12-13 16:37:25 +00009953#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
Fred Draked86ed291999-12-15 15:34:33 +000010022#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010024#endif
Fred Drakec9680921999-12-13 16:37:25 +000010025#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
Fred Draked86ed291999-12-15 15:34:33 +000010034#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010036#endif
Fred Drakec9680921999-12-13 16:37:25 +000010037#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
Fred Draked86ed291999-12-15 15:34:33 +000010040#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010042#endif
10043#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010045#endif
Fred Drakec9680921999-12-13 16:37:25 +000010046#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
Fred Draked86ed291999-12-15 15:34:33 +000010058#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010060#endif
Fred Drakec9680921999-12-13 16:37:25 +000010061#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
Fred Draked86ed291999-12-15 15:34:33 +000010082#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010084#endif
Fred Drakec9680921999-12-13 16:37:25 +000010085#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
Fred Draked86ed291999-12-15 15:34:33 +000010091#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010093#endif
Fred Drakec9680921999-12-13 16:37:25 +000010094#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
Fred Draked86ed291999-12-15 15:34:33 +000010121#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010123#endif
10124#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010126#endif
Fred Drakec9680921999-12-13 16:37:25 +000010127#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
Fred Draked86ed291999-12-15 15:34:33 +000010232#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010234#endif
Fred Drakec9680921999-12-13 16:37:25 +000010235#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370};
10371
10372static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010373conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010374{
10375 return conv_confname(arg, valuep, posix_constants_sysconf,
10376 sizeof(posix_constants_sysconf)
10377 / sizeof(struct constdef));
10378}
10379
Larry Hastings2f936352014-08-05 14:04:04 +100010380
10381/*[clinic input]
10382os.sysconf -> long
10383 name: sysconf_confname
10384 /
10385
10386Return an integer-valued system configuration variable.
10387[clinic start generated code]*/
10388
Larry Hastings2f936352014-08-05 14:04:04 +100010389static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010390os_sysconf_impl(PyObject *module, int name)
10391/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010392{
10393 long value;
10394
10395 errno = 0;
10396 value = sysconf(name);
10397 if (value == -1 && errno != 0)
10398 posix_error();
10399 return value;
10400}
10401#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010402
10403
Fred Drakebec628d1999-12-15 18:31:10 +000010404/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010405 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010406 * the exported dictionaries that are used to publish information about the
10407 * names available on the host platform.
10408 *
10409 * Sorting the table at runtime ensures that the table is properly ordered
10410 * when used, even for platforms we're not able to test on. It also makes
10411 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010412 */
Fred Drakebec628d1999-12-15 18:31:10 +000010413
10414static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010415cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010416{
10417 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010419 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010421
10422 return strcmp(c1->name, c2->name);
10423}
10424
10425static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010426setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010427 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010428{
Fred Drakebec628d1999-12-15 18:31:10 +000010429 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010430 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010431
10432 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10433 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010434 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010436
Barry Warsaw3155db32000-04-13 15:20:40 +000010437 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 PyObject *o = PyLong_FromLong(table[i].value);
10439 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10440 Py_XDECREF(o);
10441 Py_DECREF(d);
10442 return -1;
10443 }
10444 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010445 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010446 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010447}
10448
Fred Drakebec628d1999-12-15 18:31:10 +000010449/* Return -1 on failure, 0 on success. */
10450static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010451setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010452{
10453#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010454 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010455 sizeof(posix_constants_pathconf)
10456 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010457 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010458 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010459#endif
10460#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010461 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010462 sizeof(posix_constants_confstr)
10463 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010464 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010465 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010466#endif
10467#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010468 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010469 sizeof(posix_constants_sysconf)
10470 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010471 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010472 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010473#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010474 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010475}
Fred Draked86ed291999-12-15 15:34:33 +000010476
10477
Larry Hastings2f936352014-08-05 14:04:04 +100010478/*[clinic input]
10479os.abort
10480
10481Abort the interpreter immediately.
10482
10483This function 'dumps core' or otherwise fails in the hardest way possible
10484on the hosting operating system. This function never returns.
10485[clinic start generated code]*/
10486
Larry Hastings2f936352014-08-05 14:04:04 +100010487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010488os_abort_impl(PyObject *module)
10489/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010490{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010491 abort();
10492 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010493#ifndef __clang__
10494 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10495 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10496 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010497 Py_FatalError("abort() called from Python code didn't abort!");
10498 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010499#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010500}
Fred Drakebec628d1999-12-15 18:31:10 +000010501
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010502#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010503/* Grab ShellExecute dynamically from shell32 */
10504static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010505static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10506 LPCWSTR, INT);
10507static int
10508check_ShellExecute()
10509{
10510 HINSTANCE hShell32;
10511
10512 /* only recheck */
10513 if (-1 == has_ShellExecute) {
10514 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010515 /* Security note: this call is not vulnerable to "DLL hijacking".
10516 SHELL32 is part of "KnownDLLs" and so Windows always load
10517 the system SHELL32.DLL, even if there is another SHELL32.DLL
10518 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010519 hShell32 = LoadLibraryW(L"SHELL32");
10520 Py_END_ALLOW_THREADS
10521 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010522 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10523 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010524 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010525 } else {
10526 has_ShellExecute = 0;
10527 }
10528 }
10529 return has_ShellExecute;
10530}
10531
10532
Steve Dowercc16be82016-09-08 10:35:16 -070010533/*[clinic input]
10534os.startfile
10535 filepath: path_t
10536 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010537
Steve Dowercc16be82016-09-08 10:35:16 -070010538startfile(filepath [, operation])
10539
10540Start a file with its associated application.
10541
10542When "operation" is not specified or "open", this acts like
10543double-clicking the file in Explorer, or giving the file name as an
10544argument to the DOS "start" command: the file is opened with whatever
10545application (if any) its extension is associated.
10546When another "operation" is given, it specifies what should be done with
10547the file. A typical operation is "print".
10548
10549startfile returns as soon as the associated application is launched.
10550There is no option to wait for the application to close, and no way
10551to retrieve the application's exit status.
10552
10553The filepath is relative to the current directory. If you want to use
10554an absolute path, make sure the first character is not a slash ("/");
10555the underlying Win32 ShellExecute function doesn't work if it is.
10556[clinic start generated code]*/
10557
10558static PyObject *
10559os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10560/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10561{
10562 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010563
10564 if(!check_ShellExecute()) {
10565 /* If the OS doesn't have ShellExecute, return a
10566 NotImplementedError. */
10567 return PyErr_Format(PyExc_NotImplementedError,
10568 "startfile not available on this platform");
10569 }
10570
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010572 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010573 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 Py_END_ALLOW_THREADS
10575
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010577 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010578 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 }
Steve Dowercc16be82016-09-08 10:35:16 -070010580 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010581}
Larry Hastings2f936352014-08-05 14:04:04 +100010582#endif /* MS_WINDOWS */
10583
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010584
Martin v. Löwis438b5342002-12-27 10:16:42 +000010585#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010586/*[clinic input]
10587os.getloadavg
10588
10589Return average recent system load information.
10590
10591Return the number of processes in the system run queue averaged over
10592the last 1, 5, and 15 minutes as a tuple of three floats.
10593Raises OSError if the load average was unobtainable.
10594[clinic start generated code]*/
10595
Larry Hastings2f936352014-08-05 14:04:04 +100010596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010597os_getloadavg_impl(PyObject *module)
10598/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010599{
10600 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010601 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010602 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10603 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010604 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010605 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010606}
Larry Hastings2f936352014-08-05 14:04:04 +100010607#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010608
Larry Hastings2f936352014-08-05 14:04:04 +100010609
10610/*[clinic input]
10611os.device_encoding
10612 fd: int
10613
10614Return a string describing the encoding of a terminal's file descriptor.
10615
10616The file descriptor must be attached to a terminal.
10617If the device is not a terminal, return None.
10618[clinic start generated code]*/
10619
Larry Hastings2f936352014-08-05 14:04:04 +100010620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010621os_device_encoding_impl(PyObject *module, int fd)
10622/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010623{
Brett Cannonefb00c02012-02-29 18:31:31 -050010624 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010625}
10626
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010627
Larry Hastings2f936352014-08-05 14:04:04 +100010628#ifdef HAVE_SETRESUID
10629/*[clinic input]
10630os.setresuid
10631
10632 ruid: uid_t
10633 euid: uid_t
10634 suid: uid_t
10635 /
10636
10637Set the current process's real, effective, and saved user ids.
10638[clinic start generated code]*/
10639
Larry Hastings2f936352014-08-05 14:04:04 +100010640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010641os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10642/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010643{
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 if (setresuid(ruid, euid, suid) < 0)
10645 return posix_error();
10646 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010647}
Larry Hastings2f936352014-08-05 14:04:04 +100010648#endif /* HAVE_SETRESUID */
10649
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010650
10651#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010652/*[clinic input]
10653os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010654
Larry Hastings2f936352014-08-05 14:04:04 +100010655 rgid: gid_t
10656 egid: gid_t
10657 sgid: gid_t
10658 /
10659
10660Set the current process's real, effective, and saved group ids.
10661[clinic start generated code]*/
10662
Larry Hastings2f936352014-08-05 14:04:04 +100010663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010664os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10665/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010666{
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 if (setresgid(rgid, egid, sgid) < 0)
10668 return posix_error();
10669 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010670}
Larry Hastings2f936352014-08-05 14:04:04 +100010671#endif /* HAVE_SETRESGID */
10672
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010673
10674#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010675/*[clinic input]
10676os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010677
Larry Hastings2f936352014-08-05 14:04:04 +100010678Return a tuple of the current process's real, effective, and saved user ids.
10679[clinic start generated code]*/
10680
Larry Hastings2f936352014-08-05 14:04:04 +100010681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010682os_getresuid_impl(PyObject *module)
10683/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010684{
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 if (getresuid(&ruid, &euid, &suid) < 0)
10687 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010688 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10689 _PyLong_FromUid(euid),
10690 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010691}
Larry Hastings2f936352014-08-05 14:04:04 +100010692#endif /* HAVE_GETRESUID */
10693
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010694
10695#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010696/*[clinic input]
10697os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010698
Larry Hastings2f936352014-08-05 14:04:04 +100010699Return a tuple of the current process's real, effective, and saved group ids.
10700[clinic start generated code]*/
10701
Larry Hastings2f936352014-08-05 14:04:04 +100010702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010703os_getresgid_impl(PyObject *module)
10704/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010705{
10706 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010707 if (getresgid(&rgid, &egid, &sgid) < 0)
10708 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010709 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10710 _PyLong_FromGid(egid),
10711 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010712}
Larry Hastings2f936352014-08-05 14:04:04 +100010713#endif /* HAVE_GETRESGID */
10714
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010715
Benjamin Peterson9428d532011-09-14 11:45:52 -040010716#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010717/*[clinic input]
10718os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010719
Larry Hastings2f936352014-08-05 14:04:04 +100010720 path: path_t(allow_fd=True)
10721 attribute: path_t
10722 *
10723 follow_symlinks: bool = True
10724
10725Return the value of extended attribute attribute on path.
10726
10727path may be either a string or an open file descriptor.
10728If follow_symlinks is False, and the last element of the path is a symbolic
10729 link, getxattr will examine the symbolic link itself instead of the file
10730 the link points to.
10731
10732[clinic start generated code]*/
10733
Larry Hastings2f936352014-08-05 14:04:04 +100010734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010735os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010736 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010737/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010738{
10739 Py_ssize_t i;
10740 PyObject *buffer = NULL;
10741
10742 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10743 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010744
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745 for (i = 0; ; i++) {
10746 void *ptr;
10747 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010748 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010749 Py_ssize_t buffer_size = buffer_sizes[i];
10750 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010751 path_error(path);
10752 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753 }
10754 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10755 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010756 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010757 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010758
Larry Hastings9cf065c2012-06-22 16:30:09 -070010759 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010760 if (path->fd >= 0)
10761 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010762 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010763 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010764 else
Larry Hastings2f936352014-08-05 14:04:04 +100010765 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010766 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010767
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 if (result < 0) {
10769 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010770 if (errno == ERANGE)
10771 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010772 path_error(path);
10773 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010775
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776 if (result != buffer_size) {
10777 /* Can only shrink. */
10778 _PyBytes_Resize(&buffer, result);
10779 }
10780 break;
10781 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010782
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010784}
10785
Larry Hastings2f936352014-08-05 14:04:04 +100010786
10787/*[clinic input]
10788os.setxattr
10789
10790 path: path_t(allow_fd=True)
10791 attribute: path_t
10792 value: Py_buffer
10793 flags: int = 0
10794 *
10795 follow_symlinks: bool = True
10796
10797Set extended attribute attribute on path to value.
10798
10799path may be either a string or an open file descriptor.
10800If follow_symlinks is False, and the last element of the path is a symbolic
10801 link, setxattr will modify the symbolic link itself instead of the file
10802 the link points to.
10803
10804[clinic start generated code]*/
10805
Benjamin Peterson799bd802011-08-31 22:15:17 -040010806static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010807os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010808 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010809/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010810{
Larry Hastings2f936352014-08-05 14:04:04 +100010811 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010812
Larry Hastings2f936352014-08-05 14:04:04 +100010813 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010814 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010815
Benjamin Peterson799bd802011-08-31 22:15:17 -040010816 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010817 if (path->fd > -1)
10818 result = fsetxattr(path->fd, attribute->narrow,
10819 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010821 result = setxattr(path->narrow, attribute->narrow,
10822 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010823 else
Larry Hastings2f936352014-08-05 14:04:04 +100010824 result = lsetxattr(path->narrow, attribute->narrow,
10825 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010826 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010827
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010829 path_error(path);
10830 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010831 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010832
Larry Hastings2f936352014-08-05 14:04:04 +100010833 Py_RETURN_NONE;
10834}
10835
10836
10837/*[clinic input]
10838os.removexattr
10839
10840 path: path_t(allow_fd=True)
10841 attribute: path_t
10842 *
10843 follow_symlinks: bool = True
10844
10845Remove extended attribute attribute on path.
10846
10847path may be either a string or an open file descriptor.
10848If follow_symlinks is False, and the last element of the path is a symbolic
10849 link, removexattr will modify the symbolic link itself instead of the file
10850 the link points to.
10851
10852[clinic start generated code]*/
10853
Larry Hastings2f936352014-08-05 14:04:04 +100010854static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010855os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010856 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010857/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010858{
10859 ssize_t result;
10860
10861 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10862 return NULL;
10863
10864 Py_BEGIN_ALLOW_THREADS;
10865 if (path->fd > -1)
10866 result = fremovexattr(path->fd, attribute->narrow);
10867 else if (follow_symlinks)
10868 result = removexattr(path->narrow, attribute->narrow);
10869 else
10870 result = lremovexattr(path->narrow, attribute->narrow);
10871 Py_END_ALLOW_THREADS;
10872
10873 if (result) {
10874 return path_error(path);
10875 }
10876
10877 Py_RETURN_NONE;
10878}
10879
10880
10881/*[clinic input]
10882os.listxattr
10883
10884 path: path_t(allow_fd=True, nullable=True) = None
10885 *
10886 follow_symlinks: bool = True
10887
10888Return a list of extended attributes on path.
10889
10890path may be either None, a string, or an open file descriptor.
10891if path is None, listxattr will examine the current directory.
10892If follow_symlinks is False, and the last element of the path is a symbolic
10893 link, listxattr will examine the symbolic link itself instead of the file
10894 the link points to.
10895[clinic start generated code]*/
10896
Larry Hastings2f936352014-08-05 14:04:04 +100010897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010898os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10899/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010900{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010901 Py_ssize_t i;
10902 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010903 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010904 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010905
Larry Hastings2f936352014-08-05 14:04:04 +100010906 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010907 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908
Larry Hastings2f936352014-08-05 14:04:04 +100010909 name = path->narrow ? path->narrow : ".";
10910
Larry Hastings9cf065c2012-06-22 16:30:09 -070010911 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010912 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010913 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010914 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010915 Py_ssize_t buffer_size = buffer_sizes[i];
10916 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010917 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010918 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010919 break;
10920 }
10921 buffer = PyMem_MALLOC(buffer_size);
10922 if (!buffer) {
10923 PyErr_NoMemory();
10924 break;
10925 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010926
Larry Hastings9cf065c2012-06-22 16:30:09 -070010927 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010928 if (path->fd > -1)
10929 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010930 else if (follow_symlinks)
10931 length = listxattr(name, buffer, buffer_size);
10932 else
10933 length = llistxattr(name, buffer, buffer_size);
10934 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010935
Larry Hastings9cf065c2012-06-22 16:30:09 -070010936 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010937 if (errno == ERANGE) {
10938 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010939 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010940 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010941 }
Larry Hastings2f936352014-08-05 14:04:04 +100010942 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010943 break;
10944 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010945
Larry Hastings9cf065c2012-06-22 16:30:09 -070010946 result = PyList_New(0);
10947 if (!result) {
10948 goto exit;
10949 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010950
Larry Hastings9cf065c2012-06-22 16:30:09 -070010951 end = buffer + length;
10952 for (trace = start = buffer; trace != end; trace++) {
10953 if (!*trace) {
10954 int error;
10955 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10956 trace - start);
10957 if (!attribute) {
10958 Py_DECREF(result);
10959 result = NULL;
10960 goto exit;
10961 }
10962 error = PyList_Append(result, attribute);
10963 Py_DECREF(attribute);
10964 if (error) {
10965 Py_DECREF(result);
10966 result = NULL;
10967 goto exit;
10968 }
10969 start = trace + 1;
10970 }
10971 }
10972 break;
10973 }
10974exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010975 if (buffer)
10976 PyMem_FREE(buffer);
10977 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010978}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010979#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010980
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010981
Larry Hastings2f936352014-08-05 14:04:04 +100010982/*[clinic input]
10983os.urandom
10984
10985 size: Py_ssize_t
10986 /
10987
10988Return a bytes object containing random bytes suitable for cryptographic use.
10989[clinic start generated code]*/
10990
Larry Hastings2f936352014-08-05 14:04:04 +100010991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010992os_urandom_impl(PyObject *module, Py_ssize_t size)
10993/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010994{
10995 PyObject *bytes;
10996 int result;
10997
Georg Brandl2fb477c2012-02-21 00:33:36 +010010998 if (size < 0)
10999 return PyErr_Format(PyExc_ValueError,
11000 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011001 bytes = PyBytes_FromStringAndSize(NULL, size);
11002 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011003 return NULL;
11004
Victor Stinnere66987e2016-09-06 16:33:52 -070011005 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011006 if (result == -1) {
11007 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011008 return NULL;
11009 }
Larry Hastings2f936352014-08-05 14:04:04 +100011010 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011011}
11012
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011013/* Terminal size querying */
11014
11015static PyTypeObject TerminalSizeType;
11016
11017PyDoc_STRVAR(TerminalSize_docstring,
11018 "A tuple of (columns, lines) for holding terminal window size");
11019
11020static PyStructSequence_Field TerminalSize_fields[] = {
11021 {"columns", "width of the terminal window in characters"},
11022 {"lines", "height of the terminal window in characters"},
11023 {NULL, NULL}
11024};
11025
11026static PyStructSequence_Desc TerminalSize_desc = {
11027 "os.terminal_size",
11028 TerminalSize_docstring,
11029 TerminalSize_fields,
11030 2,
11031};
11032
11033#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011034/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011035PyDoc_STRVAR(termsize__doc__,
11036 "Return the size of the terminal window as (columns, lines).\n" \
11037 "\n" \
11038 "The optional argument fd (default standard output) specifies\n" \
11039 "which file descriptor should be queried.\n" \
11040 "\n" \
11041 "If the file descriptor is not connected to a terminal, an OSError\n" \
11042 "is thrown.\n" \
11043 "\n" \
11044 "This function will only be defined if an implementation is\n" \
11045 "available for this system.\n" \
11046 "\n" \
11047 "shutil.get_terminal_size is the high-level function which should \n" \
11048 "normally be used, os.get_terminal_size is the low-level implementation.");
11049
11050static PyObject*
11051get_terminal_size(PyObject *self, PyObject *args)
11052{
11053 int columns, lines;
11054 PyObject *termsize;
11055
11056 int fd = fileno(stdout);
11057 /* Under some conditions stdout may not be connected and
11058 * fileno(stdout) may point to an invalid file descriptor. For example
11059 * GUI apps don't have valid standard streams by default.
11060 *
11061 * If this happens, and the optional fd argument is not present,
11062 * the ioctl below will fail returning EBADF. This is what we want.
11063 */
11064
11065 if (!PyArg_ParseTuple(args, "|i", &fd))
11066 return NULL;
11067
11068#ifdef TERMSIZE_USE_IOCTL
11069 {
11070 struct winsize w;
11071 if (ioctl(fd, TIOCGWINSZ, &w))
11072 return PyErr_SetFromErrno(PyExc_OSError);
11073 columns = w.ws_col;
11074 lines = w.ws_row;
11075 }
11076#endif /* TERMSIZE_USE_IOCTL */
11077
11078#ifdef TERMSIZE_USE_CONIO
11079 {
11080 DWORD nhandle;
11081 HANDLE handle;
11082 CONSOLE_SCREEN_BUFFER_INFO csbi;
11083 switch (fd) {
11084 case 0: nhandle = STD_INPUT_HANDLE;
11085 break;
11086 case 1: nhandle = STD_OUTPUT_HANDLE;
11087 break;
11088 case 2: nhandle = STD_ERROR_HANDLE;
11089 break;
11090 default:
11091 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11092 }
11093 handle = GetStdHandle(nhandle);
11094 if (handle == NULL)
11095 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11096 if (handle == INVALID_HANDLE_VALUE)
11097 return PyErr_SetFromWindowsErr(0);
11098
11099 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11100 return PyErr_SetFromWindowsErr(0);
11101
11102 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11103 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11104 }
11105#endif /* TERMSIZE_USE_CONIO */
11106
11107 termsize = PyStructSequence_New(&TerminalSizeType);
11108 if (termsize == NULL)
11109 return NULL;
11110 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11111 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11112 if (PyErr_Occurred()) {
11113 Py_DECREF(termsize);
11114 return NULL;
11115 }
11116 return termsize;
11117}
11118#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11119
Larry Hastings2f936352014-08-05 14:04:04 +100011120
11121/*[clinic input]
11122os.cpu_count
11123
Charles-François Natali80d62e62015-08-13 20:37:08 +010011124Return the number of CPUs in the system; return None if indeterminable.
11125
11126This number is not equivalent to the number of CPUs the current process can
11127use. The number of usable CPUs can be obtained with
11128``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011129[clinic start generated code]*/
11130
Larry Hastings2f936352014-08-05 14:04:04 +100011131static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011132os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011133/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011134{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011135 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011136#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011137 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11138 Need to fallback to Vista behavior if this call isn't present */
11139 HINSTANCE hKernel32;
11140 hKernel32 = GetModuleHandleW(L"KERNEL32");
11141
11142 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11143 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11144 "GetMaximumProcessorCount");
11145 if (_GetMaximumProcessorCount != NULL) {
11146 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11147 }
11148 else {
11149 SYSTEM_INFO sysinfo;
11150 GetSystemInfo(&sysinfo);
11151 ncpu = sysinfo.dwNumberOfProcessors;
11152 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011153#elif defined(__hpux)
11154 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11155#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11156 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011157#elif defined(__DragonFly__) || \
11158 defined(__OpenBSD__) || \
11159 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011160 defined(__NetBSD__) || \
11161 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011162 int mib[2];
11163 size_t len = sizeof(ncpu);
11164 mib[0] = CTL_HW;
11165 mib[1] = HW_NCPU;
11166 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11167 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011168#endif
11169 if (ncpu >= 1)
11170 return PyLong_FromLong(ncpu);
11171 else
11172 Py_RETURN_NONE;
11173}
11174
Victor Stinnerdaf45552013-08-28 00:53:59 +020011175
Larry Hastings2f936352014-08-05 14:04:04 +100011176/*[clinic input]
11177os.get_inheritable -> bool
11178
11179 fd: int
11180 /
11181
11182Get the close-on-exe flag of the specified file descriptor.
11183[clinic start generated code]*/
11184
Larry Hastings2f936352014-08-05 14:04:04 +100011185static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011186os_get_inheritable_impl(PyObject *module, int fd)
11187/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011188{
Steve Dower8fc89802015-04-12 00:26:27 -040011189 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011190 _Py_BEGIN_SUPPRESS_IPH
11191 return_value = _Py_get_inheritable(fd);
11192 _Py_END_SUPPRESS_IPH
11193 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011194}
11195
11196
11197/*[clinic input]
11198os.set_inheritable
11199 fd: int
11200 inheritable: int
11201 /
11202
11203Set the inheritable flag of the specified file descriptor.
11204[clinic start generated code]*/
11205
Larry Hastings2f936352014-08-05 14:04:04 +100011206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011207os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11208/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011209{
Steve Dower8fc89802015-04-12 00:26:27 -040011210 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011211
Steve Dower8fc89802015-04-12 00:26:27 -040011212 _Py_BEGIN_SUPPRESS_IPH
11213 result = _Py_set_inheritable(fd, inheritable, NULL);
11214 _Py_END_SUPPRESS_IPH
11215 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011216 return NULL;
11217 Py_RETURN_NONE;
11218}
11219
11220
11221#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011222/*[clinic input]
11223os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011224 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011225 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011226
Larry Hastings2f936352014-08-05 14:04:04 +100011227Get the close-on-exe flag of the specified file descriptor.
11228[clinic start generated code]*/
11229
Larry Hastings2f936352014-08-05 14:04:04 +100011230static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011231os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011232/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011233{
11234 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011235
11236 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11237 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011238 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011239 }
11240
Larry Hastings2f936352014-08-05 14:04:04 +100011241 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011242}
11243
Victor Stinnerdaf45552013-08-28 00:53:59 +020011244
Larry Hastings2f936352014-08-05 14:04:04 +100011245/*[clinic input]
11246os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011247 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011248 inheritable: bool
11249 /
11250
11251Set the inheritable flag of the specified handle.
11252[clinic start generated code]*/
11253
Larry Hastings2f936352014-08-05 14:04:04 +100011254static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011255os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011256 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011257/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011258{
11259 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011260 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11261 PyErr_SetFromWindowsErr(0);
11262 return NULL;
11263 }
11264 Py_RETURN_NONE;
11265}
Larry Hastings2f936352014-08-05 14:04:04 +100011266#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011267
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011268#ifndef MS_WINDOWS
11269PyDoc_STRVAR(get_blocking__doc__,
11270 "get_blocking(fd) -> bool\n" \
11271 "\n" \
11272 "Get the blocking mode of the file descriptor:\n" \
11273 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11274
11275static PyObject*
11276posix_get_blocking(PyObject *self, PyObject *args)
11277{
11278 int fd;
11279 int blocking;
11280
11281 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11282 return NULL;
11283
Steve Dower8fc89802015-04-12 00:26:27 -040011284 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011285 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011286 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011287 if (blocking < 0)
11288 return NULL;
11289 return PyBool_FromLong(blocking);
11290}
11291
11292PyDoc_STRVAR(set_blocking__doc__,
11293 "set_blocking(fd, blocking)\n" \
11294 "\n" \
11295 "Set the blocking mode of the specified file descriptor.\n" \
11296 "Set the O_NONBLOCK flag if blocking is False,\n" \
11297 "clear the O_NONBLOCK flag otherwise.");
11298
11299static PyObject*
11300posix_set_blocking(PyObject *self, PyObject *args)
11301{
Steve Dower8fc89802015-04-12 00:26:27 -040011302 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011303
11304 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11305 return NULL;
11306
Steve Dower8fc89802015-04-12 00:26:27 -040011307 _Py_BEGIN_SUPPRESS_IPH
11308 result = _Py_set_blocking(fd, blocking);
11309 _Py_END_SUPPRESS_IPH
11310 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011311 return NULL;
11312 Py_RETURN_NONE;
11313}
11314#endif /* !MS_WINDOWS */
11315
11316
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011317/*[clinic input]
11318class os.DirEntry "DirEntry *" "&DirEntryType"
11319[clinic start generated code]*/
11320/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011321
11322typedef struct {
11323 PyObject_HEAD
11324 PyObject *name;
11325 PyObject *path;
11326 PyObject *stat;
11327 PyObject *lstat;
11328#ifdef MS_WINDOWS
11329 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011330 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011331 int got_file_index;
11332#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011333#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011334 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011335#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011336 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011337 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011338#endif
11339} DirEntry;
11340
11341static void
11342DirEntry_dealloc(DirEntry *entry)
11343{
11344 Py_XDECREF(entry->name);
11345 Py_XDECREF(entry->path);
11346 Py_XDECREF(entry->stat);
11347 Py_XDECREF(entry->lstat);
11348 Py_TYPE(entry)->tp_free((PyObject *)entry);
11349}
11350
11351/* Forward reference */
11352static int
11353DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11354
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011355/*[clinic input]
11356os.DirEntry.is_symlink -> bool
11357
11358Return True if the entry is a symbolic link; cached per entry.
11359[clinic start generated code]*/
11360
Victor Stinner6036e442015-03-08 01:58:04 +010011361static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011362os_DirEntry_is_symlink_impl(DirEntry *self)
11363/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011364{
11365#ifdef MS_WINDOWS
11366 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011367#elif defined(HAVE_DIRENT_D_TYPE)
11368 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011369 if (self->d_type != DT_UNKNOWN)
11370 return self->d_type == DT_LNK;
11371 else
11372 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011373#else
11374 /* POSIX without d_type */
11375 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011376#endif
11377}
11378
11379static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011380DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11381{
11382 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011383 STRUCT_STAT st;
11384 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011385
11386#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011387 if (!PyUnicode_FSDecoder(self->path, &ub))
11388 return NULL;
11389 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011390#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011391 if (!PyUnicode_FSConverter(self->path, &ub))
11392 return NULL;
11393 const char *path = PyBytes_AS_STRING(ub);
11394 if (self->dir_fd != DEFAULT_DIR_FD) {
11395#ifdef HAVE_FSTATAT
11396 result = fstatat(self->dir_fd, path, &st,
11397 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11398#else
11399 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11400 return NULL;
11401#endif /* HAVE_FSTATAT */
11402 }
11403 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011404#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011405 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011406 if (follow_symlinks)
11407 result = STAT(path, &st);
11408 else
11409 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011410 }
11411 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011412
11413 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011414 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011415
11416 return _pystat_fromstructstat(&st);
11417}
11418
11419static PyObject *
11420DirEntry_get_lstat(DirEntry *self)
11421{
11422 if (!self->lstat) {
11423#ifdef MS_WINDOWS
11424 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11425#else /* POSIX */
11426 self->lstat = DirEntry_fetch_stat(self, 0);
11427#endif
11428 }
11429 Py_XINCREF(self->lstat);
11430 return self->lstat;
11431}
11432
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011433/*[clinic input]
11434os.DirEntry.stat
11435 *
11436 follow_symlinks: bool = True
11437
11438Return stat_result object for the entry; cached per entry.
11439[clinic start generated code]*/
11440
Victor Stinner6036e442015-03-08 01:58:04 +010011441static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011442os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11443/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011444{
11445 if (!follow_symlinks)
11446 return DirEntry_get_lstat(self);
11447
11448 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011449 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011450 if (result == -1)
11451 return NULL;
11452 else if (result)
11453 self->stat = DirEntry_fetch_stat(self, 1);
11454 else
11455 self->stat = DirEntry_get_lstat(self);
11456 }
11457
11458 Py_XINCREF(self->stat);
11459 return self->stat;
11460}
11461
Victor Stinner6036e442015-03-08 01:58:04 +010011462/* Set exception and return -1 on error, 0 for False, 1 for True */
11463static int
11464DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11465{
11466 PyObject *stat = NULL;
11467 PyObject *st_mode = NULL;
11468 long mode;
11469 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011470#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011471 int is_symlink;
11472 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011473#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011474#ifdef MS_WINDOWS
11475 unsigned long dir_bits;
11476#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011477 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011478
11479#ifdef MS_WINDOWS
11480 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11481 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011482#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011483 is_symlink = self->d_type == DT_LNK;
11484 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11485#endif
11486
Victor Stinner35a97c02015-03-08 02:59:09 +010011487#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011488 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011489#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011490 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011491 if (!stat) {
11492 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11493 /* If file doesn't exist (anymore), then return False
11494 (i.e., say it's not a file/directory) */
11495 PyErr_Clear();
11496 return 0;
11497 }
11498 goto error;
11499 }
11500 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11501 if (!st_mode)
11502 goto error;
11503
11504 mode = PyLong_AsLong(st_mode);
11505 if (mode == -1 && PyErr_Occurred())
11506 goto error;
11507 Py_CLEAR(st_mode);
11508 Py_CLEAR(stat);
11509 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011510#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011511 }
11512 else if (is_symlink) {
11513 assert(mode_bits != S_IFLNK);
11514 result = 0;
11515 }
11516 else {
11517 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11518#ifdef MS_WINDOWS
11519 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11520 if (mode_bits == S_IFDIR)
11521 result = dir_bits != 0;
11522 else
11523 result = dir_bits == 0;
11524#else /* POSIX */
11525 if (mode_bits == S_IFDIR)
11526 result = self->d_type == DT_DIR;
11527 else
11528 result = self->d_type == DT_REG;
11529#endif
11530 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011531#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011532
11533 return result;
11534
11535error:
11536 Py_XDECREF(st_mode);
11537 Py_XDECREF(stat);
11538 return -1;
11539}
11540
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011541/*[clinic input]
11542os.DirEntry.is_dir -> bool
11543 *
11544 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011545
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011546Return True if the entry is a directory; cached per entry.
11547[clinic start generated code]*/
11548
11549static int
11550os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11551/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11552{
11553 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011554}
11555
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011556/*[clinic input]
11557os.DirEntry.is_file -> bool
11558 *
11559 follow_symlinks: bool = True
11560
11561Return True if the entry is a file; cached per entry.
11562[clinic start generated code]*/
11563
11564static int
11565os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11566/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011567{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011568 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011569}
11570
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011571/*[clinic input]
11572os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011573
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011574Return inode of the entry; cached per entry.
11575[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011576
11577static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011578os_DirEntry_inode_impl(DirEntry *self)
11579/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011580{
11581#ifdef MS_WINDOWS
11582 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011583 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011584 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011585 STRUCT_STAT stat;
11586 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011587
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011588 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011589 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011590 path = PyUnicode_AsUnicode(unicode);
11591 result = LSTAT(path, &stat);
11592 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011593
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011594 if (result != 0)
11595 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011596
11597 self->win32_file_index = stat.st_ino;
11598 self->got_file_index = 1;
11599 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011600 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11601 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011602#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011603 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11604 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011605#endif
11606}
11607
11608static PyObject *
11609DirEntry_repr(DirEntry *self)
11610{
11611 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11612}
11613
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011614/*[clinic input]
11615os.DirEntry.__fspath__
11616
11617Returns the path for the entry.
11618[clinic start generated code]*/
11619
Brett Cannon96881cd2016-06-10 14:37:21 -070011620static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011621os_DirEntry___fspath___impl(DirEntry *self)
11622/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011623{
11624 Py_INCREF(self->path);
11625 return self->path;
11626}
11627
Victor Stinner6036e442015-03-08 01:58:04 +010011628static PyMemberDef DirEntry_members[] = {
11629 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11630 "the entry's base filename, relative to scandir() \"path\" argument"},
11631 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11632 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11633 {NULL}
11634};
11635
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011636#include "clinic/posixmodule.c.h"
11637
Victor Stinner6036e442015-03-08 01:58:04 +010011638static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011639 OS_DIRENTRY_IS_DIR_METHODDEF
11640 OS_DIRENTRY_IS_FILE_METHODDEF
11641 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11642 OS_DIRENTRY_STAT_METHODDEF
11643 OS_DIRENTRY_INODE_METHODDEF
11644 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011645 {NULL}
11646};
11647
Benjamin Peterson5646de42015-04-12 17:56:34 -040011648static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011649 PyVarObject_HEAD_INIT(NULL, 0)
11650 MODNAME ".DirEntry", /* tp_name */
11651 sizeof(DirEntry), /* tp_basicsize */
11652 0, /* tp_itemsize */
11653 /* methods */
11654 (destructor)DirEntry_dealloc, /* tp_dealloc */
11655 0, /* tp_print */
11656 0, /* tp_getattr */
11657 0, /* tp_setattr */
11658 0, /* tp_compare */
11659 (reprfunc)DirEntry_repr, /* tp_repr */
11660 0, /* tp_as_number */
11661 0, /* tp_as_sequence */
11662 0, /* tp_as_mapping */
11663 0, /* tp_hash */
11664 0, /* tp_call */
11665 0, /* tp_str */
11666 0, /* tp_getattro */
11667 0, /* tp_setattro */
11668 0, /* tp_as_buffer */
11669 Py_TPFLAGS_DEFAULT, /* tp_flags */
11670 0, /* tp_doc */
11671 0, /* tp_traverse */
11672 0, /* tp_clear */
11673 0, /* tp_richcompare */
11674 0, /* tp_weaklistoffset */
11675 0, /* tp_iter */
11676 0, /* tp_iternext */
11677 DirEntry_methods, /* tp_methods */
11678 DirEntry_members, /* tp_members */
11679};
11680
11681#ifdef MS_WINDOWS
11682
11683static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011684join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011685{
11686 Py_ssize_t path_len;
11687 Py_ssize_t size;
11688 wchar_t *result;
11689 wchar_t ch;
11690
11691 if (!path_wide) { /* Default arg: "." */
11692 path_wide = L".";
11693 path_len = 1;
11694 }
11695 else {
11696 path_len = wcslen(path_wide);
11697 }
11698
11699 /* The +1's are for the path separator and the NUL */
11700 size = path_len + 1 + wcslen(filename) + 1;
11701 result = PyMem_New(wchar_t, size);
11702 if (!result) {
11703 PyErr_NoMemory();
11704 return NULL;
11705 }
11706 wcscpy(result, path_wide);
11707 if (path_len > 0) {
11708 ch = result[path_len - 1];
11709 if (ch != SEP && ch != ALTSEP && ch != L':')
11710 result[path_len++] = SEP;
11711 wcscpy(result + path_len, filename);
11712 }
11713 return result;
11714}
11715
11716static PyObject *
11717DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11718{
11719 DirEntry *entry;
11720 BY_HANDLE_FILE_INFORMATION file_info;
11721 ULONG reparse_tag;
11722 wchar_t *joined_path;
11723
11724 entry = PyObject_New(DirEntry, &DirEntryType);
11725 if (!entry)
11726 return NULL;
11727 entry->name = NULL;
11728 entry->path = NULL;
11729 entry->stat = NULL;
11730 entry->lstat = NULL;
11731 entry->got_file_index = 0;
11732
11733 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11734 if (!entry->name)
11735 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011736 if (path->narrow) {
11737 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11738 if (!entry->name)
11739 goto error;
11740 }
Victor Stinner6036e442015-03-08 01:58:04 +010011741
11742 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11743 if (!joined_path)
11744 goto error;
11745
11746 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11747 PyMem_Free(joined_path);
11748 if (!entry->path)
11749 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011750 if (path->narrow) {
11751 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11752 if (!entry->path)
11753 goto error;
11754 }
Victor Stinner6036e442015-03-08 01:58:04 +010011755
Steve Dowercc16be82016-09-08 10:35:16 -070011756 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011757 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11758
11759 return (PyObject *)entry;
11760
11761error:
11762 Py_DECREF(entry);
11763 return NULL;
11764}
11765
11766#else /* POSIX */
11767
11768static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011769join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011770{
11771 Py_ssize_t path_len;
11772 Py_ssize_t size;
11773 char *result;
11774
11775 if (!path_narrow) { /* Default arg: "." */
11776 path_narrow = ".";
11777 path_len = 1;
11778 }
11779 else {
11780 path_len = strlen(path_narrow);
11781 }
11782
11783 if (filename_len == -1)
11784 filename_len = strlen(filename);
11785
11786 /* The +1's are for the path separator and the NUL */
11787 size = path_len + 1 + filename_len + 1;
11788 result = PyMem_New(char, size);
11789 if (!result) {
11790 PyErr_NoMemory();
11791 return NULL;
11792 }
11793 strcpy(result, path_narrow);
11794 if (path_len > 0 && result[path_len - 1] != '/')
11795 result[path_len++] = '/';
11796 strcpy(result + path_len, filename);
11797 return result;
11798}
11799
11800static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011801DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011802 ino_t d_ino
11803#ifdef HAVE_DIRENT_D_TYPE
11804 , unsigned char d_type
11805#endif
11806 )
Victor Stinner6036e442015-03-08 01:58:04 +010011807{
11808 DirEntry *entry;
11809 char *joined_path;
11810
11811 entry = PyObject_New(DirEntry, &DirEntryType);
11812 if (!entry)
11813 return NULL;
11814 entry->name = NULL;
11815 entry->path = NULL;
11816 entry->stat = NULL;
11817 entry->lstat = NULL;
11818
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011819 if (path->fd != -1) {
11820 entry->dir_fd = path->fd;
11821 joined_path = NULL;
11822 }
11823 else {
11824 entry->dir_fd = DEFAULT_DIR_FD;
11825 joined_path = join_path_filename(path->narrow, name, name_len);
11826 if (!joined_path)
11827 goto error;
11828 }
Victor Stinner6036e442015-03-08 01:58:04 +010011829
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030011830 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010011831 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011832 if (joined_path)
11833 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011834 }
11835 else {
11836 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011837 if (joined_path)
11838 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011839 }
11840 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011841 if (!entry->name)
11842 goto error;
11843
11844 if (path->fd != -1) {
11845 entry->path = entry->name;
11846 Py_INCREF(entry->path);
11847 }
11848 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011849 goto error;
11850
Victor Stinner35a97c02015-03-08 02:59:09 +010011851#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011852 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011853#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011854 entry->d_ino = d_ino;
11855
11856 return (PyObject *)entry;
11857
11858error:
11859 Py_XDECREF(entry);
11860 return NULL;
11861}
11862
11863#endif
11864
11865
11866typedef struct {
11867 PyObject_HEAD
11868 path_t path;
11869#ifdef MS_WINDOWS
11870 HANDLE handle;
11871 WIN32_FIND_DATAW file_data;
11872 int first_time;
11873#else /* POSIX */
11874 DIR *dirp;
11875#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011876#ifdef HAVE_FDOPENDIR
11877 int fd;
11878#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011879} ScandirIterator;
11880
11881#ifdef MS_WINDOWS
11882
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011883static int
11884ScandirIterator_is_closed(ScandirIterator *iterator)
11885{
11886 return iterator->handle == INVALID_HANDLE_VALUE;
11887}
11888
Victor Stinner6036e442015-03-08 01:58:04 +010011889static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011890ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011891{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011892 HANDLE handle = iterator->handle;
11893
11894 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011895 return;
11896
Victor Stinner6036e442015-03-08 01:58:04 +010011897 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011898 Py_BEGIN_ALLOW_THREADS
11899 FindClose(handle);
11900 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011901}
11902
11903static PyObject *
11904ScandirIterator_iternext(ScandirIterator *iterator)
11905{
11906 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11907 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011908 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011909
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011910 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011911 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011912 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011913
11914 while (1) {
11915 if (!iterator->first_time) {
11916 Py_BEGIN_ALLOW_THREADS
11917 success = FindNextFileW(iterator->handle, file_data);
11918 Py_END_ALLOW_THREADS
11919 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011920 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011921 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011922 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011923 break;
11924 }
11925 }
11926 iterator->first_time = 0;
11927
11928 /* Skip over . and .. */
11929 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011930 wcscmp(file_data->cFileName, L"..") != 0) {
11931 entry = DirEntry_from_find_data(&iterator->path, file_data);
11932 if (!entry)
11933 break;
11934 return entry;
11935 }
Victor Stinner6036e442015-03-08 01:58:04 +010011936
11937 /* Loop till we get a non-dot directory or finish iterating */
11938 }
11939
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011940 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011941 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011942 return NULL;
11943}
11944
11945#else /* POSIX */
11946
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011947static int
11948ScandirIterator_is_closed(ScandirIterator *iterator)
11949{
11950 return !iterator->dirp;
11951}
11952
Victor Stinner6036e442015-03-08 01:58:04 +010011953static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011954ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011955{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011956 DIR *dirp = iterator->dirp;
11957
11958 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011959 return;
11960
Victor Stinner6036e442015-03-08 01:58:04 +010011961 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011962 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011963#ifdef HAVE_FDOPENDIR
11964 if (iterator->path.fd != -1)
11965 rewinddir(dirp);
11966#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011967 closedir(dirp);
11968 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011969 return;
11970}
11971
11972static PyObject *
11973ScandirIterator_iternext(ScandirIterator *iterator)
11974{
11975 struct dirent *direntp;
11976 Py_ssize_t name_len;
11977 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011978 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011979
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011980 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011981 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011982 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011983
11984 while (1) {
11985 errno = 0;
11986 Py_BEGIN_ALLOW_THREADS
11987 direntp = readdir(iterator->dirp);
11988 Py_END_ALLOW_THREADS
11989
11990 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011991 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011992 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011993 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011994 break;
11995 }
11996
11997 /* Skip over . and .. */
11998 name_len = NAMLEN(direntp);
11999 is_dot = direntp->d_name[0] == '.' &&
12000 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12001 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012002 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012003 name_len, direntp->d_ino
12004#ifdef HAVE_DIRENT_D_TYPE
12005 , direntp->d_type
12006#endif
12007 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012008 if (!entry)
12009 break;
12010 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012011 }
12012
12013 /* Loop till we get a non-dot directory or finish iterating */
12014 }
12015
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012016 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012017 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012018 return NULL;
12019}
12020
12021#endif
12022
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012023static PyObject *
12024ScandirIterator_close(ScandirIterator *self, PyObject *args)
12025{
12026 ScandirIterator_closedir(self);
12027 Py_RETURN_NONE;
12028}
12029
12030static PyObject *
12031ScandirIterator_enter(PyObject *self, PyObject *args)
12032{
12033 Py_INCREF(self);
12034 return self;
12035}
12036
12037static PyObject *
12038ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12039{
12040 ScandirIterator_closedir(self);
12041 Py_RETURN_NONE;
12042}
12043
Victor Stinner6036e442015-03-08 01:58:04 +010012044static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012045ScandirIterator_finalize(ScandirIterator *iterator)
12046{
12047 PyObject *error_type, *error_value, *error_traceback;
12048
12049 /* Save the current exception, if any. */
12050 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12051
12052 if (!ScandirIterator_is_closed(iterator)) {
12053 ScandirIterator_closedir(iterator);
12054
12055 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12056 "unclosed scandir iterator %R", iterator)) {
12057 /* Spurious errors can appear at shutdown */
12058 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12059 PyErr_WriteUnraisable((PyObject *) iterator);
12060 }
12061 }
12062 }
12063
Victor Stinner7bfa4092016-03-23 00:43:54 +010012064 path_cleanup(&iterator->path);
12065
12066 /* Restore the saved exception. */
12067 PyErr_Restore(error_type, error_value, error_traceback);
12068}
12069
12070static void
Victor Stinner6036e442015-03-08 01:58:04 +010012071ScandirIterator_dealloc(ScandirIterator *iterator)
12072{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012073 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12074 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012075
Victor Stinner6036e442015-03-08 01:58:04 +010012076 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12077}
12078
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012079static PyMethodDef ScandirIterator_methods[] = {
12080 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12081 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12082 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12083 {NULL}
12084};
12085
Benjamin Peterson5646de42015-04-12 17:56:34 -040012086static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012087 PyVarObject_HEAD_INIT(NULL, 0)
12088 MODNAME ".ScandirIterator", /* tp_name */
12089 sizeof(ScandirIterator), /* tp_basicsize */
12090 0, /* tp_itemsize */
12091 /* methods */
12092 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12093 0, /* tp_print */
12094 0, /* tp_getattr */
12095 0, /* tp_setattr */
12096 0, /* tp_compare */
12097 0, /* tp_repr */
12098 0, /* tp_as_number */
12099 0, /* tp_as_sequence */
12100 0, /* tp_as_mapping */
12101 0, /* tp_hash */
12102 0, /* tp_call */
12103 0, /* tp_str */
12104 0, /* tp_getattro */
12105 0, /* tp_setattro */
12106 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012107 Py_TPFLAGS_DEFAULT
12108 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012109 0, /* tp_doc */
12110 0, /* tp_traverse */
12111 0, /* tp_clear */
12112 0, /* tp_richcompare */
12113 0, /* tp_weaklistoffset */
12114 PyObject_SelfIter, /* tp_iter */
12115 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012116 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012117 0, /* tp_members */
12118 0, /* tp_getset */
12119 0, /* tp_base */
12120 0, /* tp_dict */
12121 0, /* tp_descr_get */
12122 0, /* tp_descr_set */
12123 0, /* tp_dictoffset */
12124 0, /* tp_init */
12125 0, /* tp_alloc */
12126 0, /* tp_new */
12127 0, /* tp_free */
12128 0, /* tp_is_gc */
12129 0, /* tp_bases */
12130 0, /* tp_mro */
12131 0, /* tp_cache */
12132 0, /* tp_subclasses */
12133 0, /* tp_weaklist */
12134 0, /* tp_del */
12135 0, /* tp_version_tag */
12136 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012137};
12138
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012139/*[clinic input]
12140os.scandir
12141
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012142 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012143
12144Return an iterator of DirEntry objects for given path.
12145
12146path can be specified as either str, bytes or path-like object. If path
12147is bytes, the names of yielded DirEntry objects will also be bytes; in
12148all other circumstances they will be str.
12149
12150If path is None, uses the path='.'.
12151[clinic start generated code]*/
12152
Victor Stinner6036e442015-03-08 01:58:04 +010012153static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012154os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012155/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012156{
12157 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012158#ifdef MS_WINDOWS
12159 wchar_t *path_strW;
12160#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012161 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012162#ifdef HAVE_FDOPENDIR
12163 int fd = -1;
12164#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012165#endif
12166
12167 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12168 if (!iterator)
12169 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012170
12171#ifdef MS_WINDOWS
12172 iterator->handle = INVALID_HANDLE_VALUE;
12173#else
12174 iterator->dirp = NULL;
12175#endif
12176
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012177 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012178 /* Move the ownership to iterator->path */
12179 path->object = NULL;
12180 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012181
12182#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012183 iterator->first_time = 1;
12184
12185 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12186 if (!path_strW)
12187 goto error;
12188
12189 Py_BEGIN_ALLOW_THREADS
12190 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12191 Py_END_ALLOW_THREADS
12192
12193 PyMem_Free(path_strW);
12194
12195 if (iterator->handle == INVALID_HANDLE_VALUE) {
12196 path_error(&iterator->path);
12197 goto error;
12198 }
12199#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012200 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012201#ifdef HAVE_FDOPENDIR
12202 if (path->fd != -1) {
12203 /* closedir() closes the FD, so we duplicate it */
12204 fd = _Py_dup(path->fd);
12205 if (fd == -1)
12206 goto error;
12207
12208 Py_BEGIN_ALLOW_THREADS
12209 iterator->dirp = fdopendir(fd);
12210 Py_END_ALLOW_THREADS
12211 }
12212 else
12213#endif
12214 {
12215 if (iterator->path.narrow)
12216 path_str = iterator->path.narrow;
12217 else
12218 path_str = ".";
12219
12220 Py_BEGIN_ALLOW_THREADS
12221 iterator->dirp = opendir(path_str);
12222 Py_END_ALLOW_THREADS
12223 }
Victor Stinner6036e442015-03-08 01:58:04 +010012224
12225 if (!iterator->dirp) {
12226 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012227#ifdef HAVE_FDOPENDIR
12228 if (fd != -1) {
12229 Py_BEGIN_ALLOW_THREADS
12230 close(fd);
12231 Py_END_ALLOW_THREADS
12232 }
12233#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012234 goto error;
12235 }
12236#endif
12237
12238 return (PyObject *)iterator;
12239
12240error:
12241 Py_DECREF(iterator);
12242 return NULL;
12243}
12244
Ethan Furman410ef8e2016-06-04 12:06:26 -070012245/*
12246 Return the file system path representation of the object.
12247
12248 If the object is str or bytes, then allow it to pass through with
12249 an incremented refcount. If the object defines __fspath__(), then
12250 return the result of that method. All other types raise a TypeError.
12251*/
12252PyObject *
12253PyOS_FSPath(PyObject *path)
12254{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012255 /* For error message reasons, this function is manually inlined in
12256 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012257 _Py_IDENTIFIER(__fspath__);
12258 PyObject *func = NULL;
12259 PyObject *path_repr = NULL;
12260
12261 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12262 Py_INCREF(path);
12263 return path;
12264 }
12265
12266 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12267 if (NULL == func) {
12268 return PyErr_Format(PyExc_TypeError,
12269 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012270 "not %.200s",
12271 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012272 }
12273
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012274 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012275 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012276 if (NULL == path_repr) {
12277 return NULL;
12278 }
12279
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012280 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12281 PyErr_Format(PyExc_TypeError,
12282 "expected %.200s.__fspath__() to return str or bytes, "
12283 "not %.200s", Py_TYPE(path)->tp_name,
12284 Py_TYPE(path_repr)->tp_name);
12285 Py_DECREF(path_repr);
12286 return NULL;
12287 }
12288
Ethan Furman410ef8e2016-06-04 12:06:26 -070012289 return path_repr;
12290}
12291
12292/*[clinic input]
12293os.fspath
12294
12295 path: object
12296
12297Return the file system path representation of the object.
12298
Brett Cannonb4f43e92016-06-09 14:32:08 -070012299If the object is str or bytes, then allow it to pass through as-is. If the
12300object defines __fspath__(), then return the result of that method. All other
12301types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012302[clinic start generated code]*/
12303
12304static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012305os_fspath_impl(PyObject *module, PyObject *path)
12306/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012307{
12308 return PyOS_FSPath(path);
12309}
Victor Stinner6036e442015-03-08 01:58:04 +010012310
Victor Stinner9b1f4742016-09-06 16:18:52 -070012311#ifdef HAVE_GETRANDOM_SYSCALL
12312/*[clinic input]
12313os.getrandom
12314
12315 size: Py_ssize_t
12316 flags: int=0
12317
12318Obtain a series of random bytes.
12319[clinic start generated code]*/
12320
12321static PyObject *
12322os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12323/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12324{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012325 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012326 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012327
12328 if (size < 0) {
12329 errno = EINVAL;
12330 return posix_error();
12331 }
12332
Victor Stinnerec2319c2016-09-20 23:00:59 +020012333 bytes = PyBytes_FromStringAndSize(NULL, size);
12334 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012335 PyErr_NoMemory();
12336 return NULL;
12337 }
12338
12339 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012340 n = syscall(SYS_getrandom,
12341 PyBytes_AS_STRING(bytes),
12342 PyBytes_GET_SIZE(bytes),
12343 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012344 if (n < 0 && errno == EINTR) {
12345 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012346 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012347 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012348
12349 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012350 continue;
12351 }
12352 break;
12353 }
12354
12355 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012356 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012357 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012358 }
12359
Victor Stinnerec2319c2016-09-20 23:00:59 +020012360 if (n != size) {
12361 _PyBytes_Resize(&bytes, n);
12362 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012363
12364 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012365
12366error:
12367 Py_DECREF(bytes);
12368 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012369}
12370#endif /* HAVE_GETRANDOM_SYSCALL */
12371
Larry Hastings31826802013-10-19 00:09:25 -070012372
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012373static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012374
12375 OS_STAT_METHODDEF
12376 OS_ACCESS_METHODDEF
12377 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012378 OS_CHDIR_METHODDEF
12379 OS_CHFLAGS_METHODDEF
12380 OS_CHMOD_METHODDEF
12381 OS_FCHMOD_METHODDEF
12382 OS_LCHMOD_METHODDEF
12383 OS_CHOWN_METHODDEF
12384 OS_FCHOWN_METHODDEF
12385 OS_LCHOWN_METHODDEF
12386 OS_LCHFLAGS_METHODDEF
12387 OS_CHROOT_METHODDEF
12388 OS_CTERMID_METHODDEF
12389 OS_GETCWD_METHODDEF
12390 OS_GETCWDB_METHODDEF
12391 OS_LINK_METHODDEF
12392 OS_LISTDIR_METHODDEF
12393 OS_LSTAT_METHODDEF
12394 OS_MKDIR_METHODDEF
12395 OS_NICE_METHODDEF
12396 OS_GETPRIORITY_METHODDEF
12397 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012398#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012399 {"readlink", (PyCFunction)posix_readlink,
12400 METH_VARARGS | METH_KEYWORDS,
12401 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012402#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012403#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012404 {"readlink", (PyCFunction)win_readlink,
12405 METH_VARARGS | METH_KEYWORDS,
12406 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012407#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012408 OS_RENAME_METHODDEF
12409 OS_REPLACE_METHODDEF
12410 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012411 OS_SYMLINK_METHODDEF
12412 OS_SYSTEM_METHODDEF
12413 OS_UMASK_METHODDEF
12414 OS_UNAME_METHODDEF
12415 OS_UNLINK_METHODDEF
12416 OS_REMOVE_METHODDEF
12417 OS_UTIME_METHODDEF
12418 OS_TIMES_METHODDEF
12419 OS__EXIT_METHODDEF
12420 OS_EXECV_METHODDEF
12421 OS_EXECVE_METHODDEF
12422 OS_SPAWNV_METHODDEF
12423 OS_SPAWNVE_METHODDEF
12424 OS_FORK1_METHODDEF
12425 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012426 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012427 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12428 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12429 OS_SCHED_GETPARAM_METHODDEF
12430 OS_SCHED_GETSCHEDULER_METHODDEF
12431 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12432 OS_SCHED_SETPARAM_METHODDEF
12433 OS_SCHED_SETSCHEDULER_METHODDEF
12434 OS_SCHED_YIELD_METHODDEF
12435 OS_SCHED_SETAFFINITY_METHODDEF
12436 OS_SCHED_GETAFFINITY_METHODDEF
12437 OS_OPENPTY_METHODDEF
12438 OS_FORKPTY_METHODDEF
12439 OS_GETEGID_METHODDEF
12440 OS_GETEUID_METHODDEF
12441 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012442#ifdef HAVE_GETGROUPLIST
12443 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12444#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012445 OS_GETGROUPS_METHODDEF
12446 OS_GETPID_METHODDEF
12447 OS_GETPGRP_METHODDEF
12448 OS_GETPPID_METHODDEF
12449 OS_GETUID_METHODDEF
12450 OS_GETLOGIN_METHODDEF
12451 OS_KILL_METHODDEF
12452 OS_KILLPG_METHODDEF
12453 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012454#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012455 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012456#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012457 OS_SETUID_METHODDEF
12458 OS_SETEUID_METHODDEF
12459 OS_SETREUID_METHODDEF
12460 OS_SETGID_METHODDEF
12461 OS_SETEGID_METHODDEF
12462 OS_SETREGID_METHODDEF
12463 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012464#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012465 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012466#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012467 OS_GETPGID_METHODDEF
12468 OS_SETPGRP_METHODDEF
12469 OS_WAIT_METHODDEF
12470 OS_WAIT3_METHODDEF
12471 OS_WAIT4_METHODDEF
12472 OS_WAITID_METHODDEF
12473 OS_WAITPID_METHODDEF
12474 OS_GETSID_METHODDEF
12475 OS_SETSID_METHODDEF
12476 OS_SETPGID_METHODDEF
12477 OS_TCGETPGRP_METHODDEF
12478 OS_TCSETPGRP_METHODDEF
12479 OS_OPEN_METHODDEF
12480 OS_CLOSE_METHODDEF
12481 OS_CLOSERANGE_METHODDEF
12482 OS_DEVICE_ENCODING_METHODDEF
12483 OS_DUP_METHODDEF
12484 OS_DUP2_METHODDEF
12485 OS_LOCKF_METHODDEF
12486 OS_LSEEK_METHODDEF
12487 OS_READ_METHODDEF
12488 OS_READV_METHODDEF
12489 OS_PREAD_METHODDEF
12490 OS_WRITE_METHODDEF
12491 OS_WRITEV_METHODDEF
12492 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012493#ifdef HAVE_SENDFILE
12494 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12495 posix_sendfile__doc__},
12496#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012497 OS_FSTAT_METHODDEF
12498 OS_ISATTY_METHODDEF
12499 OS_PIPE_METHODDEF
12500 OS_PIPE2_METHODDEF
12501 OS_MKFIFO_METHODDEF
12502 OS_MKNOD_METHODDEF
12503 OS_MAJOR_METHODDEF
12504 OS_MINOR_METHODDEF
12505 OS_MAKEDEV_METHODDEF
12506 OS_FTRUNCATE_METHODDEF
12507 OS_TRUNCATE_METHODDEF
12508 OS_POSIX_FALLOCATE_METHODDEF
12509 OS_POSIX_FADVISE_METHODDEF
12510 OS_PUTENV_METHODDEF
12511 OS_UNSETENV_METHODDEF
12512 OS_STRERROR_METHODDEF
12513 OS_FCHDIR_METHODDEF
12514 OS_FSYNC_METHODDEF
12515 OS_SYNC_METHODDEF
12516 OS_FDATASYNC_METHODDEF
12517 OS_WCOREDUMP_METHODDEF
12518 OS_WIFCONTINUED_METHODDEF
12519 OS_WIFSTOPPED_METHODDEF
12520 OS_WIFSIGNALED_METHODDEF
12521 OS_WIFEXITED_METHODDEF
12522 OS_WEXITSTATUS_METHODDEF
12523 OS_WTERMSIG_METHODDEF
12524 OS_WSTOPSIG_METHODDEF
12525 OS_FSTATVFS_METHODDEF
12526 OS_STATVFS_METHODDEF
12527 OS_CONFSTR_METHODDEF
12528 OS_SYSCONF_METHODDEF
12529 OS_FPATHCONF_METHODDEF
12530 OS_PATHCONF_METHODDEF
12531 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012532 OS__GETFULLPATHNAME_METHODDEF
12533 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012534 OS__GETDISKUSAGE_METHODDEF
12535 OS__GETFINALPATHNAME_METHODDEF
12536 OS__GETVOLUMEPATHNAME_METHODDEF
12537 OS_GETLOADAVG_METHODDEF
12538 OS_URANDOM_METHODDEF
12539 OS_SETRESUID_METHODDEF
12540 OS_SETRESGID_METHODDEF
12541 OS_GETRESUID_METHODDEF
12542 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012543
Larry Hastings2f936352014-08-05 14:04:04 +100012544 OS_GETXATTR_METHODDEF
12545 OS_SETXATTR_METHODDEF
12546 OS_REMOVEXATTR_METHODDEF
12547 OS_LISTXATTR_METHODDEF
12548
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012549#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12550 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12551#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012552 OS_CPU_COUNT_METHODDEF
12553 OS_GET_INHERITABLE_METHODDEF
12554 OS_SET_INHERITABLE_METHODDEF
12555 OS_GET_HANDLE_INHERITABLE_METHODDEF
12556 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012557#ifndef MS_WINDOWS
12558 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12559 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12560#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012561 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012562 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012563 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012564 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012565};
12566
12567
Brian Curtin52173d42010-12-02 18:29:18 +000012568#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012569static int
Brian Curtin52173d42010-12-02 18:29:18 +000012570enable_symlink()
12571{
12572 HANDLE tok;
12573 TOKEN_PRIVILEGES tok_priv;
12574 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012575
12576 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012577 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012578
12579 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012580 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012581
12582 tok_priv.PrivilegeCount = 1;
12583 tok_priv.Privileges[0].Luid = luid;
12584 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12585
12586 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12587 sizeof(TOKEN_PRIVILEGES),
12588 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012589 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012590
Brian Curtin3b4499c2010-12-28 14:31:47 +000012591 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12592 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012593}
12594#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12595
Barry Warsaw4a342091996-12-19 23:50:02 +000012596static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012598{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012599#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012601#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012602#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012604#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012605#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012606 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012607#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012608#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012609 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012610#endif
Fred Drakec9680921999-12-13 16:37:25 +000012611#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012612 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012613#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012614#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012615 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012616#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012617#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012618 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012619#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012620#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012622#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012623#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012624 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012625#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012626#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012628#endif
12629#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012630 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012631#endif
12632#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012633 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012634#endif
12635#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012636 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012637#endif
12638#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012639 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012640#endif
12641#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012643#endif
12644#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012645 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012646#endif
12647#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012648 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012649#endif
12650#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012651 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012652#endif
12653#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012654 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012655#endif
12656#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012657 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012658#endif
12659#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012660 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012661#endif
12662#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012663 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012664#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012665#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012666 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012667#endif
12668#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012669 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012670#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012671#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012673#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012674#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012676#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012677#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012678#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012679 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012680#endif
12681#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012682 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012683#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012684#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012685#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012687#endif
12688#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012690#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012691#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012693#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012694#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012696#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012697#ifdef O_TMPFILE
12698 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12699#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012700#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012702#endif
12703#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012705#endif
12706#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012708#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012709#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012710 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012711#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012712#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012714#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012715
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012716
Jesus Cea94363612012-06-22 18:32:07 +020012717#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012718 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012719#endif
12720#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012721 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012722#endif
12723
Tim Peters5aa91602002-01-30 05:46:57 +000012724/* MS Windows */
12725#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012726 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012727 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012728#endif
12729#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012730 /* Optimize for short life (keep in memory). */
12731 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012733#endif
12734#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012735 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012736 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012737#endif
12738#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012739 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012741#endif
12742#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012743 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012745#endif
12746
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012747/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012748#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012749 /* Send a SIGIO signal whenever input or output
12750 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012751 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012752#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012753#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012754 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012755 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012756#endif
12757#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012758 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012760#endif
12761#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012762 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012764#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012765#ifdef O_NOLINKS
12766 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012768#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012769#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012770 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012772#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012773
Victor Stinner8c62be82010-05-06 00:08:46 +000012774 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012775#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012777#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012778#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012780#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012781#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012783#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012784#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012786#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012787#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012789#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012790#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012792#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012793#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012795#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012796#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012798#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012799#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012801#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012802#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012804#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012805#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012806 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012807#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012808#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012809 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012810#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012811#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012812 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012813#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012814#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012815 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012816#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012817#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012818 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012819#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012820#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012821 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012822#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012823#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012824 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012825#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012826
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012827 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012828#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012829 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012830#endif /* ST_RDONLY */
12831#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012832 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012833#endif /* ST_NOSUID */
12834
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012835 /* GNU extensions */
12836#ifdef ST_NODEV
12837 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12838#endif /* ST_NODEV */
12839#ifdef ST_NOEXEC
12840 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12841#endif /* ST_NOEXEC */
12842#ifdef ST_SYNCHRONOUS
12843 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12844#endif /* ST_SYNCHRONOUS */
12845#ifdef ST_MANDLOCK
12846 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12847#endif /* ST_MANDLOCK */
12848#ifdef ST_WRITE
12849 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12850#endif /* ST_WRITE */
12851#ifdef ST_APPEND
12852 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12853#endif /* ST_APPEND */
12854#ifdef ST_NOATIME
12855 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12856#endif /* ST_NOATIME */
12857#ifdef ST_NODIRATIME
12858 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12859#endif /* ST_NODIRATIME */
12860#ifdef ST_RELATIME
12861 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12862#endif /* ST_RELATIME */
12863
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012864 /* FreeBSD sendfile() constants */
12865#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012867#endif
12868#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012870#endif
12871#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012873#endif
12874
Ross Lagerwall7807c352011-03-17 20:20:30 +020012875 /* constants for posix_fadvise */
12876#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012877 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012878#endif
12879#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012880 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012881#endif
12882#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012883 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012884#endif
12885#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012886 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012887#endif
12888#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012889 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012890#endif
12891#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012892 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012893#endif
12894
12895 /* constants for waitid */
12896#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012897 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12898 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12899 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012900#endif
12901#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012903#endif
12904#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012906#endif
12907#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012909#endif
12910#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012911 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012912#endif
12913#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012915#endif
12916#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012917 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012918#endif
12919#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012920 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012921#endif
12922
12923 /* constants for lockf */
12924#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012925 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012926#endif
12927#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012928 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012929#endif
12930#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012931 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012932#endif
12933#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012934 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012935#endif
12936
Guido van Rossum246bc171999-02-01 23:54:31 +000012937#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012938 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12939 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12940 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12941 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12942 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012943#endif
12944
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012945#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012946#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012947 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012948#endif
12949#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012950 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012951#endif
12952#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012953 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012954#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012955#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080012956 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012957#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012958#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012959 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012960#endif
12961#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012962 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012963#endif
12964#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012965 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012966#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012967#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012968 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012969#endif
12970#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012971 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012972#endif
12973#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012974 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012975#endif
12976#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012977 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012978#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012979#endif
12980
Benjamin Peterson9428d532011-09-14 11:45:52 -040012981#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012982 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12983 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12984 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012985#endif
12986
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012987#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012988 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012989#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012990#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012991 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012992#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012993#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012994 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012995#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012996#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012997 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012998#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012999#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013000 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013001#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013002#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013003 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013004#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013005#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013007#endif
13008
Victor Stinner9b1f4742016-09-06 16:18:52 -070013009#ifdef HAVE_GETRANDOM_SYSCALL
13010 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13011 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13012#endif
13013
Victor Stinner8c62be82010-05-06 00:08:46 +000013014 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013015}
13016
13017
Martin v. Löwis1a214512008-06-11 05:26:20 +000013018static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013019 PyModuleDef_HEAD_INIT,
13020 MODNAME,
13021 posix__doc__,
13022 -1,
13023 posix_methods,
13024 NULL,
13025 NULL,
13026 NULL,
13027 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013028};
13029
13030
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013031static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013032
13033#ifdef HAVE_FACCESSAT
13034 "HAVE_FACCESSAT",
13035#endif
13036
13037#ifdef HAVE_FCHDIR
13038 "HAVE_FCHDIR",
13039#endif
13040
13041#ifdef HAVE_FCHMOD
13042 "HAVE_FCHMOD",
13043#endif
13044
13045#ifdef HAVE_FCHMODAT
13046 "HAVE_FCHMODAT",
13047#endif
13048
13049#ifdef HAVE_FCHOWN
13050 "HAVE_FCHOWN",
13051#endif
13052
Larry Hastings00964ed2013-08-12 13:49:30 -040013053#ifdef HAVE_FCHOWNAT
13054 "HAVE_FCHOWNAT",
13055#endif
13056
Larry Hastings9cf065c2012-06-22 16:30:09 -070013057#ifdef HAVE_FEXECVE
13058 "HAVE_FEXECVE",
13059#endif
13060
13061#ifdef HAVE_FDOPENDIR
13062 "HAVE_FDOPENDIR",
13063#endif
13064
Georg Brandl306336b2012-06-24 12:55:33 +020013065#ifdef HAVE_FPATHCONF
13066 "HAVE_FPATHCONF",
13067#endif
13068
Larry Hastings9cf065c2012-06-22 16:30:09 -070013069#ifdef HAVE_FSTATAT
13070 "HAVE_FSTATAT",
13071#endif
13072
13073#ifdef HAVE_FSTATVFS
13074 "HAVE_FSTATVFS",
13075#endif
13076
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013077#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013078 "HAVE_FTRUNCATE",
13079#endif
13080
Larry Hastings9cf065c2012-06-22 16:30:09 -070013081#ifdef HAVE_FUTIMENS
13082 "HAVE_FUTIMENS",
13083#endif
13084
13085#ifdef HAVE_FUTIMES
13086 "HAVE_FUTIMES",
13087#endif
13088
13089#ifdef HAVE_FUTIMESAT
13090 "HAVE_FUTIMESAT",
13091#endif
13092
13093#ifdef HAVE_LINKAT
13094 "HAVE_LINKAT",
13095#endif
13096
13097#ifdef HAVE_LCHFLAGS
13098 "HAVE_LCHFLAGS",
13099#endif
13100
13101#ifdef HAVE_LCHMOD
13102 "HAVE_LCHMOD",
13103#endif
13104
13105#ifdef HAVE_LCHOWN
13106 "HAVE_LCHOWN",
13107#endif
13108
13109#ifdef HAVE_LSTAT
13110 "HAVE_LSTAT",
13111#endif
13112
13113#ifdef HAVE_LUTIMES
13114 "HAVE_LUTIMES",
13115#endif
13116
13117#ifdef HAVE_MKDIRAT
13118 "HAVE_MKDIRAT",
13119#endif
13120
13121#ifdef HAVE_MKFIFOAT
13122 "HAVE_MKFIFOAT",
13123#endif
13124
13125#ifdef HAVE_MKNODAT
13126 "HAVE_MKNODAT",
13127#endif
13128
13129#ifdef HAVE_OPENAT
13130 "HAVE_OPENAT",
13131#endif
13132
13133#ifdef HAVE_READLINKAT
13134 "HAVE_READLINKAT",
13135#endif
13136
13137#ifdef HAVE_RENAMEAT
13138 "HAVE_RENAMEAT",
13139#endif
13140
13141#ifdef HAVE_SYMLINKAT
13142 "HAVE_SYMLINKAT",
13143#endif
13144
13145#ifdef HAVE_UNLINKAT
13146 "HAVE_UNLINKAT",
13147#endif
13148
13149#ifdef HAVE_UTIMENSAT
13150 "HAVE_UTIMENSAT",
13151#endif
13152
13153#ifdef MS_WINDOWS
13154 "MS_WINDOWS",
13155#endif
13156
13157 NULL
13158};
13159
13160
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013161PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013162INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013163{
Victor Stinner8c62be82010-05-06 00:08:46 +000013164 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013165 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013166 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013167
Brian Curtin52173d42010-12-02 18:29:18 +000013168#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013169 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013170#endif
13171
Victor Stinner8c62be82010-05-06 00:08:46 +000013172 m = PyModule_Create(&posixmodule);
13173 if (m == NULL)
13174 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013175
Victor Stinner8c62be82010-05-06 00:08:46 +000013176 /* Initialize environ dictionary */
13177 v = convertenviron();
13178 Py_XINCREF(v);
13179 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13180 return NULL;
13181 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013182
Victor Stinner8c62be82010-05-06 00:08:46 +000013183 if (all_ins(m))
13184 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013185
Victor Stinner8c62be82010-05-06 00:08:46 +000013186 if (setup_confname_tables(m))
13187 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013188
Victor Stinner8c62be82010-05-06 00:08:46 +000013189 Py_INCREF(PyExc_OSError);
13190 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013191
Guido van Rossumb3d39562000-01-31 18:41:26 +000013192#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013193 if (posix_putenv_garbage == NULL)
13194 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013195#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013196
Victor Stinner8c62be82010-05-06 00:08:46 +000013197 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013198#if defined(HAVE_WAITID) && !defined(__APPLE__)
13199 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013200 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13201 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013202#endif
13203
Christian Heimes25827622013-10-12 01:27:08 +020013204 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013205 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13206 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13207 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013208 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13209 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013210 structseq_new = StatResultType.tp_new;
13211 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013212
Christian Heimes25827622013-10-12 01:27:08 +020013213 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013214 if (PyStructSequence_InitType2(&StatVFSResultType,
13215 &statvfs_result_desc) < 0)
13216 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013217#ifdef NEED_TICKS_PER_SECOND
13218# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013219 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013220# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013221 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013222# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013223 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013224# endif
13225#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013226
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013227#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013228 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013229 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13230 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013231 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013232#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013233
13234 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013235 if (PyStructSequence_InitType2(&TerminalSizeType,
13236 &TerminalSize_desc) < 0)
13237 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013238
13239 /* initialize scandir types */
13240 if (PyType_Ready(&ScandirIteratorType) < 0)
13241 return NULL;
13242 if (PyType_Ready(&DirEntryType) < 0)
13243 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013244 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013245#if defined(HAVE_WAITID) && !defined(__APPLE__)
13246 Py_INCREF((PyObject*) &WaitidResultType);
13247 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13248#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013249 Py_INCREF((PyObject*) &StatResultType);
13250 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13251 Py_INCREF((PyObject*) &StatVFSResultType);
13252 PyModule_AddObject(m, "statvfs_result",
13253 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013254
13255#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013256 Py_INCREF(&SchedParamType);
13257 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013258#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013259
Larry Hastings605a62d2012-06-24 04:33:36 -070013260 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013261 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13262 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013263 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13264
13265 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013266 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13267 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013268 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13269
Thomas Wouters477c8d52006-05-27 19:21:47 +000013270#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013271 /*
13272 * Step 2 of weak-linking support on Mac OS X.
13273 *
13274 * The code below removes functions that are not available on the
13275 * currently active platform.
13276 *
13277 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013278 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013279 * OSX 10.4.
13280 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013281#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013282 if (fstatvfs == NULL) {
13283 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13284 return NULL;
13285 }
13286 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013287#endif /* HAVE_FSTATVFS */
13288
13289#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013290 if (statvfs == NULL) {
13291 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13292 return NULL;
13293 }
13294 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013295#endif /* HAVE_STATVFS */
13296
13297# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013298 if (lchown == NULL) {
13299 if (PyObject_DelAttrString(m, "lchown") == -1) {
13300 return NULL;
13301 }
13302 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013303#endif /* HAVE_LCHOWN */
13304
13305
13306#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013307
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013308 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013309 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13310
Larry Hastings6fe20b32012-04-19 15:07:49 -070013311 billion = PyLong_FromLong(1000000000);
13312 if (!billion)
13313 return NULL;
13314
Larry Hastings9cf065c2012-06-22 16:30:09 -070013315 /* suppress "function not used" warnings */
13316 {
13317 int ignored;
13318 fd_specified("", -1);
13319 follow_symlinks_specified("", 1);
13320 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13321 dir_fd_converter(Py_None, &ignored);
13322 dir_fd_unavailable(Py_None, &ignored);
13323 }
13324
13325 /*
13326 * provide list of locally available functions
13327 * so os.py can populate support_* lists
13328 */
13329 list = PyList_New(0);
13330 if (!list)
13331 return NULL;
13332 for (trace = have_functions; *trace; trace++) {
13333 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13334 if (!unicode)
13335 return NULL;
13336 if (PyList_Append(list, unicode))
13337 return NULL;
13338 Py_DECREF(unicode);
13339 }
13340 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013341
13342 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013343 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013344
13345 initialized = 1;
13346
Victor Stinner8c62be82010-05-06 00:08:46 +000013347 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013348}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013349
13350#ifdef __cplusplus
13351}
13352#endif