blob: 38b6c80e6bdd4235122d317c48c8a339f8dc99e5 [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",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001863 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001865};
1866
1867static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001868 "statvfs_result", /* name */
1869 statvfs_result__doc__, /* doc */
1870 statvfs_result_fields,
1871 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001872};
1873
Ross Lagerwall7807c352011-03-17 20:20:30 +02001874#if defined(HAVE_WAITID) && !defined(__APPLE__)
1875PyDoc_STRVAR(waitid_result__doc__,
1876"waitid_result: Result from waitid.\n\n\
1877This object may be accessed either as a tuple of\n\
1878 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1879or via the attributes si_pid, si_uid, and so on.\n\
1880\n\
1881See os.waitid for more information.");
1882
1883static PyStructSequence_Field waitid_result_fields[] = {
1884 {"si_pid", },
1885 {"si_uid", },
1886 {"si_signo", },
1887 {"si_status", },
1888 {"si_code", },
1889 {0}
1890};
1891
1892static PyStructSequence_Desc waitid_result_desc = {
1893 "waitid_result", /* name */
1894 waitid_result__doc__, /* doc */
1895 waitid_result_fields,
1896 5
1897};
1898static PyTypeObject WaitidResultType;
1899#endif
1900
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001901static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001902static PyTypeObject StatResultType;
1903static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001904#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001905static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001906#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001907static newfunc structseq_new;
1908
1909static PyObject *
1910statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1911{
Victor Stinner8c62be82010-05-06 00:08:46 +00001912 PyStructSequence *result;
1913 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001914
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 result = (PyStructSequence*)structseq_new(type, args, kwds);
1916 if (!result)
1917 return NULL;
1918 /* If we have been initialized from a tuple,
1919 st_?time might be set to None. Initialize it
1920 from the int slots. */
1921 for (i = 7; i <= 9; i++) {
1922 if (result->ob_item[i+3] == Py_None) {
1923 Py_DECREF(Py_None);
1924 Py_INCREF(result->ob_item[i]);
1925 result->ob_item[i+3] = result->ob_item[i];
1926 }
1927 }
1928 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001929}
1930
1931
Larry Hastings6fe20b32012-04-19 15:07:49 -07001932static PyObject *billion = NULL;
1933
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001934static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001935fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001936{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001937 PyObject *s = _PyLong_FromTime_t(sec);
1938 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1939 PyObject *s_in_ns = NULL;
1940 PyObject *ns_total = NULL;
1941 PyObject *float_s = NULL;
1942
1943 if (!(s && ns_fractional))
1944 goto exit;
1945
1946 s_in_ns = PyNumber_Multiply(s, billion);
1947 if (!s_in_ns)
1948 goto exit;
1949
1950 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1951 if (!ns_total)
1952 goto exit;
1953
Victor Stinner01b5aab2017-10-24 02:02:00 -07001954 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1955 if (!float_s) {
1956 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001957 }
1958
1959 PyStructSequence_SET_ITEM(v, index, s);
1960 PyStructSequence_SET_ITEM(v, index+3, float_s);
1961 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1962 s = NULL;
1963 float_s = NULL;
1964 ns_total = NULL;
1965exit:
1966 Py_XDECREF(s);
1967 Py_XDECREF(ns_fractional);
1968 Py_XDECREF(s_in_ns);
1969 Py_XDECREF(ns_total);
1970 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001971}
1972
Tim Peters5aa91602002-01-30 05:46:57 +00001973/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001974 (used by posix_stat() and posix_fstat()) */
1975static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001976_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001977{
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 unsigned long ansec, mnsec, cnsec;
1979 PyObject *v = PyStructSequence_New(&StatResultType);
1980 if (v == NULL)
1981 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001982
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01001984 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02001985 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001986#ifdef MS_WINDOWS
1987 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001988#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001989 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001990#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001992#if defined(MS_WINDOWS)
1993 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1994 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1995#else
1996 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1997 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1998#endif
xdegaye50e86032017-05-22 11:15:08 +02001999 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2000 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002001
Martin v. Löwis14694662006-02-03 12:54:16 +00002002#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002003 ansec = st->st_atim.tv_nsec;
2004 mnsec = st->st_mtim.tv_nsec;
2005 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002006#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002007 ansec = st->st_atimespec.tv_nsec;
2008 mnsec = st->st_mtimespec.tv_nsec;
2009 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002010#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 ansec = st->st_atime_nsec;
2012 mnsec = st->st_mtime_nsec;
2013 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002014#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002016#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002017 fill_time(v, 7, st->st_atime, ansec);
2018 fill_time(v, 8, st->st_mtime, mnsec);
2019 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002020
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002021#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2023 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002024#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002025#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2027 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002028#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002029#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2031 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002032#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002033#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2035 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002036#endif
2037#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002039 PyObject *val;
2040 unsigned long bsec,bnsec;
2041 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002042#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002043 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002044#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002045 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002046#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002047 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002048 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2049 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002051#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002052#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2054 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002055#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002056#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2057 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2058 PyLong_FromUnsignedLong(st->st_file_attributes));
2059#endif
Fred Drake699f3522000-06-29 21:12:41 +00002060
Victor Stinner8c62be82010-05-06 00:08:46 +00002061 if (PyErr_Occurred()) {
2062 Py_DECREF(v);
2063 return NULL;
2064 }
Fred Drake699f3522000-06-29 21:12:41 +00002065
Victor Stinner8c62be82010-05-06 00:08:46 +00002066 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002067}
2068
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002069/* POSIX methods */
2070
Guido van Rossum94f6f721999-01-06 18:42:14 +00002071
2072static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002073posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002074 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002075{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002076 STRUCT_STAT st;
2077 int result;
2078
2079#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2080 if (follow_symlinks_specified(function_name, follow_symlinks))
2081 return NULL;
2082#endif
2083
2084 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2085 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2086 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2087 return NULL;
2088
2089 Py_BEGIN_ALLOW_THREADS
2090 if (path->fd != -1)
2091 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002092#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002093 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002094 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002095 else
Steve Dowercc16be82016-09-08 10:35:16 -07002096 result = win32_lstat(path->wide, &st);
2097#else
2098 else
2099#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002100 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2101 result = LSTAT(path->narrow, &st);
2102 else
Steve Dowercc16be82016-09-08 10:35:16 -07002103#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002104#ifdef HAVE_FSTATAT
2105 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2106 result = fstatat(dir_fd, path->narrow, &st,
2107 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2108 else
Steve Dowercc16be82016-09-08 10:35:16 -07002109#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002110 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002111#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002112 Py_END_ALLOW_THREADS
2113
Victor Stinner292c8352012-10-30 02:17:38 +01002114 if (result != 0) {
2115 return path_error(path);
2116 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002117
2118 return _pystat_fromstructstat(&st);
2119}
2120
Larry Hastings2f936352014-08-05 14:04:04 +10002121/*[python input]
2122
2123for s in """
2124
2125FACCESSAT
2126FCHMODAT
2127FCHOWNAT
2128FSTATAT
2129LINKAT
2130MKDIRAT
2131MKFIFOAT
2132MKNODAT
2133OPENAT
2134READLINKAT
2135SYMLINKAT
2136UNLINKAT
2137
2138""".strip().split():
2139 s = s.strip()
2140 print("""
2141#ifdef HAVE_{s}
2142 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002143#else
Larry Hastings2f936352014-08-05 14:04:04 +10002144 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002145#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002146""".rstrip().format(s=s))
2147
2148for s in """
2149
2150FCHDIR
2151FCHMOD
2152FCHOWN
2153FDOPENDIR
2154FEXECVE
2155FPATHCONF
2156FSTATVFS
2157FTRUNCATE
2158
2159""".strip().split():
2160 s = s.strip()
2161 print("""
2162#ifdef HAVE_{s}
2163 #define PATH_HAVE_{s} 1
2164#else
2165 #define PATH_HAVE_{s} 0
2166#endif
2167
2168""".rstrip().format(s=s))
2169[python start generated code]*/
2170
2171#ifdef HAVE_FACCESSAT
2172 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2173#else
2174 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2175#endif
2176
2177#ifdef HAVE_FCHMODAT
2178 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2179#else
2180 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2181#endif
2182
2183#ifdef HAVE_FCHOWNAT
2184 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2185#else
2186 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2187#endif
2188
2189#ifdef HAVE_FSTATAT
2190 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2191#else
2192 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2193#endif
2194
2195#ifdef HAVE_LINKAT
2196 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2197#else
2198 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2199#endif
2200
2201#ifdef HAVE_MKDIRAT
2202 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2203#else
2204 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2205#endif
2206
2207#ifdef HAVE_MKFIFOAT
2208 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2209#else
2210 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2211#endif
2212
2213#ifdef HAVE_MKNODAT
2214 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2215#else
2216 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2217#endif
2218
2219#ifdef HAVE_OPENAT
2220 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2221#else
2222 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2223#endif
2224
2225#ifdef HAVE_READLINKAT
2226 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2227#else
2228 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2229#endif
2230
2231#ifdef HAVE_SYMLINKAT
2232 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2233#else
2234 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2235#endif
2236
2237#ifdef HAVE_UNLINKAT
2238 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2239#else
2240 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2241#endif
2242
2243#ifdef HAVE_FCHDIR
2244 #define PATH_HAVE_FCHDIR 1
2245#else
2246 #define PATH_HAVE_FCHDIR 0
2247#endif
2248
2249#ifdef HAVE_FCHMOD
2250 #define PATH_HAVE_FCHMOD 1
2251#else
2252 #define PATH_HAVE_FCHMOD 0
2253#endif
2254
2255#ifdef HAVE_FCHOWN
2256 #define PATH_HAVE_FCHOWN 1
2257#else
2258 #define PATH_HAVE_FCHOWN 0
2259#endif
2260
2261#ifdef HAVE_FDOPENDIR
2262 #define PATH_HAVE_FDOPENDIR 1
2263#else
2264 #define PATH_HAVE_FDOPENDIR 0
2265#endif
2266
2267#ifdef HAVE_FEXECVE
2268 #define PATH_HAVE_FEXECVE 1
2269#else
2270 #define PATH_HAVE_FEXECVE 0
2271#endif
2272
2273#ifdef HAVE_FPATHCONF
2274 #define PATH_HAVE_FPATHCONF 1
2275#else
2276 #define PATH_HAVE_FPATHCONF 0
2277#endif
2278
2279#ifdef HAVE_FSTATVFS
2280 #define PATH_HAVE_FSTATVFS 1
2281#else
2282 #define PATH_HAVE_FSTATVFS 0
2283#endif
2284
2285#ifdef HAVE_FTRUNCATE
2286 #define PATH_HAVE_FTRUNCATE 1
2287#else
2288 #define PATH_HAVE_FTRUNCATE 0
2289#endif
2290/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002291
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002292#ifdef MS_WINDOWS
2293 #undef PATH_HAVE_FTRUNCATE
2294 #define PATH_HAVE_FTRUNCATE 1
2295#endif
Larry Hastings31826802013-10-19 00:09:25 -07002296
Larry Hastings61272b72014-01-07 12:41:53 -08002297/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002298
2299class path_t_converter(CConverter):
2300
2301 type = "path_t"
2302 impl_by_reference = True
2303 parse_by_reference = True
2304
2305 converter = 'path_converter'
2306
2307 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002308 # right now path_t doesn't support default values.
2309 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002310 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002311 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002312
Larry Hastings2f936352014-08-05 14:04:04 +10002313 if self.c_default not in (None, 'Py_None'):
2314 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002315
2316 self.nullable = nullable
2317 self.allow_fd = allow_fd
2318
Larry Hastings7726ac92014-01-31 22:03:12 -08002319 def pre_render(self):
2320 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002321 if isinstance(value, str):
2322 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002323 return str(int(bool(value)))
2324
2325 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002326 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002327 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002328 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002329 strify(self.nullable),
2330 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002331 )
2332
2333 def cleanup(self):
2334 return "path_cleanup(&" + self.name + ");\n"
2335
2336
2337class dir_fd_converter(CConverter):
2338 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002339
Larry Hastings2f936352014-08-05 14:04:04 +10002340 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002341 if self.default in (unspecified, None):
2342 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002343 if isinstance(requires, str):
2344 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2345 else:
2346 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002347
Larry Hastings2f936352014-08-05 14:04:04 +10002348class fildes_converter(CConverter):
2349 type = 'int'
2350 converter = 'fildes_converter'
2351
2352class uid_t_converter(CConverter):
2353 type = "uid_t"
2354 converter = '_Py_Uid_Converter'
2355
2356class gid_t_converter(CConverter):
2357 type = "gid_t"
2358 converter = '_Py_Gid_Converter'
2359
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002360class dev_t_converter(CConverter):
2361 type = 'dev_t'
2362 converter = '_Py_Dev_Converter'
2363
2364class dev_t_return_converter(unsigned_long_return_converter):
2365 type = 'dev_t'
2366 conversion_fn = '_PyLong_FromDev'
2367 unsigned_cast = '(dev_t)'
2368
Larry Hastings2f936352014-08-05 14:04:04 +10002369class FSConverter_converter(CConverter):
2370 type = 'PyObject *'
2371 converter = 'PyUnicode_FSConverter'
2372 def converter_init(self):
2373 if self.default is not unspecified:
2374 fail("FSConverter_converter does not support default values")
2375 self.c_default = 'NULL'
2376
2377 def cleanup(self):
2378 return "Py_XDECREF(" + self.name + ");\n"
2379
2380class pid_t_converter(CConverter):
2381 type = 'pid_t'
2382 format_unit = '" _Py_PARSE_PID "'
2383
2384class idtype_t_converter(int_converter):
2385 type = 'idtype_t'
2386
2387class id_t_converter(CConverter):
2388 type = 'id_t'
2389 format_unit = '" _Py_PARSE_PID "'
2390
Benjamin Petersonca470632016-09-06 13:47:26 -07002391class intptr_t_converter(CConverter):
2392 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002393 format_unit = '" _Py_PARSE_INTPTR "'
2394
2395class Py_off_t_converter(CConverter):
2396 type = 'Py_off_t'
2397 converter = 'Py_off_t_converter'
2398
2399class Py_off_t_return_converter(long_return_converter):
2400 type = 'Py_off_t'
2401 conversion_fn = 'PyLong_FromPy_off_t'
2402
2403class path_confname_converter(CConverter):
2404 type="int"
2405 converter="conv_path_confname"
2406
2407class confstr_confname_converter(path_confname_converter):
2408 converter='conv_confstr_confname'
2409
2410class sysconf_confname_converter(path_confname_converter):
2411 converter="conv_sysconf_confname"
2412
2413class sched_param_converter(CConverter):
2414 type = 'struct sched_param'
2415 converter = 'convert_sched_param'
2416 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002417
Larry Hastings61272b72014-01-07 12:41:53 -08002418[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002419/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002420
Larry Hastings61272b72014-01-07 12:41:53 -08002421/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002422
Larry Hastings2a727912014-01-16 11:32:01 -08002423os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002424
2425 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002426 Path to be examined; can be string, bytes, path-like object or
2427 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002428
2429 *
2430
Larry Hastings2f936352014-08-05 14:04:04 +10002431 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002432 If not None, it should be a file descriptor open to a directory,
2433 and path should be a relative string; path will then be relative to
2434 that directory.
2435
2436 follow_symlinks: bool = True
2437 If False, and the last element of the path is a symbolic link,
2438 stat will examine the symbolic link itself instead of the file
2439 the link points to.
2440
2441Perform a stat system call on the given path.
2442
2443dir_fd and follow_symlinks may not be implemented
2444 on your platform. If they are unavailable, using them will raise a
2445 NotImplementedError.
2446
2447It's an error to use dir_fd or follow_symlinks when specifying path as
2448 an open file descriptor.
2449
Larry Hastings61272b72014-01-07 12:41:53 -08002450[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002451
Larry Hastings31826802013-10-19 00:09:25 -07002452static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002453os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002454/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002455{
2456 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2457}
2458
Larry Hastings2f936352014-08-05 14:04:04 +10002459
2460/*[clinic input]
2461os.lstat
2462
2463 path : path_t
2464
2465 *
2466
2467 dir_fd : dir_fd(requires='fstatat') = None
2468
2469Perform a stat system call on the given path, without following symbolic links.
2470
2471Like stat(), but do not follow symbolic links.
2472Equivalent to stat(path, follow_symlinks=False).
2473[clinic start generated code]*/
2474
Larry Hastings2f936352014-08-05 14:04:04 +10002475static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002476os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2477/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002478{
2479 int follow_symlinks = 0;
2480 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2481}
Larry Hastings31826802013-10-19 00:09:25 -07002482
Larry Hastings2f936352014-08-05 14:04:04 +10002483
Larry Hastings61272b72014-01-07 12:41:53 -08002484/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002485os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002486
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002487 path: path_t
2488 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002489
2490 mode: int
2491 Operating-system mode bitfield. Can be F_OK to test existence,
2492 or the inclusive-OR of R_OK, W_OK, and X_OK.
2493
2494 *
2495
Larry Hastings2f936352014-08-05 14:04:04 +10002496 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002497 If not None, it should be a file descriptor open to a directory,
2498 and path should be relative; path will then be relative to that
2499 directory.
2500
2501 effective_ids: bool = False
2502 If True, access will use the effective uid/gid instead of
2503 the real uid/gid.
2504
2505 follow_symlinks: bool = True
2506 If False, and the last element of the path is a symbolic link,
2507 access will examine the symbolic link itself instead of the file
2508 the link points to.
2509
2510Use the real uid/gid to test for access to a path.
2511
2512{parameters}
2513dir_fd, effective_ids, and follow_symlinks may not be implemented
2514 on your platform. If they are unavailable, using them will raise a
2515 NotImplementedError.
2516
2517Note that most operations will use the effective uid/gid, therefore this
2518 routine can be used in a suid/sgid environment to test if the invoking user
2519 has the specified access to the path.
2520
Larry Hastings61272b72014-01-07 12:41:53 -08002521[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002522
Larry Hastings2f936352014-08-05 14:04:04 +10002523static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002524os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002525 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002526/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002527{
Larry Hastings2f936352014-08-05 14:04:04 +10002528 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002529
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002530#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002531 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002532#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002534#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002535
Larry Hastings9cf065c2012-06-22 16:30:09 -07002536#ifndef HAVE_FACCESSAT
2537 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002538 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539
2540 if (effective_ids) {
2541 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002542 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002543 }
2544#endif
2545
2546#ifdef MS_WINDOWS
2547 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002548 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002549 Py_END_ALLOW_THREADS
2550
2551 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002552 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553 * * we didn't get a -1, and
2554 * * write access wasn't requested,
2555 * * or the file isn't read-only,
2556 * * or it's a directory.
2557 * (Directories cannot be read-only on Windows.)
2558 */
Larry Hastings2f936352014-08-05 14:04:04 +10002559 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002560 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002561 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002562 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002563#else
2564
2565 Py_BEGIN_ALLOW_THREADS
2566#ifdef HAVE_FACCESSAT
2567 if ((dir_fd != DEFAULT_DIR_FD) ||
2568 effective_ids ||
2569 !follow_symlinks) {
2570 int flags = 0;
2571 if (!follow_symlinks)
2572 flags |= AT_SYMLINK_NOFOLLOW;
2573 if (effective_ids)
2574 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002575 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576 }
2577 else
2578#endif
Larry Hastings31826802013-10-19 00:09:25 -07002579 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002580 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002581 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582#endif
2583
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002585}
2586
Guido van Rossumd371ff11999-01-25 16:12:23 +00002587#ifndef F_OK
2588#define F_OK 0
2589#endif
2590#ifndef R_OK
2591#define R_OK 4
2592#endif
2593#ifndef W_OK
2594#define W_OK 2
2595#endif
2596#ifndef X_OK
2597#define X_OK 1
2598#endif
2599
Larry Hastings31826802013-10-19 00:09:25 -07002600
Guido van Rossumd371ff11999-01-25 16:12:23 +00002601#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002602/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002603os.ttyname -> DecodeFSDefault
2604
2605 fd: int
2606 Integer file descriptor handle.
2607
2608 /
2609
2610Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002611[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002612
Larry Hastings31826802013-10-19 00:09:25 -07002613static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002614os_ttyname_impl(PyObject *module, int fd)
2615/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002616{
2617 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002618
Larry Hastings31826802013-10-19 00:09:25 -07002619 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002620 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002621 posix_error();
2622 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002623}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002624#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002625
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002626#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002627/*[clinic input]
2628os.ctermid
2629
2630Return the name of the controlling terminal for this process.
2631[clinic start generated code]*/
2632
Larry Hastings2f936352014-08-05 14:04:04 +10002633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002634os_ctermid_impl(PyObject *module)
2635/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002636{
Victor Stinner8c62be82010-05-06 00:08:46 +00002637 char *ret;
2638 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002639
Greg Wardb48bc172000-03-01 21:51:56 +00002640#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002641 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002642#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002643 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002644#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002645 if (ret == NULL)
2646 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002647 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002648}
Larry Hastings2f936352014-08-05 14:04:04 +10002649#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002650
Larry Hastings2f936352014-08-05 14:04:04 +10002651
2652/*[clinic input]
2653os.chdir
2654
2655 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2656
2657Change the current working directory to the specified path.
2658
2659path may always be specified as a string.
2660On some platforms, path may also be specified as an open file descriptor.
2661 If this functionality is unavailable, using it raises an exception.
2662[clinic start generated code]*/
2663
Larry Hastings2f936352014-08-05 14:04:04 +10002664static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002665os_chdir_impl(PyObject *module, path_t *path)
2666/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002667{
2668 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002669
2670 Py_BEGIN_ALLOW_THREADS
2671#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002672 /* on unix, success = 0, on windows, success = !0 */
2673 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674#else
2675#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002676 if (path->fd != -1)
2677 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002678 else
2679#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002680 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002681#endif
2682 Py_END_ALLOW_THREADS
2683
2684 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002685 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 }
2687
Larry Hastings2f936352014-08-05 14:04:04 +10002688 Py_RETURN_NONE;
2689}
2690
2691
2692#ifdef HAVE_FCHDIR
2693/*[clinic input]
2694os.fchdir
2695
2696 fd: fildes
2697
2698Change to the directory of the given file descriptor.
2699
2700fd must be opened on a directory, not a file.
2701Equivalent to os.chdir(fd).
2702
2703[clinic start generated code]*/
2704
Fred Drake4d1e64b2002-04-15 19:40:07 +00002705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002706os_fchdir_impl(PyObject *module, int fd)
2707/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002708{
Larry Hastings2f936352014-08-05 14:04:04 +10002709 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002710}
2711#endif /* HAVE_FCHDIR */
2712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002713
Larry Hastings2f936352014-08-05 14:04:04 +10002714/*[clinic input]
2715os.chmod
2716
2717 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2718 Path to be modified. May always be specified as a str or bytes.
2719 On some platforms, path may also be specified as an open file descriptor.
2720 If this functionality is unavailable, using it raises an exception.
2721
2722 mode: int
2723 Operating-system mode bitfield.
2724
2725 *
2726
2727 dir_fd : dir_fd(requires='fchmodat') = None
2728 If not None, it should be a file descriptor open to a directory,
2729 and path should be relative; path will then be relative to that
2730 directory.
2731
2732 follow_symlinks: bool = True
2733 If False, and the last element of the path is a symbolic link,
2734 chmod will modify the symbolic link itself instead of the file
2735 the link points to.
2736
2737Change the access permissions of a file.
2738
2739It is an error to use dir_fd or follow_symlinks when specifying path as
2740 an open file descriptor.
2741dir_fd and follow_symlinks may not be implemented on your platform.
2742 If they are unavailable, using them will raise a NotImplementedError.
2743
2744[clinic start generated code]*/
2745
Larry Hastings2f936352014-08-05 14:04:04 +10002746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002747os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002748 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002749/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002750{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002751 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002752
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002753#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002754 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002755#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002756
Larry Hastings9cf065c2012-06-22 16:30:09 -07002757#ifdef HAVE_FCHMODAT
2758 int fchmodat_nofollow_unsupported = 0;
2759#endif
2760
Larry Hastings9cf065c2012-06-22 16:30:09 -07002761#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2762 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002763 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002764#endif
2765
2766#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002767 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002768 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002769 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002770 result = 0;
2771 else {
2772 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002773 attr &= ~FILE_ATTRIBUTE_READONLY;
2774 else
2775 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002776 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002777 }
2778 Py_END_ALLOW_THREADS
2779
2780 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002781 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782 }
2783#else /* MS_WINDOWS */
2784 Py_BEGIN_ALLOW_THREADS
2785#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002786 if (path->fd != -1)
2787 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788 else
2789#endif
2790#ifdef HAVE_LCHMOD
2791 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002792 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 else
2794#endif
2795#ifdef HAVE_FCHMODAT
2796 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2797 /*
2798 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2799 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002800 * and then says it isn't implemented yet.
2801 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802 *
2803 * Once it is supported, os.chmod will automatically
2804 * support dir_fd and follow_symlinks=False. (Hopefully.)
2805 * Until then, we need to be careful what exception we raise.
2806 */
Larry Hastings2f936352014-08-05 14:04:04 +10002807 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2809 /*
2810 * But wait! We can't throw the exception without allowing threads,
2811 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2812 */
2813 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002814 result &&
2815 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2816 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002817 }
2818 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002819#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002820 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002821 Py_END_ALLOW_THREADS
2822
2823 if (result) {
2824#ifdef HAVE_FCHMODAT
2825 if (fchmodat_nofollow_unsupported) {
2826 if (dir_fd != DEFAULT_DIR_FD)
2827 dir_fd_and_follow_symlinks_invalid("chmod",
2828 dir_fd, follow_symlinks);
2829 else
2830 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002831 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832 }
2833 else
2834#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002835 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836 }
2837#endif
2838
Larry Hastings2f936352014-08-05 14:04:04 +10002839 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002840}
2841
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842
Christian Heimes4e30a842007-11-30 22:12:06 +00002843#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002844/*[clinic input]
2845os.fchmod
2846
2847 fd: int
2848 mode: int
2849
2850Change the access permissions of the file given by file descriptor fd.
2851
2852Equivalent to os.chmod(fd, mode).
2853[clinic start generated code]*/
2854
Larry Hastings2f936352014-08-05 14:04:04 +10002855static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002856os_fchmod_impl(PyObject *module, int fd, int mode)
2857/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002858{
2859 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002860 int async_err = 0;
2861
2862 do {
2863 Py_BEGIN_ALLOW_THREADS
2864 res = fchmod(fd, mode);
2865 Py_END_ALLOW_THREADS
2866 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2867 if (res != 0)
2868 return (!async_err) ? posix_error() : NULL;
2869
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002871}
2872#endif /* HAVE_FCHMOD */
2873
Larry Hastings2f936352014-08-05 14:04:04 +10002874
Christian Heimes4e30a842007-11-30 22:12:06 +00002875#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002876/*[clinic input]
2877os.lchmod
2878
2879 path: path_t
2880 mode: int
2881
2882Change the access permissions of a file, without following symbolic links.
2883
2884If path is a symlink, this affects the link itself rather than the target.
2885Equivalent to chmod(path, mode, follow_symlinks=False)."
2886[clinic start generated code]*/
2887
Larry Hastings2f936352014-08-05 14:04:04 +10002888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002889os_lchmod_impl(PyObject *module, path_t *path, int mode)
2890/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002891{
Victor Stinner8c62be82010-05-06 00:08:46 +00002892 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002894 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002895 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002896 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002897 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002898 return NULL;
2899 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002900 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002901}
2902#endif /* HAVE_LCHMOD */
2903
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002904
Thomas Wouterscf297e42007-02-23 15:07:44 +00002905#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002906/*[clinic input]
2907os.chflags
2908
2909 path: path_t
2910 flags: unsigned_long(bitwise=True)
2911 follow_symlinks: bool=True
2912
2913Set file flags.
2914
2915If follow_symlinks is False, and the last element of the path is a symbolic
2916 link, chflags will change flags on the symbolic link itself instead of the
2917 file the link points to.
2918follow_symlinks may not be implemented on your platform. If it is
2919unavailable, using it will raise a NotImplementedError.
2920
2921[clinic start generated code]*/
2922
Larry Hastings2f936352014-08-05 14:04:04 +10002923static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002924os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002925 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002926/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002927{
2928 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929
2930#ifndef HAVE_LCHFLAGS
2931 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002932 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002933#endif
2934
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002936#ifdef HAVE_LCHFLAGS
2937 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002938 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002939 else
2940#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002941 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002943
Larry Hastings2f936352014-08-05 14:04:04 +10002944 if (result)
2945 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002946
Larry Hastings2f936352014-08-05 14:04:04 +10002947 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002948}
2949#endif /* HAVE_CHFLAGS */
2950
Larry Hastings2f936352014-08-05 14:04:04 +10002951
Thomas Wouterscf297e42007-02-23 15:07:44 +00002952#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002953/*[clinic input]
2954os.lchflags
2955
2956 path: path_t
2957 flags: unsigned_long(bitwise=True)
2958
2959Set file flags.
2960
2961This function will not follow symbolic links.
2962Equivalent to chflags(path, flags, follow_symlinks=False).
2963[clinic start generated code]*/
2964
Larry Hastings2f936352014-08-05 14:04:04 +10002965static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002966os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2967/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002968{
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002971 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002972 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002973 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002974 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002975 }
Victor Stinner292c8352012-10-30 02:17:38 +01002976 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002977}
2978#endif /* HAVE_LCHFLAGS */
2979
Larry Hastings2f936352014-08-05 14:04:04 +10002980
Martin v. Löwis244edc82001-10-04 22:44:26 +00002981#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002982/*[clinic input]
2983os.chroot
2984 path: path_t
2985
2986Change root directory to path.
2987
2988[clinic start generated code]*/
2989
Larry Hastings2f936352014-08-05 14:04:04 +10002990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002991os_chroot_impl(PyObject *module, path_t *path)
2992/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002993{
2994 int res;
2995 Py_BEGIN_ALLOW_THREADS
2996 res = chroot(path->narrow);
2997 Py_END_ALLOW_THREADS
2998 if (res < 0)
2999 return path_error(path);
3000 Py_RETURN_NONE;
3001}
3002#endif /* HAVE_CHROOT */
3003
Martin v. Löwis244edc82001-10-04 22:44:26 +00003004
Guido van Rossum21142a01999-01-08 21:05:37 +00003005#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003006/*[clinic input]
3007os.fsync
3008
3009 fd: fildes
3010
3011Force write of fd to disk.
3012[clinic start generated code]*/
3013
Larry Hastings2f936352014-08-05 14:04:04 +10003014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003015os_fsync_impl(PyObject *module, int fd)
3016/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003017{
3018 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003019}
3020#endif /* HAVE_FSYNC */
3021
Larry Hastings2f936352014-08-05 14:04:04 +10003022
Ross Lagerwall7807c352011-03-17 20:20:30 +02003023#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003024/*[clinic input]
3025os.sync
3026
3027Force write of everything to disk.
3028[clinic start generated code]*/
3029
Larry Hastings2f936352014-08-05 14:04:04 +10003030static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003031os_sync_impl(PyObject *module)
3032/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003033{
3034 Py_BEGIN_ALLOW_THREADS
3035 sync();
3036 Py_END_ALLOW_THREADS
3037 Py_RETURN_NONE;
3038}
Larry Hastings2f936352014-08-05 14:04:04 +10003039#endif /* HAVE_SYNC */
3040
Ross Lagerwall7807c352011-03-17 20:20:30 +02003041
Guido van Rossum21142a01999-01-08 21:05:37 +00003042#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003043#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003044extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3045#endif
3046
Larry Hastings2f936352014-08-05 14:04:04 +10003047/*[clinic input]
3048os.fdatasync
3049
3050 fd: fildes
3051
3052Force write of fd to disk without forcing update of metadata.
3053[clinic start generated code]*/
3054
Larry Hastings2f936352014-08-05 14:04:04 +10003055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003056os_fdatasync_impl(PyObject *module, int fd)
3057/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003058{
3059 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003060}
3061#endif /* HAVE_FDATASYNC */
3062
3063
Fredrik Lundh10723342000-07-10 16:38:09 +00003064#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003065/*[clinic input]
3066os.chown
3067
3068 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3069 Path to be examined; can be string, bytes, or open-file-descriptor int.
3070
3071 uid: uid_t
3072
3073 gid: gid_t
3074
3075 *
3076
3077 dir_fd : dir_fd(requires='fchownat') = None
3078 If not None, it should be a file descriptor open to a directory,
3079 and path should be relative; path will then be relative to that
3080 directory.
3081
3082 follow_symlinks: bool = True
3083 If False, and the last element of the path is a symbolic link,
3084 stat will examine the symbolic link itself instead of the file
3085 the link points to.
3086
3087Change the owner and group id of path to the numeric uid and gid.\
3088
3089path may always be specified as a string.
3090On some platforms, path may also be specified as an open file descriptor.
3091 If this functionality is unavailable, using it raises an exception.
3092If dir_fd is not None, it should be a file descriptor open to a directory,
3093 and path should be relative; path will then be relative to that directory.
3094If follow_symlinks is False, and the last element of the path is a symbolic
3095 link, chown will modify the symbolic link itself instead of the file the
3096 link points to.
3097It is an error to use dir_fd or follow_symlinks when specifying path as
3098 an open file descriptor.
3099dir_fd and follow_symlinks may not be implemented on your platform.
3100 If they are unavailable, using them will raise a NotImplementedError.
3101
3102[clinic start generated code]*/
3103
Larry Hastings2f936352014-08-05 14:04:04 +10003104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003105os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003106 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003107/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003108{
3109 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110
3111#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3112 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003113 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003114#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003115 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3116 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3117 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003118
3119#ifdef __APPLE__
3120 /*
3121 * This is for Mac OS X 10.3, which doesn't have lchown.
3122 * (But we still have an lchown symbol because of weak-linking.)
3123 * It doesn't have fchownat either. So there's no possibility
3124 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003125 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003126 if ((!follow_symlinks) && (lchown == NULL)) {
3127 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003128 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003129 }
3130#endif
3131
Victor Stinner8c62be82010-05-06 00:08:46 +00003132 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003133#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003134 if (path->fd != -1)
3135 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003136 else
3137#endif
3138#ifdef HAVE_LCHOWN
3139 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003140 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141 else
3142#endif
3143#ifdef HAVE_FCHOWNAT
3144 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003145 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003146 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3147 else
3148#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003149 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003150 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003151
Larry Hastings2f936352014-08-05 14:04:04 +10003152 if (result)
3153 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003154
Larry Hastings2f936352014-08-05 14:04:04 +10003155 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003156}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003157#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003158
Larry Hastings2f936352014-08-05 14:04:04 +10003159
Christian Heimes4e30a842007-11-30 22:12:06 +00003160#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003161/*[clinic input]
3162os.fchown
3163
3164 fd: int
3165 uid: uid_t
3166 gid: gid_t
3167
3168Change the owner and group id of the file specified by file descriptor.
3169
3170Equivalent to os.chown(fd, uid, gid).
3171
3172[clinic start generated code]*/
3173
Larry Hastings2f936352014-08-05 14:04:04 +10003174static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003175os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3176/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003177{
Victor Stinner8c62be82010-05-06 00:08:46 +00003178 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003179 int async_err = 0;
3180
3181 do {
3182 Py_BEGIN_ALLOW_THREADS
3183 res = fchown(fd, uid, gid);
3184 Py_END_ALLOW_THREADS
3185 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3186 if (res != 0)
3187 return (!async_err) ? posix_error() : NULL;
3188
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003190}
3191#endif /* HAVE_FCHOWN */
3192
Larry Hastings2f936352014-08-05 14:04:04 +10003193
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003194#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003195/*[clinic input]
3196os.lchown
3197
3198 path : path_t
3199 uid: uid_t
3200 gid: gid_t
3201
3202Change the owner and group id of path to the numeric uid and gid.
3203
3204This function will not follow symbolic links.
3205Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3206[clinic start generated code]*/
3207
Larry Hastings2f936352014-08-05 14:04:04 +10003208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003209os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3210/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003211{
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003214 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003216 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003217 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003218 }
Larry Hastings2f936352014-08-05 14:04:04 +10003219 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003220}
3221#endif /* HAVE_LCHOWN */
3222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003223
Barry Warsaw53699e91996-12-10 23:23:01 +00003224static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003225posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003226{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003227 char *buf, *tmpbuf;
3228 char *cwd;
3229 const size_t chunk = 1024;
3230 size_t buflen = 0;
3231 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003232
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003233#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003235 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 wchar_t *wbuf2 = wbuf;
3237 PyObject *resobj;
3238 DWORD len;
3239 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003240 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 /* If the buffer is large enough, len does not include the
3242 terminating \0. If the buffer is too small, len includes
3243 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003244 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003245 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 if (wbuf2)
3247 len = GetCurrentDirectoryW(len, wbuf2);
3248 }
3249 Py_END_ALLOW_THREADS
3250 if (!wbuf2) {
3251 PyErr_NoMemory();
3252 return NULL;
3253 }
3254 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003255 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003256 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003257 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 }
3259 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003260 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003261 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003262 return resobj;
3263 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003264
3265 if (win32_warn_bytes_api())
3266 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003267#endif
3268
Victor Stinner4403d7d2015-04-25 00:16:10 +02003269 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003270 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003271 do {
3272 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003273#ifdef MS_WINDOWS
3274 if (buflen > INT_MAX) {
3275 PyErr_NoMemory();
3276 break;
3277 }
3278#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003279 tmpbuf = PyMem_RawRealloc(buf, buflen);
3280 if (tmpbuf == NULL)
3281 break;
3282
3283 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003284#ifdef MS_WINDOWS
3285 cwd = getcwd(buf, (int)buflen);
3286#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003287 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003288#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003289 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003291
3292 if (cwd == NULL) {
3293 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003295 }
3296
Victor Stinner8c62be82010-05-06 00:08:46 +00003297 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003298 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3299 else
3300 obj = PyUnicode_DecodeFSDefault(buf);
3301 PyMem_RawFree(buf);
3302
3303 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003304}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003305
Larry Hastings2f936352014-08-05 14:04:04 +10003306
3307/*[clinic input]
3308os.getcwd
3309
3310Return a unicode string representing the current working directory.
3311[clinic start generated code]*/
3312
Larry Hastings2f936352014-08-05 14:04:04 +10003313static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003314os_getcwd_impl(PyObject *module)
3315/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003316{
3317 return posix_getcwd(0);
3318}
3319
Larry Hastings2f936352014-08-05 14:04:04 +10003320
3321/*[clinic input]
3322os.getcwdb
3323
3324Return a bytes string representing the current working directory.
3325[clinic start generated code]*/
3326
Larry Hastings2f936352014-08-05 14:04:04 +10003327static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003328os_getcwdb_impl(PyObject *module)
3329/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003330{
3331 return posix_getcwd(1);
3332}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003333
Larry Hastings2f936352014-08-05 14:04:04 +10003334
Larry Hastings9cf065c2012-06-22 16:30:09 -07003335#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3336#define HAVE_LINK 1
3337#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003338
Guido van Rossumb6775db1994-08-01 11:34:53 +00003339#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003340/*[clinic input]
3341
3342os.link
3343
3344 src : path_t
3345 dst : path_t
3346 *
3347 src_dir_fd : dir_fd = None
3348 dst_dir_fd : dir_fd = None
3349 follow_symlinks: bool = True
3350
3351Create a hard link to a file.
3352
3353If either src_dir_fd or dst_dir_fd is not None, it should be a file
3354 descriptor open to a directory, and the respective path string (src or dst)
3355 should be relative; the path will then be relative to that directory.
3356If follow_symlinks is False, and the last element of src is a symbolic
3357 link, link will create a link to the symbolic link itself instead of the
3358 file the link points to.
3359src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3360 platform. If they are unavailable, using them will raise a
3361 NotImplementedError.
3362[clinic start generated code]*/
3363
Larry Hastings2f936352014-08-05 14:04:04 +10003364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003365os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003366 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003367/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003368{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003369#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003370 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371#else
3372 int result;
3373#endif
3374
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375#ifndef HAVE_LINKAT
3376 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3377 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003378 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379 }
3380#endif
3381
Steve Dowercc16be82016-09-08 10:35:16 -07003382#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003383 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384 PyErr_SetString(PyExc_NotImplementedError,
3385 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003386 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003387 }
Steve Dowercc16be82016-09-08 10:35:16 -07003388#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003389
Brian Curtin1b9df392010-11-24 20:24:31 +00003390#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003392 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003393 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003394
Larry Hastings2f936352014-08-05 14:04:04 +10003395 if (!result)
3396 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003397#else
3398 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003399#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3401 (dst_dir_fd != DEFAULT_DIR_FD) ||
3402 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003403 result = linkat(src_dir_fd, src->narrow,
3404 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003405 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3406 else
Steve Dowercc16be82016-09-08 10:35:16 -07003407#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003408 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003410
Larry Hastings2f936352014-08-05 14:04:04 +10003411 if (result)
3412 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003413#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414
Larry Hastings2f936352014-08-05 14:04:04 +10003415 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003416}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417#endif
3418
Brian Curtin1b9df392010-11-24 20:24:31 +00003419
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003420#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003421static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003422_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003423{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424 PyObject *v;
3425 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3426 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003427 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003429 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431
Steve Dowercc16be82016-09-08 10:35:16 -07003432 WIN32_FIND_DATAW wFileData;
3433 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003434
Steve Dowercc16be82016-09-08 10:35:16 -07003435 if (!path->wide) { /* Default arg: "." */
3436 po_wchars = L".";
3437 len = 1;
3438 } else {
3439 po_wchars = path->wide;
3440 len = wcslen(path->wide);
3441 }
3442 /* The +5 is so we can append "\\*.*\0" */
3443 wnamebuf = PyMem_New(wchar_t, len + 5);
3444 if (!wnamebuf) {
3445 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 }
Steve Dowercc16be82016-09-08 10:35:16 -07003448 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003449 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003450 wchar_t wch = wnamebuf[len-1];
3451 if (wch != SEP && wch != ALTSEP && wch != L':')
3452 wnamebuf[len++] = SEP;
3453 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 }
Steve Dowercc16be82016-09-08 10:35:16 -07003455 if ((list = PyList_New(0)) == NULL) {
3456 goto exit;
3457 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003458 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003459 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003460 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 if (hFindFile == INVALID_HANDLE_VALUE) {
3462 int error = GetLastError();
3463 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464 goto exit;
3465 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003466 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 }
3469 do {
3470 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003471 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3472 wcscmp(wFileData.cFileName, L"..") != 0) {
3473 v = PyUnicode_FromWideChar(wFileData.cFileName,
3474 wcslen(wFileData.cFileName));
3475 if (path->narrow && v) {
3476 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3477 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 Py_DECREF(list);
3480 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003481 break;
3482 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 Py_DECREF(list);
3486 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 break;
3488 }
3489 Py_DECREF(v);
3490 }
3491 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003492 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003493 Py_END_ALLOW_THREADS
3494 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3495 it got to the end of the directory. */
3496 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003498 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 }
3501 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003502
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503exit:
3504 if (hFindFile != INVALID_HANDLE_VALUE) {
3505 if (FindClose(hFindFile) == FALSE) {
3506 if (list != NULL) {
3507 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003508 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509 }
3510 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003512 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003513
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003515} /* end of _listdir_windows_no_opendir */
3516
3517#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3518
3519static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003520_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003521{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003522 PyObject *v;
3523 DIR *dirp = NULL;
3524 struct dirent *ep;
3525 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003526#ifdef HAVE_FDOPENDIR
3527 int fd = -1;
3528#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003529
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003532 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003534 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003535 if (fd == -1)
3536 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537
Larry Hastingsfdaea062012-06-25 04:42:23 -07003538 return_str = 1;
3539
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540 Py_BEGIN_ALLOW_THREADS
3541 dirp = fdopendir(fd);
3542 Py_END_ALLOW_THREADS
3543 }
3544 else
3545#endif
3546 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003547 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003548 if (path->narrow) {
3549 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003550 /* only return bytes if they specified a bytes-like object */
3551 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003552 }
3553 else {
3554 name = ".";
3555 return_str = 1;
3556 }
3557
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558 Py_BEGIN_ALLOW_THREADS
3559 dirp = opendir(name);
3560 Py_END_ALLOW_THREADS
3561 }
3562
3563 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003564 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003565#ifdef HAVE_FDOPENDIR
3566 if (fd != -1) {
3567 Py_BEGIN_ALLOW_THREADS
3568 close(fd);
3569 Py_END_ALLOW_THREADS
3570 }
3571#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 goto exit;
3573 }
3574 if ((list = PyList_New(0)) == NULL) {
3575 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 }
3577 for (;;) {
3578 errno = 0;
3579 Py_BEGIN_ALLOW_THREADS
3580 ep = readdir(dirp);
3581 Py_END_ALLOW_THREADS
3582 if (ep == NULL) {
3583 if (errno == 0) {
3584 break;
3585 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003586 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003587 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003588 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 }
3590 }
3591 if (ep->d_name[0] == '.' &&
3592 (NAMLEN(ep) == 1 ||
3593 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3594 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003595 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003596 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3597 else
3598 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 break;
3602 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 break;
3607 }
3608 Py_DECREF(v);
3609 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003610
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611exit:
3612 if (dirp != NULL) {
3613 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003614#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 if (fd > -1)
3616 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003617#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 closedir(dirp);
3619 Py_END_ALLOW_THREADS
3620 }
3621
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003623} /* end of _posix_listdir */
3624#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003625
Larry Hastings2f936352014-08-05 14:04:04 +10003626
3627/*[clinic input]
3628os.listdir
3629
3630 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3631
3632Return a list containing the names of the files in the directory.
3633
3634path can be specified as either str or bytes. If path is bytes,
3635 the filenames returned will also be bytes; in all other circumstances
3636 the filenames returned will be str.
3637If path is None, uses the path='.'.
3638On some platforms, path may also be specified as an open file descriptor;\
3639 the file descriptor must refer to a directory.
3640 If this functionality is unavailable, using it raises NotImplementedError.
3641
3642The list is in arbitrary order. It does not include the special
3643entries '.' and '..' even if they are present in the directory.
3644
3645
3646[clinic start generated code]*/
3647
Larry Hastings2f936352014-08-05 14:04:04 +10003648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003649os_listdir_impl(PyObject *module, path_t *path)
3650/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003651{
3652#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3653 return _listdir_windows_no_opendir(path, NULL);
3654#else
3655 return _posix_listdir(path, NULL);
3656#endif
3657}
3658
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003659#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003660/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003661/*[clinic input]
3662os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003663
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003664 path: path_t
3665 /
3666
3667[clinic start generated code]*/
3668
3669static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003670os__getfullpathname_impl(PyObject *module, path_t *path)
3671/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003672{
Steve Dowercc16be82016-09-08 10:35:16 -07003673 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3674 wchar_t *wtemp;
3675 DWORD result;
3676 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003677
Steve Dowercc16be82016-09-08 10:35:16 -07003678 result = GetFullPathNameW(path->wide,
3679 Py_ARRAY_LENGTH(woutbuf),
3680 woutbuf, &wtemp);
3681 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3682 woutbufp = PyMem_New(wchar_t, result);
3683 if (!woutbufp)
3684 return PyErr_NoMemory();
3685 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 }
Steve Dowercc16be82016-09-08 10:35:16 -07003687 if (result) {
3688 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3689 if (path->narrow)
3690 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3691 } else
3692 v = win32_error_object("GetFullPathNameW", path->object);
3693 if (woutbufp != woutbuf)
3694 PyMem_Free(woutbufp);
3695 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003696}
Brian Curtind40e6f72010-07-08 21:39:08 +00003697
Brian Curtind25aef52011-06-13 15:16:04 -05003698
Larry Hastings2f936352014-08-05 14:04:04 +10003699/*[clinic input]
3700os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003701
Larry Hastings2f936352014-08-05 14:04:04 +10003702 path: unicode
3703 /
3704
3705A helper function for samepath on windows.
3706[clinic start generated code]*/
3707
Larry Hastings2f936352014-08-05 14:04:04 +10003708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003709os__getfinalpathname_impl(PyObject *module, PyObject *path)
3710/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003711{
3712 HANDLE hFile;
3713 int buf_size;
3714 wchar_t *target_path;
3715 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003716 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003717 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003718
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03003719 path_wchar = _PyUnicode_AsUnicode(path);
Larry Hastings2f936352014-08-05 14:04:04 +10003720 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003721 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003722
Brian Curtind40e6f72010-07-08 21:39:08 +00003723 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003724 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003725 0, /* desired access */
3726 0, /* share mode */
3727 NULL, /* security attributes */
3728 OPEN_EXISTING,
3729 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3730 FILE_FLAG_BACKUP_SEMANTICS,
3731 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003732
Victor Stinnereb5657a2011-09-30 01:44:27 +02003733 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003734 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003735
3736 /* We have a good handle to the target, use it to determine the
3737 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003738 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003739
3740 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003741 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003742
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003743 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744 if(!target_path)
3745 return PyErr_NoMemory();
3746
Steve Dower2ea51c92015-03-20 21:49:12 -07003747 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3748 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003749 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003750 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003751
3752 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003753 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003754
3755 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003756 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003757 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003758 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003759}
Brian Curtin62857742010-09-06 17:07:27 +00003760
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003761/*[clinic input]
3762os._isdir
3763
3764 path: path_t
3765 /
3766
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003767Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003768[clinic start generated code]*/
3769
Brian Curtin9c669cc2011-06-08 18:17:18 -05003770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003771os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003772/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003773{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003774 DWORD attributes;
3775
Steve Dowerb22a6772016-07-17 20:49:38 -07003776 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003777 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003778 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003779
Brian Curtin9c669cc2011-06-08 18:17:18 -05003780 if (attributes == INVALID_FILE_ATTRIBUTES)
3781 Py_RETURN_FALSE;
3782
Brian Curtin9c669cc2011-06-08 18:17:18 -05003783 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3784 Py_RETURN_TRUE;
3785 else
3786 Py_RETURN_FALSE;
3787}
Tim Golden6b528062013-08-01 12:44:00 +01003788
Tim Golden6b528062013-08-01 12:44:00 +01003789
Larry Hastings2f936352014-08-05 14:04:04 +10003790/*[clinic input]
3791os._getvolumepathname
3792
3793 path: unicode
3794
3795A helper function for ismount on Win32.
3796[clinic start generated code]*/
3797
Larry Hastings2f936352014-08-05 14:04:04 +10003798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003799os__getvolumepathname_impl(PyObject *module, PyObject *path)
3800/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003801{
3802 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003803 const wchar_t *path_wchar;
3804 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003805 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003806 BOOL ret;
3807
Larry Hastings2f936352014-08-05 14:04:04 +10003808 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3809 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003810 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003811 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003812
3813 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003814 buflen = Py_MAX(buflen, MAX_PATH);
3815
Victor Stinner850a18e2017-10-24 16:53:32 -07003816 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003817 PyErr_SetString(PyExc_OverflowError, "path too long");
3818 return NULL;
3819 }
3820
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003821 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003822 if (mountpath == NULL)
3823 return PyErr_NoMemory();
3824
3825 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003826 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003827 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003828 Py_END_ALLOW_THREADS
3829
3830 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003831 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003832 goto exit;
3833 }
3834 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3835
3836exit:
3837 PyMem_Free(mountpath);
3838 return result;
3839}
Tim Golden6b528062013-08-01 12:44:00 +01003840
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003841#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003842
Larry Hastings2f936352014-08-05 14:04:04 +10003843
3844/*[clinic input]
3845os.mkdir
3846
3847 path : path_t
3848
3849 mode: int = 0o777
3850
3851 *
3852
3853 dir_fd : dir_fd(requires='mkdirat') = None
3854
3855# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3856
3857Create a directory.
3858
3859If dir_fd is not None, it should be a file descriptor open to a directory,
3860 and path should be relative; path will then be relative to that directory.
3861dir_fd may not be implemented on your platform.
3862 If it is unavailable, using it will raise a NotImplementedError.
3863
3864The mode argument is ignored on Windows.
3865[clinic start generated code]*/
3866
Larry Hastings2f936352014-08-05 14:04:04 +10003867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003868os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3869/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003870{
3871 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003872
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003873#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003875 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003876 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003877
Larry Hastings2f936352014-08-05 14:04:04 +10003878 if (!result)
3879 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003880#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003882#if HAVE_MKDIRAT
3883 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003884 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003885 else
3886#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003887#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003888 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003889#else
Larry Hastings2f936352014-08-05 14:04:04 +10003890 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003891#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003892 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003893 if (result < 0)
3894 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003895#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003896 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003897}
3898
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003899
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003900/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3901#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003902#include <sys/resource.h>
3903#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003904
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003905
3906#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003907/*[clinic input]
3908os.nice
3909
3910 increment: int
3911 /
3912
3913Add increment to the priority of process and return the new priority.
3914[clinic start generated code]*/
3915
Larry Hastings2f936352014-08-05 14:04:04 +10003916static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003917os_nice_impl(PyObject *module, int increment)
3918/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003919{
3920 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003921
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 /* There are two flavours of 'nice': one that returns the new
3923 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003924 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003925 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003926
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 If we are of the nice family that returns the new priority, we
3928 need to clear errno before the call, and check if errno is filled
3929 before calling posix_error() on a returnvalue of -1, because the
3930 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003931
Victor Stinner8c62be82010-05-06 00:08:46 +00003932 errno = 0;
3933 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003934#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 if (value == 0)
3936 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003937#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003938 if (value == -1 && errno != 0)
3939 /* either nice() or getpriority() returned an error */
3940 return posix_error();
3941 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003942}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003943#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003944
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003945
3946#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003947/*[clinic input]
3948os.getpriority
3949
3950 which: int
3951 who: int
3952
3953Return program scheduling priority.
3954[clinic start generated code]*/
3955
Larry Hastings2f936352014-08-05 14:04:04 +10003956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003957os_getpriority_impl(PyObject *module, int which, int who)
3958/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003959{
3960 int retval;
3961
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003962 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003963 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003964 if (errno != 0)
3965 return posix_error();
3966 return PyLong_FromLong((long)retval);
3967}
3968#endif /* HAVE_GETPRIORITY */
3969
3970
3971#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003972/*[clinic input]
3973os.setpriority
3974
3975 which: int
3976 who: int
3977 priority: int
3978
3979Set program scheduling priority.
3980[clinic start generated code]*/
3981
Larry Hastings2f936352014-08-05 14:04:04 +10003982static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003983os_setpriority_impl(PyObject *module, int which, int who, int priority)
3984/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003985{
3986 int retval;
3987
3988 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003989 if (retval == -1)
3990 return posix_error();
3991 Py_RETURN_NONE;
3992}
3993#endif /* HAVE_SETPRIORITY */
3994
3995
Barry Warsaw53699e91996-12-10 23:23:01 +00003996static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003997internal_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 +00003998{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003999 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004000 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004002#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004003 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004004 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004005#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004007#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004008
Larry Hastings9cf065c2012-06-22 16:30:09 -07004009 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4010 (dst_dir_fd != DEFAULT_DIR_FD);
4011#ifndef HAVE_RENAMEAT
4012 if (dir_fd_specified) {
4013 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004014 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004015 }
4016#endif
4017
Larry Hastings9cf065c2012-06-22 16:30:09 -07004018#ifdef MS_WINDOWS
4019 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004020 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004021 Py_END_ALLOW_THREADS
4022
Larry Hastings2f936352014-08-05 14:04:04 +10004023 if (!result)
4024 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004025
4026#else
Steve Dowercc16be82016-09-08 10:35:16 -07004027 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4028 PyErr_Format(PyExc_ValueError,
4029 "%s: src and dst must be the same type", function_name);
4030 return NULL;
4031 }
4032
Larry Hastings9cf065c2012-06-22 16:30:09 -07004033 Py_BEGIN_ALLOW_THREADS
4034#ifdef HAVE_RENAMEAT
4035 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004036 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004037 else
4038#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004039 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040 Py_END_ALLOW_THREADS
4041
Larry Hastings2f936352014-08-05 14:04:04 +10004042 if (result)
4043 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004044#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004045 Py_RETURN_NONE;
4046}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047
Larry Hastings2f936352014-08-05 14:04:04 +10004048
4049/*[clinic input]
4050os.rename
4051
4052 src : path_t
4053 dst : path_t
4054 *
4055 src_dir_fd : dir_fd = None
4056 dst_dir_fd : dir_fd = None
4057
4058Rename a file or directory.
4059
4060If either src_dir_fd or dst_dir_fd is not None, it should be a file
4061 descriptor open to a directory, and the respective path string (src or dst)
4062 should be relative; the path will then be relative to that directory.
4063src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4064 If they are unavailable, using them will raise a NotImplementedError.
4065[clinic start generated code]*/
4066
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004068os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004069 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004070/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004071{
Larry Hastings2f936352014-08-05 14:04:04 +10004072 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004073}
4074
Larry Hastings2f936352014-08-05 14:04:04 +10004075
4076/*[clinic input]
4077os.replace = os.rename
4078
4079Rename a file or directory, overwriting the destination.
4080
4081If either src_dir_fd or dst_dir_fd is not None, it should be a file
4082 descriptor open to a directory, and the respective path string (src or dst)
4083 should be relative; the path will then be relative to that directory.
4084src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4085 If they are unavailable, using them will raise a NotImplementedError."
4086[clinic start generated code]*/
4087
Larry Hastings2f936352014-08-05 14:04:04 +10004088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004089os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4090 int dst_dir_fd)
4091/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004092{
4093 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4094}
4095
4096
4097/*[clinic input]
4098os.rmdir
4099
4100 path: path_t
4101 *
4102 dir_fd: dir_fd(requires='unlinkat') = None
4103
4104Remove a directory.
4105
4106If dir_fd is not None, it should be a file descriptor open to a directory,
4107 and path should be relative; path will then be relative to that directory.
4108dir_fd may not be implemented on your platform.
4109 If it is unavailable, using it will raise a NotImplementedError.
4110[clinic start generated code]*/
4111
Larry Hastings2f936352014-08-05 14:04:04 +10004112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004113os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4114/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004115{
4116 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004117
4118 Py_BEGIN_ALLOW_THREADS
4119#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004120 /* Windows, success=1, UNIX, success=0 */
4121 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004122#else
4123#ifdef HAVE_UNLINKAT
4124 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004125 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004126 else
4127#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004128 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004129#endif
4130 Py_END_ALLOW_THREADS
4131
Larry Hastings2f936352014-08-05 14:04:04 +10004132 if (result)
4133 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004134
Larry Hastings2f936352014-08-05 14:04:04 +10004135 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004136}
4137
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004138
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004139#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004140#ifdef MS_WINDOWS
4141/*[clinic input]
4142os.system -> long
4143
4144 command: Py_UNICODE
4145
4146Execute the command in a subshell.
4147[clinic start generated code]*/
4148
Larry Hastings2f936352014-08-05 14:04:04 +10004149static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004150os_system_impl(PyObject *module, Py_UNICODE *command)
4151/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004152{
4153 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004155 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004156 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004157 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004158 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004159 return result;
4160}
4161#else /* MS_WINDOWS */
4162/*[clinic input]
4163os.system -> long
4164
4165 command: FSConverter
4166
4167Execute the command in a subshell.
4168[clinic start generated code]*/
4169
Larry Hastings2f936352014-08-05 14:04:04 +10004170static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004171os_system_impl(PyObject *module, PyObject *command)
4172/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004173{
4174 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004175 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004176 Py_BEGIN_ALLOW_THREADS
4177 result = system(bytes);
4178 Py_END_ALLOW_THREADS
4179 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004180}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004181#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004182#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Larry Hastings2f936352014-08-05 14:04:04 +10004185/*[clinic input]
4186os.umask
4187
4188 mask: int
4189 /
4190
4191Set the current numeric umask and return the previous umask.
4192[clinic start generated code]*/
4193
Larry Hastings2f936352014-08-05 14:04:04 +10004194static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004195os_umask_impl(PyObject *module, int mask)
4196/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004197{
4198 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 if (i < 0)
4200 return posix_error();
4201 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004202}
4203
Brian Curtind40e6f72010-07-08 21:39:08 +00004204#ifdef MS_WINDOWS
4205
4206/* override the default DeleteFileW behavior so that directory
4207symlinks can be removed with this function, the same as with
4208Unix symlinks */
4209BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4210{
4211 WIN32_FILE_ATTRIBUTE_DATA info;
4212 WIN32_FIND_DATAW find_data;
4213 HANDLE find_data_handle;
4214 int is_directory = 0;
4215 int is_link = 0;
4216
4217 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4218 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004219
Brian Curtind40e6f72010-07-08 21:39:08 +00004220 /* Get WIN32_FIND_DATA structure for the path to determine if
4221 it is a symlink */
4222 if(is_directory &&
4223 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4224 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4225
4226 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004227 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4228 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4229 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4230 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004231 FindClose(find_data_handle);
4232 }
4233 }
4234 }
4235
4236 if (is_directory && is_link)
4237 return RemoveDirectoryW(lpFileName);
4238
4239 return DeleteFileW(lpFileName);
4240}
4241#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004243
Larry Hastings2f936352014-08-05 14:04:04 +10004244/*[clinic input]
4245os.unlink
4246
4247 path: path_t
4248 *
4249 dir_fd: dir_fd(requires='unlinkat')=None
4250
4251Remove a file (same as remove()).
4252
4253If dir_fd is not None, it should be a file descriptor open to a directory,
4254 and path should be relative; path will then be relative to that directory.
4255dir_fd may not be implemented on your platform.
4256 If it is unavailable, using it will raise a NotImplementedError.
4257
4258[clinic start generated code]*/
4259
Larry Hastings2f936352014-08-05 14:04:04 +10004260static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004261os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4262/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004263{
4264 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004265
4266 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004267 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004268#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004269 /* Windows, success=1, UNIX, success=0 */
4270 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004271#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004272#ifdef HAVE_UNLINKAT
4273 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004274 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004275 else
4276#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004277 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004278#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004279 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004280 Py_END_ALLOW_THREADS
4281
Larry Hastings2f936352014-08-05 14:04:04 +10004282 if (result)
4283 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004284
Larry Hastings2f936352014-08-05 14:04:04 +10004285 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004286}
4287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004288
Larry Hastings2f936352014-08-05 14:04:04 +10004289/*[clinic input]
4290os.remove = os.unlink
4291
4292Remove a file (same as unlink()).
4293
4294If dir_fd is not None, it should be a file descriptor open to a directory,
4295 and path should be relative; path will then be relative to that directory.
4296dir_fd may not be implemented on your platform.
4297 If it is unavailable, using it will raise a NotImplementedError.
4298[clinic start generated code]*/
4299
Larry Hastings2f936352014-08-05 14:04:04 +10004300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004301os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4302/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004303{
4304 return os_unlink_impl(module, path, dir_fd);
4305}
4306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Larry Hastings605a62d2012-06-24 04:33:36 -07004308static PyStructSequence_Field uname_result_fields[] = {
4309 {"sysname", "operating system name"},
4310 {"nodename", "name of machine on network (implementation-defined)"},
4311 {"release", "operating system release"},
4312 {"version", "operating system version"},
4313 {"machine", "hardware identifier"},
4314 {NULL}
4315};
4316
4317PyDoc_STRVAR(uname_result__doc__,
4318"uname_result: Result from os.uname().\n\n\
4319This object may be accessed either as a tuple of\n\
4320 (sysname, nodename, release, version, machine),\n\
4321or via the attributes sysname, nodename, release, version, and machine.\n\
4322\n\
4323See os.uname for more information.");
4324
4325static PyStructSequence_Desc uname_result_desc = {
4326 "uname_result", /* name */
4327 uname_result__doc__, /* doc */
4328 uname_result_fields,
4329 5
4330};
4331
4332static PyTypeObject UnameResultType;
4333
4334
4335#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004336/*[clinic input]
4337os.uname
4338
4339Return an object identifying the current operating system.
4340
4341The object behaves like a named tuple with the following fields:
4342 (sysname, nodename, release, version, machine)
4343
4344[clinic start generated code]*/
4345
Larry Hastings2f936352014-08-05 14:04:04 +10004346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004347os_uname_impl(PyObject *module)
4348/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004349{
Victor Stinner8c62be82010-05-06 00:08:46 +00004350 struct utsname u;
4351 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004352 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004353
Victor Stinner8c62be82010-05-06 00:08:46 +00004354 Py_BEGIN_ALLOW_THREADS
4355 res = uname(&u);
4356 Py_END_ALLOW_THREADS
4357 if (res < 0)
4358 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004359
4360 value = PyStructSequence_New(&UnameResultType);
4361 if (value == NULL)
4362 return NULL;
4363
4364#define SET(i, field) \
4365 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004366 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004367 if (!o) { \
4368 Py_DECREF(value); \
4369 return NULL; \
4370 } \
4371 PyStructSequence_SET_ITEM(value, i, o); \
4372 } \
4373
4374 SET(0, u.sysname);
4375 SET(1, u.nodename);
4376 SET(2, u.release);
4377 SET(3, u.version);
4378 SET(4, u.machine);
4379
4380#undef SET
4381
4382 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004383}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004384#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004385
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004386
Larry Hastings9cf065c2012-06-22 16:30:09 -07004387
4388typedef struct {
4389 int now;
4390 time_t atime_s;
4391 long atime_ns;
4392 time_t mtime_s;
4393 long mtime_ns;
4394} utime_t;
4395
4396/*
Victor Stinner484df002014-10-09 13:52:31 +02004397 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004398 * they also intentionally leak the declaration of a pointer named "time"
4399 */
4400#define UTIME_TO_TIMESPEC \
4401 struct timespec ts[2]; \
4402 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004403 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004404 time = NULL; \
4405 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004406 ts[0].tv_sec = ut->atime_s; \
4407 ts[0].tv_nsec = ut->atime_ns; \
4408 ts[1].tv_sec = ut->mtime_s; \
4409 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004410 time = ts; \
4411 } \
4412
4413#define UTIME_TO_TIMEVAL \
4414 struct timeval tv[2]; \
4415 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004416 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004417 time = NULL; \
4418 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004419 tv[0].tv_sec = ut->atime_s; \
4420 tv[0].tv_usec = ut->atime_ns / 1000; \
4421 tv[1].tv_sec = ut->mtime_s; \
4422 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004423 time = tv; \
4424 } \
4425
4426#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004427 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004428 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004429 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004430 time = NULL; \
4431 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004432 u.actime = ut->atime_s; \
4433 u.modtime = ut->mtime_s; \
4434 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004435 }
4436
4437#define UTIME_TO_TIME_T \
4438 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004439 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004440 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004441 time = NULL; \
4442 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004443 timet[0] = ut->atime_s; \
4444 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004445 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004446 } \
4447
4448
Victor Stinner528a9ab2015-09-03 21:30:26 +02004449#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450
4451static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004452utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004453{
4454#ifdef HAVE_UTIMENSAT
4455 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4456 UTIME_TO_TIMESPEC;
4457 return utimensat(dir_fd, path, time, flags);
4458#elif defined(HAVE_FUTIMESAT)
4459 UTIME_TO_TIMEVAL;
4460 /*
4461 * follow_symlinks will never be false here;
4462 * we only allow !follow_symlinks and dir_fd together
4463 * if we have utimensat()
4464 */
4465 assert(follow_symlinks);
4466 return futimesat(dir_fd, path, time);
4467#endif
4468}
4469
Larry Hastings2f936352014-08-05 14:04:04 +10004470 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4471#else
4472 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473#endif
4474
Victor Stinner528a9ab2015-09-03 21:30:26 +02004475#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476
4477static int
Victor Stinner484df002014-10-09 13:52:31 +02004478utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004479{
4480#ifdef HAVE_FUTIMENS
4481 UTIME_TO_TIMESPEC;
4482 return futimens(fd, time);
4483#else
4484 UTIME_TO_TIMEVAL;
4485 return futimes(fd, time);
4486#endif
4487}
4488
Larry Hastings2f936352014-08-05 14:04:04 +10004489 #define PATH_UTIME_HAVE_FD 1
4490#else
4491 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004492#endif
4493
Victor Stinner5ebae872015-09-22 01:29:33 +02004494#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4495# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4496#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497
Victor Stinner4552ced2015-09-21 22:37:15 +02004498#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499
4500static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004501utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004502{
4503#ifdef HAVE_UTIMENSAT
4504 UTIME_TO_TIMESPEC;
4505 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4506#else
4507 UTIME_TO_TIMEVAL;
4508 return lutimes(path, time);
4509#endif
4510}
4511
4512#endif
4513
4514#ifndef MS_WINDOWS
4515
4516static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004517utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518{
4519#ifdef HAVE_UTIMENSAT
4520 UTIME_TO_TIMESPEC;
4521 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4522#elif defined(HAVE_UTIMES)
4523 UTIME_TO_TIMEVAL;
4524 return utimes(path, time);
4525#elif defined(HAVE_UTIME_H)
4526 UTIME_TO_UTIMBUF;
4527 return utime(path, time);
4528#else
4529 UTIME_TO_TIME_T;
4530 return utime(path, time);
4531#endif
4532}
4533
4534#endif
4535
Larry Hastings76ad59b2012-05-03 00:30:07 -07004536static int
4537split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4538{
4539 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004540 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004541 divmod = PyNumber_Divmod(py_long, billion);
4542 if (!divmod)
4543 goto exit;
4544 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4545 if ((*s == -1) && PyErr_Occurred())
4546 goto exit;
4547 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004548 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004549 goto exit;
4550
4551 result = 1;
4552exit:
4553 Py_XDECREF(divmod);
4554 return result;
4555}
4556
Larry Hastings2f936352014-08-05 14:04:04 +10004557
4558/*[clinic input]
4559os.utime
4560
4561 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4562 times: object = NULL
4563 *
4564 ns: object = NULL
4565 dir_fd: dir_fd(requires='futimensat') = None
4566 follow_symlinks: bool=True
4567
Martin Panter0ff89092015-09-09 01:56:53 +00004568# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004569
4570Set the access and modified time of path.
4571
4572path may always be specified as a string.
4573On some platforms, path may also be specified as an open file descriptor.
4574 If this functionality is unavailable, using it raises an exception.
4575
4576If times is not None, it must be a tuple (atime, mtime);
4577 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004578If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004579 atime_ns and mtime_ns should be expressed as integer nanoseconds
4580 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004581If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004582Specifying tuples for both times and ns is an error.
4583
4584If dir_fd is not None, it should be a file descriptor open to a directory,
4585 and path should be relative; path will then be relative to that directory.
4586If follow_symlinks is False, and the last element of the path is a symbolic
4587 link, utime will modify the symbolic link itself instead of the file the
4588 link points to.
4589It is an error to use dir_fd or follow_symlinks when specifying path
4590 as an open file descriptor.
4591dir_fd and follow_symlinks may not be available on your platform.
4592 If they are unavailable, using them will raise a NotImplementedError.
4593
4594[clinic start generated code]*/
4595
Larry Hastings2f936352014-08-05 14:04:04 +10004596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004597os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4598 int dir_fd, int follow_symlinks)
4599/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004600{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601#ifdef MS_WINDOWS
4602 HANDLE hFile;
4603 FILETIME atime, mtime;
4604#else
4605 int result;
4606#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004607
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004609 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004610
Christian Heimesb3c87242013-08-01 00:08:16 +02004611 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004612
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613 if (times && (times != Py_None) && ns) {
4614 PyErr_SetString(PyExc_ValueError,
4615 "utime: you may specify either 'times'"
4616 " or 'ns' but not both");
4617 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004618 }
4619
4620 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004621 time_t a_sec, m_sec;
4622 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004623 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624 PyErr_SetString(PyExc_TypeError,
4625 "utime: 'times' must be either"
4626 " a tuple of two ints or None");
4627 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004628 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004630 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004631 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004632 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004633 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004635 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004636 utime.atime_s = a_sec;
4637 utime.atime_ns = a_nsec;
4638 utime.mtime_s = m_sec;
4639 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004640 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004642 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004643 PyErr_SetString(PyExc_TypeError,
4644 "utime: 'ns' must be a tuple of two ints");
4645 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004646 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004648 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004650 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 &utime.mtime_s, &utime.mtime_ns)) {
4652 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004653 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 }
4655 else {
4656 /* times and ns are both None/unspecified. use "now". */
4657 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004658 }
4659
Victor Stinner4552ced2015-09-21 22:37:15 +02004660#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004661 if (follow_symlinks_specified("utime", follow_symlinks))
4662 goto exit;
4663#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004664
Larry Hastings2f936352014-08-05 14:04:04 +10004665 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4666 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4667 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004669
Larry Hastings9cf065c2012-06-22 16:30:09 -07004670#if !defined(HAVE_UTIMENSAT)
4671 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004672 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673 "utime: cannot use dir_fd and follow_symlinks "
4674 "together on this platform");
4675 goto exit;
4676 }
4677#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004678
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004679#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004681 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4682 NULL, OPEN_EXISTING,
4683 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004684 Py_END_ALLOW_THREADS
4685 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004686 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004688 }
4689
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004691 GetSystemTimeAsFileTime(&mtime);
4692 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004693 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004694 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004695 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4696 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004697 }
4698 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4699 /* Avoid putting the file name into the error here,
4700 as that may confuse the user into believing that
4701 something is wrong with the file, when it also
4702 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004703 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004704 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004705 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004706#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004708
Victor Stinner4552ced2015-09-21 22:37:15 +02004709#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004711 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004713#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714
Victor Stinner528a9ab2015-09-03 21:30:26 +02004715#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004717 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 else
4719#endif
4720
Victor Stinner528a9ab2015-09-03 21:30:26 +02004721#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004722 if (path->fd != -1)
4723 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004724 else
4725#endif
4726
Larry Hastings2f936352014-08-05 14:04:04 +10004727 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004728
4729 Py_END_ALLOW_THREADS
4730
4731 if (result < 0) {
4732 /* see previous comment about not putting filename in error here */
4733 return_value = posix_error();
4734 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004736
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004737#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738
4739 Py_INCREF(Py_None);
4740 return_value = Py_None;
4741
4742exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743#ifdef MS_WINDOWS
4744 if (hFile != INVALID_HANDLE_VALUE)
4745 CloseHandle(hFile);
4746#endif
4747 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004748}
4749
Guido van Rossum3b066191991-06-04 19:40:25 +00004750/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004751
Larry Hastings2f936352014-08-05 14:04:04 +10004752
4753/*[clinic input]
4754os._exit
4755
4756 status: int
4757
4758Exit to the system with specified status, without normal exit processing.
4759[clinic start generated code]*/
4760
Larry Hastings2f936352014-08-05 14:04:04 +10004761static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004762os__exit_impl(PyObject *module, int status)
4763/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004764{
4765 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004766 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004767}
4768
Steve Dowercc16be82016-09-08 10:35:16 -07004769#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4770#define EXECV_CHAR wchar_t
4771#else
4772#define EXECV_CHAR char
4773#endif
4774
Martin v. Löwis114619e2002-10-07 06:44:21 +00004775#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4776static void
Steve Dowercc16be82016-09-08 10:35:16 -07004777free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004778{
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 Py_ssize_t i;
4780 for (i = 0; i < count; i++)
4781 PyMem_Free(array[i]);
4782 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004783}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004784
Berker Peksag81816462016-09-15 20:19:47 +03004785static int
4786fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004787{
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004789 PyObject *ub;
4790 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004791#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004792 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004793 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004794 *out = PyUnicode_AsWideCharString(ub, &size);
4795 if (*out)
4796 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004797#else
Berker Peksag81816462016-09-15 20:19:47 +03004798 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004800 size = PyBytes_GET_SIZE(ub);
4801 *out = PyMem_Malloc(size + 1);
4802 if (*out) {
4803 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4804 result = 1;
4805 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004806 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004807#endif
Berker Peksag81816462016-09-15 20:19:47 +03004808 Py_DECREF(ub);
4809 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004810}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004811#endif
4812
Ross Lagerwall7807c352011-03-17 20:20:30 +02004813#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004814static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004815parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4816{
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 Py_ssize_t i, pos, envc;
4818 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004819 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004820 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004821
Victor Stinner8c62be82010-05-06 00:08:46 +00004822 i = PyMapping_Size(env);
4823 if (i < 0)
4824 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004825 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004826 if (envlist == NULL) {
4827 PyErr_NoMemory();
4828 return NULL;
4829 }
4830 envc = 0;
4831 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004832 if (!keys)
4833 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004835 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 goto error;
4837 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4838 PyErr_Format(PyExc_TypeError,
4839 "env.keys() or env.values() is not a list");
4840 goto error;
4841 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004842
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 for (pos = 0; pos < i; pos++) {
4844 key = PyList_GetItem(keys, pos);
4845 val = PyList_GetItem(vals, pos);
4846 if (!key || !val)
4847 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004848
Berker Peksag81816462016-09-15 20:19:47 +03004849#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4850 if (!PyUnicode_FSDecoder(key, &key2))
4851 goto error;
4852 if (!PyUnicode_FSDecoder(val, &val2)) {
4853 Py_DECREF(key2);
4854 goto error;
4855 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004856 /* Search from index 1 because on Windows starting '=' is allowed for
4857 defining hidden environment variables. */
4858 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4859 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4860 {
4861 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004862 Py_DECREF(key2);
4863 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004864 goto error;
4865 }
Berker Peksag81816462016-09-15 20:19:47 +03004866 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4867#else
4868 if (!PyUnicode_FSConverter(key, &key2))
4869 goto error;
4870 if (!PyUnicode_FSConverter(val, &val2)) {
4871 Py_DECREF(key2);
4872 goto error;
4873 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004874 if (PyBytes_GET_SIZE(key2) == 0 ||
4875 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4876 {
4877 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004878 Py_DECREF(key2);
4879 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004880 goto error;
4881 }
Berker Peksag81816462016-09-15 20:19:47 +03004882 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4883 PyBytes_AS_STRING(val2));
4884#endif
4885 Py_DECREF(key2);
4886 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004887 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004888 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004889
4890 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4891 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 goto error;
4893 }
Berker Peksag81816462016-09-15 20:19:47 +03004894
Steve Dowercc16be82016-09-08 10:35:16 -07004895 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 }
4897 Py_DECREF(vals);
4898 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004899
Victor Stinner8c62be82010-05-06 00:08:46 +00004900 envlist[envc] = 0;
4901 *envc_ptr = envc;
4902 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004903
4904error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004905 Py_XDECREF(keys);
4906 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004907 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004909}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004910
Steve Dowercc16be82016-09-08 10:35:16 -07004911static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004912parse_arglist(PyObject* argv, Py_ssize_t *argc)
4913{
4914 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004915 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004916 if (argvlist == NULL) {
4917 PyErr_NoMemory();
4918 return NULL;
4919 }
4920 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004921 PyObject* item = PySequence_ITEM(argv, i);
4922 if (item == NULL)
4923 goto fail;
4924 if (!fsconvert_strdup(item, &argvlist[i])) {
4925 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004926 goto fail;
4927 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004928 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004929 }
4930 argvlist[*argc] = NULL;
4931 return argvlist;
4932fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004933 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004934 free_string_array(argvlist, *argc);
4935 return NULL;
4936}
Steve Dowercc16be82016-09-08 10:35:16 -07004937
Ross Lagerwall7807c352011-03-17 20:20:30 +02004938#endif
4939
Larry Hastings2f936352014-08-05 14:04:04 +10004940
Ross Lagerwall7807c352011-03-17 20:20:30 +02004941#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004942/*[clinic input]
4943os.execv
4944
Steve Dowercc16be82016-09-08 10:35:16 -07004945 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004946 Path of executable file.
4947 argv: object
4948 Tuple or list of strings.
4949 /
4950
4951Execute an executable path with arguments, replacing current process.
4952[clinic start generated code]*/
4953
Larry Hastings2f936352014-08-05 14:04:04 +10004954static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004955os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4956/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004957{
Steve Dowercc16be82016-09-08 10:35:16 -07004958 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004959 Py_ssize_t argc;
4960
4961 /* execv has two arguments: (path, argv), where
4962 argv is a list or tuple of strings. */
4963
Ross Lagerwall7807c352011-03-17 20:20:30 +02004964 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4965 PyErr_SetString(PyExc_TypeError,
4966 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004967 return NULL;
4968 }
4969 argc = PySequence_Size(argv);
4970 if (argc < 1) {
4971 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004972 return NULL;
4973 }
4974
4975 argvlist = parse_arglist(argv, &argc);
4976 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004977 return NULL;
4978 }
Steve Dowerbce26262016-11-19 19:17:26 -08004979 if (!argvlist[0][0]) {
4980 PyErr_SetString(PyExc_ValueError,
4981 "execv() arg 2 first element cannot be empty");
4982 free_string_array(argvlist, argc);
4983 return NULL;
4984 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004985
Steve Dowerbce26262016-11-19 19:17:26 -08004986 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07004987#ifdef HAVE_WEXECV
4988 _wexecv(path->wide, argvlist);
4989#else
4990 execv(path->narrow, argvlist);
4991#endif
Steve Dowerbce26262016-11-19 19:17:26 -08004992 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02004993
4994 /* If we get here it's definitely an error */
4995
4996 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 return posix_error();
4998}
4999
Larry Hastings2f936352014-08-05 14:04:04 +10005000
5001/*[clinic input]
5002os.execve
5003
5004 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5005 Path of executable file.
5006 argv: object
5007 Tuple or list of strings.
5008 env: object
5009 Dictionary of strings mapping to strings.
5010
5011Execute an executable path with arguments, replacing current process.
5012[clinic start generated code]*/
5013
Larry Hastings2f936352014-08-05 14:04:04 +10005014static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005015os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5016/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005017{
Steve Dowercc16be82016-09-08 10:35:16 -07005018 EXECV_CHAR **argvlist = NULL;
5019 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005020 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005021
Victor Stinner8c62be82010-05-06 00:08:46 +00005022 /* execve has three arguments: (path, argv, env), where
5023 argv is a list or tuple of strings and env is a dictionary
5024 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005025
Ross Lagerwall7807c352011-03-17 20:20:30 +02005026 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005027 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005028 "execve: argv must be a tuple or list");
5029 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005031 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005032 if (argc < 1) {
5033 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5034 return NULL;
5035 }
5036
Victor Stinner8c62be82010-05-06 00:08:46 +00005037 if (!PyMapping_Check(env)) {
5038 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005039 "execve: environment must be a mapping object");
5040 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005042
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005045 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 }
Steve Dowerbce26262016-11-19 19:17:26 -08005047 if (!argvlist[0][0]) {
5048 PyErr_SetString(PyExc_ValueError,
5049 "execve: argv first element cannot be empty");
5050 goto fail;
5051 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005052
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 envlist = parse_envlist(env, &envc);
5054 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055 goto fail;
5056
Steve Dowerbce26262016-11-19 19:17:26 -08005057 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005058#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005059 if (path->fd > -1)
5060 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005061 else
5062#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005063#ifdef HAVE_WEXECV
5064 _wexecve(path->wide, argvlist, envlist);
5065#else
Larry Hastings2f936352014-08-05 14:04:04 +10005066 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005067#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005068 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005069
5070 /* If we get here it's definitely an error */
5071
Larry Hastings2f936352014-08-05 14:04:04 +10005072 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005073
Steve Dowercc16be82016-09-08 10:35:16 -07005074 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005075 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005076 if (argvlist)
5077 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005078 return NULL;
5079}
Steve Dowercc16be82016-09-08 10:35:16 -07005080
Larry Hastings9cf065c2012-06-22 16:30:09 -07005081#endif /* HAVE_EXECV */
5082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Steve Dowercc16be82016-09-08 10:35:16 -07005084#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005085/*[clinic input]
5086os.spawnv
5087
5088 mode: int
5089 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005090 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005091 Path of executable file.
5092 argv: object
5093 Tuple or list of strings.
5094 /
5095
5096Execute the program specified by path in a new process.
5097[clinic start generated code]*/
5098
Larry Hastings2f936352014-08-05 14:04:04 +10005099static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005100os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5101/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005102{
Steve Dowercc16be82016-09-08 10:35:16 -07005103 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005104 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005106 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005108
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 /* spawnv has three arguments: (mode, path, argv), where
5110 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005111
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 if (PyList_Check(argv)) {
5113 argc = PyList_Size(argv);
5114 getitem = PyList_GetItem;
5115 }
5116 else if (PyTuple_Check(argv)) {
5117 argc = PyTuple_Size(argv);
5118 getitem = PyTuple_GetItem;
5119 }
5120 else {
5121 PyErr_SetString(PyExc_TypeError,
5122 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 return NULL;
5124 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005125 if (argc == 0) {
5126 PyErr_SetString(PyExc_ValueError,
5127 "spawnv() arg 2 cannot be empty");
5128 return NULL;
5129 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005130
Steve Dowercc16be82016-09-08 10:35:16 -07005131 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 return PyErr_NoMemory();
5134 }
5135 for (i = 0; i < argc; i++) {
5136 if (!fsconvert_strdup((*getitem)(argv, i),
5137 &argvlist[i])) {
5138 free_string_array(argvlist, i);
5139 PyErr_SetString(
5140 PyExc_TypeError,
5141 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 return NULL;
5143 }
Steve Dower93ff8722016-11-19 19:03:54 -08005144 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005145 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005146 PyErr_SetString(
5147 PyExc_ValueError,
5148 "spawnv() arg 2 first element cannot be empty");
5149 return NULL;
5150 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 }
5152 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005153
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 if (mode == _OLD_P_OVERLAY)
5155 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005156
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005158 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005159#ifdef HAVE_WSPAWNV
5160 spawnval = _wspawnv(mode, path->wide, argvlist);
5161#else
5162 spawnval = _spawnv(mode, path->narrow, argvlist);
5163#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005164 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005166
Victor Stinner8c62be82010-05-06 00:08:46 +00005167 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005168
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 if (spawnval == -1)
5170 return posix_error();
5171 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005172 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005173}
5174
5175
Larry Hastings2f936352014-08-05 14:04:04 +10005176/*[clinic input]
5177os.spawnve
5178
5179 mode: int
5180 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005181 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005182 Path of executable file.
5183 argv: object
5184 Tuple or list of strings.
5185 env: object
5186 Dictionary of strings mapping to strings.
5187 /
5188
5189Execute the program specified by path in a new process.
5190[clinic start generated code]*/
5191
Larry Hastings2f936352014-08-05 14:04:04 +10005192static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005193os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005194 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005195/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005196{
Steve Dowercc16be82016-09-08 10:35:16 -07005197 EXECV_CHAR **argvlist;
5198 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005200 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005201 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005203 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 /* spawnve has four arguments: (mode, path, argv, env), where
5206 argv is a list or tuple of strings and env is a dictionary
5207 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005208
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 if (PyList_Check(argv)) {
5210 argc = PyList_Size(argv);
5211 getitem = PyList_GetItem;
5212 }
5213 else if (PyTuple_Check(argv)) {
5214 argc = PyTuple_Size(argv);
5215 getitem = PyTuple_GetItem;
5216 }
5217 else {
5218 PyErr_SetString(PyExc_TypeError,
5219 "spawnve() arg 2 must be a tuple or list");
5220 goto fail_0;
5221 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005222 if (argc == 0) {
5223 PyErr_SetString(PyExc_ValueError,
5224 "spawnve() arg 2 cannot be empty");
5225 goto fail_0;
5226 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005227 if (!PyMapping_Check(env)) {
5228 PyErr_SetString(PyExc_TypeError,
5229 "spawnve() arg 3 must be a mapping object");
5230 goto fail_0;
5231 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005232
Steve Dowercc16be82016-09-08 10:35:16 -07005233 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005234 if (argvlist == NULL) {
5235 PyErr_NoMemory();
5236 goto fail_0;
5237 }
5238 for (i = 0; i < argc; i++) {
5239 if (!fsconvert_strdup((*getitem)(argv, i),
5240 &argvlist[i]))
5241 {
5242 lastarg = i;
5243 goto fail_1;
5244 }
Steve Dowerbce26262016-11-19 19:17:26 -08005245 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005246 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005247 PyErr_SetString(
5248 PyExc_ValueError,
5249 "spawnv() arg 2 first element cannot be empty");
5250 goto fail_1;
5251 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 }
5253 lastarg = argc;
5254 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005255
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 envlist = parse_envlist(env, &envc);
5257 if (envlist == NULL)
5258 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005259
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 if (mode == _OLD_P_OVERLAY)
5261 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005262
Victor Stinner8c62be82010-05-06 00:08:46 +00005263 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005264 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005265#ifdef HAVE_WSPAWNV
5266 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5267#else
5268 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5269#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005270 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005271 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005272
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 if (spawnval == -1)
5274 (void) posix_error();
5275 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005276 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005277
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 while (--envc >= 0)
5279 PyMem_DEL(envlist[envc]);
5280 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005281 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005282 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005283 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005284 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005285}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005286
Guido van Rossuma1065681999-01-25 23:20:23 +00005287#endif /* HAVE_SPAWNV */
5288
5289
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005290#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005291
5292/* Helper function to validate arguments.
5293 Returns 0 on success. non-zero on failure with a TypeError raised.
5294 If obj is non-NULL it must be callable. */
5295static int
5296check_null_or_callable(PyObject *obj, const char* obj_name)
5297{
5298 if (obj && !PyCallable_Check(obj)) {
5299 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5300 obj_name, Py_TYPE(obj)->tp_name);
5301 return -1;
5302 }
5303 return 0;
5304}
5305
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005306/*[clinic input]
5307os.register_at_fork
5308
Gregory P. Smith163468a2017-05-29 10:03:41 -07005309 *
5310 before: object=NULL
5311 A callable to be called in the parent before the fork() syscall.
5312 after_in_child: object=NULL
5313 A callable to be called in the child after fork().
5314 after_in_parent: object=NULL
5315 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005316
Gregory P. Smith163468a2017-05-29 10:03:41 -07005317Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005318
Gregory P. Smith163468a2017-05-29 10:03:41 -07005319'before' callbacks are called in reverse order.
5320'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005321
5322[clinic start generated code]*/
5323
5324static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005325os_register_at_fork_impl(PyObject *module, PyObject *before,
5326 PyObject *after_in_child, PyObject *after_in_parent)
5327/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005328{
5329 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005330
Gregory P. Smith163468a2017-05-29 10:03:41 -07005331 if (!before && !after_in_child && !after_in_parent) {
5332 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5333 return NULL;
5334 }
5335 if (check_null_or_callable(before, "before") ||
5336 check_null_or_callable(after_in_child, "after_in_child") ||
5337 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005338 return NULL;
5339 }
5340 interp = PyThreadState_Get()->interp;
5341
Gregory P. Smith163468a2017-05-29 10:03:41 -07005342 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005343 return NULL;
5344 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005345 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005346 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005347 }
5348 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5349 return NULL;
5350 }
5351 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005352}
5353#endif /* HAVE_FORK */
5354
5355
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005356#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005357/*[clinic input]
5358os.fork1
5359
5360Fork a child process with a single multiplexed (i.e., not bound) thread.
5361
5362Return 0 to child process and PID of child to parent process.
5363[clinic start generated code]*/
5364
Larry Hastings2f936352014-08-05 14:04:04 +10005365static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005366os_fork1_impl(PyObject *module)
5367/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005368{
Victor Stinner8c62be82010-05-06 00:08:46 +00005369 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005370
5371 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 pid = fork1();
5373 if (pid == 0) {
5374 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005375 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005376 } else {
5377 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005378 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005379 }
5380 if (pid == -1)
5381 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005383}
Larry Hastings2f936352014-08-05 14:04:04 +10005384#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005385
5386
Guido van Rossumad0ee831995-03-01 10:34:45 +00005387#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005388/*[clinic input]
5389os.fork
5390
5391Fork a child process.
5392
5393Return 0 to child process and PID of child to parent process.
5394[clinic start generated code]*/
5395
Larry Hastings2f936352014-08-05 14:04:04 +10005396static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005397os_fork_impl(PyObject *module)
5398/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005399{
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005401
5402 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 pid = fork();
5404 if (pid == 0) {
5405 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005406 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 } else {
5408 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005409 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 }
5411 if (pid == -1)
5412 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005414}
Larry Hastings2f936352014-08-05 14:04:04 +10005415#endif /* HAVE_FORK */
5416
Guido van Rossum85e3b011991-06-03 12:42:10 +00005417
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005418#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005419#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005420/*[clinic input]
5421os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005422
Larry Hastings2f936352014-08-05 14:04:04 +10005423 policy: int
5424
5425Get the maximum scheduling priority for policy.
5426[clinic start generated code]*/
5427
Larry Hastings2f936352014-08-05 14:04:04 +10005428static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005429os_sched_get_priority_max_impl(PyObject *module, int policy)
5430/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005431{
5432 int max;
5433
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005434 max = sched_get_priority_max(policy);
5435 if (max < 0)
5436 return posix_error();
5437 return PyLong_FromLong(max);
5438}
5439
Larry Hastings2f936352014-08-05 14:04:04 +10005440
5441/*[clinic input]
5442os.sched_get_priority_min
5443
5444 policy: int
5445
5446Get the minimum scheduling priority for policy.
5447[clinic start generated code]*/
5448
Larry Hastings2f936352014-08-05 14:04:04 +10005449static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005450os_sched_get_priority_min_impl(PyObject *module, int policy)
5451/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005452{
5453 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005454 if (min < 0)
5455 return posix_error();
5456 return PyLong_FromLong(min);
5457}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005458#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5459
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005460
Larry Hastings2f936352014-08-05 14:04:04 +10005461#ifdef HAVE_SCHED_SETSCHEDULER
5462/*[clinic input]
5463os.sched_getscheduler
5464 pid: pid_t
5465 /
5466
5467Get the scheduling policy for the process identifiedy by pid.
5468
5469Passing 0 for pid returns the scheduling policy for the calling process.
5470[clinic start generated code]*/
5471
Larry Hastings2f936352014-08-05 14:04:04 +10005472static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005473os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5474/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005475{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005476 int policy;
5477
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005478 policy = sched_getscheduler(pid);
5479 if (policy < 0)
5480 return posix_error();
5481 return PyLong_FromLong(policy);
5482}
Larry Hastings2f936352014-08-05 14:04:04 +10005483#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005484
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005485
5486#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005487/*[clinic input]
5488class os.sched_param "PyObject *" "&SchedParamType"
5489
5490@classmethod
5491os.sched_param.__new__
5492
5493 sched_priority: object
5494 A scheduling parameter.
5495
5496Current has only one field: sched_priority");
5497[clinic start generated code]*/
5498
Larry Hastings2f936352014-08-05 14:04:04 +10005499static PyObject *
5500os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005501/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005502{
5503 PyObject *res;
5504
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005505 res = PyStructSequence_New(type);
5506 if (!res)
5507 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005508 Py_INCREF(sched_priority);
5509 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005510 return res;
5511}
5512
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005513
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005514PyDoc_VAR(os_sched_param__doc__);
5515
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005516static PyStructSequence_Field sched_param_fields[] = {
5517 {"sched_priority", "the scheduling priority"},
5518 {0}
5519};
5520
5521static PyStructSequence_Desc sched_param_desc = {
5522 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005523 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005524 sched_param_fields,
5525 1
5526};
5527
5528static int
5529convert_sched_param(PyObject *param, struct sched_param *res)
5530{
5531 long priority;
5532
5533 if (Py_TYPE(param) != &SchedParamType) {
5534 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5535 return 0;
5536 }
5537 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5538 if (priority == -1 && PyErr_Occurred())
5539 return 0;
5540 if (priority > INT_MAX || priority < INT_MIN) {
5541 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5542 return 0;
5543 }
5544 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5545 return 1;
5546}
Larry Hastings2f936352014-08-05 14:04:04 +10005547#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005549
5550#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005551/*[clinic input]
5552os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005553
Larry Hastings2f936352014-08-05 14:04:04 +10005554 pid: pid_t
5555 policy: int
5556 param: sched_param
5557 /
5558
5559Set the scheduling policy for the process identified by pid.
5560
5561If pid is 0, the calling process is changed.
5562param is an instance of sched_param.
5563[clinic start generated code]*/
5564
Larry Hastings2f936352014-08-05 14:04:04 +10005565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005566os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005567 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005568/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005569{
Jesus Cea9c822272011-09-10 01:40:52 +02005570 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005571 ** sched_setscheduler() returns 0 in Linux, but the previous
5572 ** scheduling policy under Solaris/Illumos, and others.
5573 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005574 */
Larry Hastings2f936352014-08-05 14:04:04 +10005575 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005576 return posix_error();
5577 Py_RETURN_NONE;
5578}
Larry Hastings2f936352014-08-05 14:04:04 +10005579#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005580
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005581
5582#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005583/*[clinic input]
5584os.sched_getparam
5585 pid: pid_t
5586 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005587
Larry Hastings2f936352014-08-05 14:04:04 +10005588Returns scheduling parameters for the process identified by pid.
5589
5590If pid is 0, returns parameters for the calling process.
5591Return value is an instance of sched_param.
5592[clinic start generated code]*/
5593
Larry Hastings2f936352014-08-05 14:04:04 +10005594static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005595os_sched_getparam_impl(PyObject *module, pid_t pid)
5596/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005597{
5598 struct sched_param param;
5599 PyObject *result;
5600 PyObject *priority;
5601
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005602 if (sched_getparam(pid, &param))
5603 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005604 result = PyStructSequence_New(&SchedParamType);
5605 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005606 return NULL;
5607 priority = PyLong_FromLong(param.sched_priority);
5608 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005609 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005610 return NULL;
5611 }
Larry Hastings2f936352014-08-05 14:04:04 +10005612 PyStructSequence_SET_ITEM(result, 0, priority);
5613 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005614}
5615
Larry Hastings2f936352014-08-05 14:04:04 +10005616
5617/*[clinic input]
5618os.sched_setparam
5619 pid: pid_t
5620 param: sched_param
5621 /
5622
5623Set scheduling parameters for the process identified by pid.
5624
5625If pid is 0, sets parameters for the calling process.
5626param should be an instance of sched_param.
5627[clinic start generated code]*/
5628
Larry Hastings2f936352014-08-05 14:04:04 +10005629static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005630os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005631 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005632/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005633{
5634 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005635 return posix_error();
5636 Py_RETURN_NONE;
5637}
Larry Hastings2f936352014-08-05 14:04:04 +10005638#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005639
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005640
5641#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005642/*[clinic input]
5643os.sched_rr_get_interval -> double
5644 pid: pid_t
5645 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005646
Larry Hastings2f936352014-08-05 14:04:04 +10005647Return the round-robin quantum for the process identified by pid, in seconds.
5648
5649Value returned is a float.
5650[clinic start generated code]*/
5651
Larry Hastings2f936352014-08-05 14:04:04 +10005652static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005653os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5654/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005655{
5656 struct timespec interval;
5657 if (sched_rr_get_interval(pid, &interval)) {
5658 posix_error();
5659 return -1.0;
5660 }
5661 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5662}
5663#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005664
Larry Hastings2f936352014-08-05 14:04:04 +10005665
5666/*[clinic input]
5667os.sched_yield
5668
5669Voluntarily relinquish the CPU.
5670[clinic start generated code]*/
5671
Larry Hastings2f936352014-08-05 14:04:04 +10005672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005673os_sched_yield_impl(PyObject *module)
5674/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005675{
5676 if (sched_yield())
5677 return posix_error();
5678 Py_RETURN_NONE;
5679}
5680
Benjamin Peterson2740af82011-08-02 17:41:34 -05005681#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005682/* The minimum number of CPUs allocated in a cpu_set_t */
5683static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005684
Larry Hastings2f936352014-08-05 14:04:04 +10005685/*[clinic input]
5686os.sched_setaffinity
5687 pid: pid_t
5688 mask : object
5689 /
5690
5691Set the CPU affinity of the process identified by pid to mask.
5692
5693mask should be an iterable of integers identifying CPUs.
5694[clinic start generated code]*/
5695
Larry Hastings2f936352014-08-05 14:04:04 +10005696static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005697os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5698/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005699{
Antoine Pitrou84869872012-08-04 16:16:35 +02005700 int ncpus;
5701 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005702 cpu_set_t *cpu_set = NULL;
5703 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005704
Larry Hastings2f936352014-08-05 14:04:04 +10005705 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005706 if (iterator == NULL)
5707 return NULL;
5708
5709 ncpus = NCPUS_START;
5710 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005711 cpu_set = CPU_ALLOC(ncpus);
5712 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005713 PyErr_NoMemory();
5714 goto error;
5715 }
Larry Hastings2f936352014-08-05 14:04:04 +10005716 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005717
5718 while ((item = PyIter_Next(iterator))) {
5719 long cpu;
5720 if (!PyLong_Check(item)) {
5721 PyErr_Format(PyExc_TypeError,
5722 "expected an iterator of ints, "
5723 "but iterator yielded %R",
5724 Py_TYPE(item));
5725 Py_DECREF(item);
5726 goto error;
5727 }
5728 cpu = PyLong_AsLong(item);
5729 Py_DECREF(item);
5730 if (cpu < 0) {
5731 if (!PyErr_Occurred())
5732 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5733 goto error;
5734 }
5735 if (cpu > INT_MAX - 1) {
5736 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5737 goto error;
5738 }
5739 if (cpu >= ncpus) {
5740 /* Grow CPU mask to fit the CPU number */
5741 int newncpus = ncpus;
5742 cpu_set_t *newmask;
5743 size_t newsetsize;
5744 while (newncpus <= cpu) {
5745 if (newncpus > INT_MAX / 2)
5746 newncpus = cpu + 1;
5747 else
5748 newncpus = newncpus * 2;
5749 }
5750 newmask = CPU_ALLOC(newncpus);
5751 if (newmask == NULL) {
5752 PyErr_NoMemory();
5753 goto error;
5754 }
5755 newsetsize = CPU_ALLOC_SIZE(newncpus);
5756 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005757 memcpy(newmask, cpu_set, setsize);
5758 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005759 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005760 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005761 ncpus = newncpus;
5762 }
Larry Hastings2f936352014-08-05 14:04:04 +10005763 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005764 }
5765 Py_CLEAR(iterator);
5766
Larry Hastings2f936352014-08-05 14:04:04 +10005767 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005768 posix_error();
5769 goto error;
5770 }
Larry Hastings2f936352014-08-05 14:04:04 +10005771 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005772 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005773
5774error:
Larry Hastings2f936352014-08-05 14:04:04 +10005775 if (cpu_set)
5776 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005777 Py_XDECREF(iterator);
5778 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005779}
5780
Larry Hastings2f936352014-08-05 14:04:04 +10005781
5782/*[clinic input]
5783os.sched_getaffinity
5784 pid: pid_t
5785 /
5786
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005787Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005788
5789The affinity is returned as a set of CPU identifiers.
5790[clinic start generated code]*/
5791
Larry Hastings2f936352014-08-05 14:04:04 +10005792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005793os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005794/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005795{
Antoine Pitrou84869872012-08-04 16:16:35 +02005796 int cpu, ncpus, count;
5797 size_t setsize;
5798 cpu_set_t *mask = NULL;
5799 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005800
Antoine Pitrou84869872012-08-04 16:16:35 +02005801 ncpus = NCPUS_START;
5802 while (1) {
5803 setsize = CPU_ALLOC_SIZE(ncpus);
5804 mask = CPU_ALLOC(ncpus);
5805 if (mask == NULL)
5806 return PyErr_NoMemory();
5807 if (sched_getaffinity(pid, setsize, mask) == 0)
5808 break;
5809 CPU_FREE(mask);
5810 if (errno != EINVAL)
5811 return posix_error();
5812 if (ncpus > INT_MAX / 2) {
5813 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5814 "a large enough CPU set");
5815 return NULL;
5816 }
5817 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005818 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005819
5820 res = PySet_New(NULL);
5821 if (res == NULL)
5822 goto error;
5823 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5824 if (CPU_ISSET_S(cpu, setsize, mask)) {
5825 PyObject *cpu_num = PyLong_FromLong(cpu);
5826 --count;
5827 if (cpu_num == NULL)
5828 goto error;
5829 if (PySet_Add(res, cpu_num)) {
5830 Py_DECREF(cpu_num);
5831 goto error;
5832 }
5833 Py_DECREF(cpu_num);
5834 }
5835 }
5836 CPU_FREE(mask);
5837 return res;
5838
5839error:
5840 if (mask)
5841 CPU_FREE(mask);
5842 Py_XDECREF(res);
5843 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005844}
5845
Benjamin Peterson2740af82011-08-02 17:41:34 -05005846#endif /* HAVE_SCHED_SETAFFINITY */
5847
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005848#endif /* HAVE_SCHED_H */
5849
Larry Hastings2f936352014-08-05 14:04:04 +10005850
Neal Norwitzb59798b2003-03-21 01:43:31 +00005851/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005852/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5853#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005854#define DEV_PTY_FILE "/dev/ptc"
5855#define HAVE_DEV_PTMX
5856#else
5857#define DEV_PTY_FILE "/dev/ptmx"
5858#endif
5859
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005860#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005861#ifdef HAVE_PTY_H
5862#include <pty.h>
5863#else
5864#ifdef HAVE_LIBUTIL_H
5865#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005866#else
5867#ifdef HAVE_UTIL_H
5868#include <util.h>
5869#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005870#endif /* HAVE_LIBUTIL_H */
5871#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005872#ifdef HAVE_STROPTS_H
5873#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005874#endif
5875#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005876
Larry Hastings2f936352014-08-05 14:04:04 +10005877
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005878#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005879/*[clinic input]
5880os.openpty
5881
5882Open a pseudo-terminal.
5883
5884Return a tuple of (master_fd, slave_fd) containing open file descriptors
5885for both the master and slave ends.
5886[clinic start generated code]*/
5887
Larry Hastings2f936352014-08-05 14:04:04 +10005888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005889os_openpty_impl(PyObject *module)
5890/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005891{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005892 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005893#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005894 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005895#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005896#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005897 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005898#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005899 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005900#endif
5901#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005902
Thomas Wouters70c21a12000-07-14 14:28:33 +00005903#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005904 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005905 goto posix_error;
5906
5907 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5908 goto error;
5909 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5910 goto error;
5911
Neal Norwitzb59798b2003-03-21 01:43:31 +00005912#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005913 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5914 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005915 goto posix_error;
5916 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5917 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005918
Victor Stinnerdaf45552013-08-28 00:53:59 +02005919 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005921 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005922
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005923#else
Victor Stinner000de532013-11-25 23:19:58 +01005924 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005926 goto posix_error;
5927
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005929
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 /* change permission of slave */
5931 if (grantpt(master_fd) < 0) {
5932 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005933 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005935
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 /* unlock slave */
5937 if (unlockpt(master_fd) < 0) {
5938 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005939 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005941
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005943
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 slave_name = ptsname(master_fd); /* get name of slave */
5945 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005946 goto posix_error;
5947
5948 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005949 if (slave_fd == -1)
5950 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005951
5952 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5953 goto posix_error;
5954
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005955#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5957 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005958#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005960#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005961#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005962#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005963
Victor Stinner8c62be82010-05-06 00:08:46 +00005964 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005965
Victor Stinnerdaf45552013-08-28 00:53:59 +02005966posix_error:
5967 posix_error();
5968error:
5969 if (master_fd != -1)
5970 close(master_fd);
5971 if (slave_fd != -1)
5972 close(slave_fd);
5973 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005974}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005975#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005976
Larry Hastings2f936352014-08-05 14:04:04 +10005977
Fred Drake8cef4cf2000-06-28 16:40:38 +00005978#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005979/*[clinic input]
5980os.forkpty
5981
5982Fork a new process with a new pseudo-terminal as controlling tty.
5983
5984Returns a tuple of (pid, master_fd).
5985Like fork(), return pid of 0 to the child process,
5986and pid of child to the parent process.
5987To both, return fd of newly opened pseudo-terminal.
5988[clinic start generated code]*/
5989
Larry Hastings2f936352014-08-05 14:04:04 +10005990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005991os_forkpty_impl(PyObject *module)
5992/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005993{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005994 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005996
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005997 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 pid = forkpty(&master_fd, NULL, NULL, NULL);
5999 if (pid == 0) {
6000 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006001 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 } else {
6003 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006004 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 }
6006 if (pid == -1)
6007 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006009}
Larry Hastings2f936352014-08-05 14:04:04 +10006010#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006011
Ross Lagerwall7807c352011-03-17 20:20:30 +02006012
Guido van Rossumad0ee831995-03-01 10:34:45 +00006013#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006014/*[clinic input]
6015os.getegid
6016
6017Return the current process's effective group id.
6018[clinic start generated code]*/
6019
Larry Hastings2f936352014-08-05 14:04:04 +10006020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006021os_getegid_impl(PyObject *module)
6022/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006023{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006024 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006025}
Larry Hastings2f936352014-08-05 14:04:04 +10006026#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006028
Guido van Rossumad0ee831995-03-01 10:34:45 +00006029#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006030/*[clinic input]
6031os.geteuid
6032
6033Return the current process's effective user id.
6034[clinic start generated code]*/
6035
Larry Hastings2f936352014-08-05 14:04:04 +10006036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006037os_geteuid_impl(PyObject *module)
6038/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006039{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006040 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006041}
Larry Hastings2f936352014-08-05 14:04:04 +10006042#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006044
Guido van Rossumad0ee831995-03-01 10:34:45 +00006045#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006046/*[clinic input]
6047os.getgid
6048
6049Return the current process's group id.
6050[clinic start generated code]*/
6051
Larry Hastings2f936352014-08-05 14:04:04 +10006052static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006053os_getgid_impl(PyObject *module)
6054/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006055{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006056 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006057}
Larry Hastings2f936352014-08-05 14:04:04 +10006058#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006060
Berker Peksag39404992016-09-15 20:45:16 +03006061#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006062/*[clinic input]
6063os.getpid
6064
6065Return the current process id.
6066[clinic start generated code]*/
6067
Larry Hastings2f936352014-08-05 14:04:04 +10006068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006069os_getpid_impl(PyObject *module)
6070/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006071{
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006073}
Berker Peksag39404992016-09-15 20:45:16 +03006074#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006075
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006076#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006077
6078/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006079PyDoc_STRVAR(posix_getgrouplist__doc__,
6080"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6081Returns a list of groups to which a user belongs.\n\n\
6082 user: username to lookup\n\
6083 group: base group id of the user");
6084
6085static PyObject *
6086posix_getgrouplist(PyObject *self, PyObject *args)
6087{
6088#ifdef NGROUPS_MAX
6089#define MAX_GROUPS NGROUPS_MAX
6090#else
6091 /* defined to be 16 on Solaris7, so this should be a small number */
6092#define MAX_GROUPS 64
6093#endif
6094
6095 const char *user;
6096 int i, ngroups;
6097 PyObject *list;
6098#ifdef __APPLE__
6099 int *groups, basegid;
6100#else
6101 gid_t *groups, basegid;
6102#endif
6103 ngroups = MAX_GROUPS;
6104
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006105#ifdef __APPLE__
6106 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006107 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006108#else
6109 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6110 _Py_Gid_Converter, &basegid))
6111 return NULL;
6112#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006113
6114#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006115 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006116#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006117 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006118#endif
6119 if (groups == NULL)
6120 return PyErr_NoMemory();
6121
6122 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6123 PyMem_Del(groups);
6124 return posix_error();
6125 }
6126
6127 list = PyList_New(ngroups);
6128 if (list == NULL) {
6129 PyMem_Del(groups);
6130 return NULL;
6131 }
6132
6133 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006134#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006135 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006136#else
6137 PyObject *o = _PyLong_FromGid(groups[i]);
6138#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006139 if (o == NULL) {
6140 Py_DECREF(list);
6141 PyMem_Del(groups);
6142 return NULL;
6143 }
6144 PyList_SET_ITEM(list, i, o);
6145 }
6146
6147 PyMem_Del(groups);
6148
6149 return list;
6150}
Larry Hastings2f936352014-08-05 14:04:04 +10006151#endif /* HAVE_GETGROUPLIST */
6152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006153
Fred Drakec9680921999-12-13 16:37:25 +00006154#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006155/*[clinic input]
6156os.getgroups
6157
6158Return list of supplemental group IDs for the process.
6159[clinic start generated code]*/
6160
Larry Hastings2f936352014-08-05 14:04:04 +10006161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006162os_getgroups_impl(PyObject *module)
6163/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006164{
6165 PyObject *result = NULL;
6166
Fred Drakec9680921999-12-13 16:37:25 +00006167#ifdef NGROUPS_MAX
6168#define MAX_GROUPS NGROUPS_MAX
6169#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006170 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006171#define MAX_GROUPS 64
6172#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006173 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006174
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006175 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006176 * This is a helper variable to store the intermediate result when
6177 * that happens.
6178 *
6179 * To keep the code readable the OSX behaviour is unconditional,
6180 * according to the POSIX spec this should be safe on all unix-y
6181 * systems.
6182 */
6183 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006184 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006185
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006186#ifdef __APPLE__
6187 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6188 * there are more groups than can fit in grouplist. Therefore, on OS X
6189 * always first call getgroups with length 0 to get the actual number
6190 * of groups.
6191 */
6192 n = getgroups(0, NULL);
6193 if (n < 0) {
6194 return posix_error();
6195 } else if (n <= MAX_GROUPS) {
6196 /* groups will fit in existing array */
6197 alt_grouplist = grouplist;
6198 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006199 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006200 if (alt_grouplist == NULL) {
6201 errno = EINVAL;
6202 return posix_error();
6203 }
6204 }
6205
6206 n = getgroups(n, alt_grouplist);
6207 if (n == -1) {
6208 if (alt_grouplist != grouplist) {
6209 PyMem_Free(alt_grouplist);
6210 }
6211 return posix_error();
6212 }
6213#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006214 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006215 if (n < 0) {
6216 if (errno == EINVAL) {
6217 n = getgroups(0, NULL);
6218 if (n == -1) {
6219 return posix_error();
6220 }
6221 if (n == 0) {
6222 /* Avoid malloc(0) */
6223 alt_grouplist = grouplist;
6224 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006225 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006226 if (alt_grouplist == NULL) {
6227 errno = EINVAL;
6228 return posix_error();
6229 }
6230 n = getgroups(n, alt_grouplist);
6231 if (n == -1) {
6232 PyMem_Free(alt_grouplist);
6233 return posix_error();
6234 }
6235 }
6236 } else {
6237 return posix_error();
6238 }
6239 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006240#endif
6241
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006242 result = PyList_New(n);
6243 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006244 int i;
6245 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006246 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006248 Py_DECREF(result);
6249 result = NULL;
6250 break;
Fred Drakec9680921999-12-13 16:37:25 +00006251 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006253 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006254 }
6255
6256 if (alt_grouplist != grouplist) {
6257 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006259
Fred Drakec9680921999-12-13 16:37:25 +00006260 return result;
6261}
Larry Hastings2f936352014-08-05 14:04:04 +10006262#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006263
Antoine Pitroub7572f02009-12-02 20:46:48 +00006264#ifdef HAVE_INITGROUPS
6265PyDoc_STRVAR(posix_initgroups__doc__,
6266"initgroups(username, gid) -> None\n\n\
6267Call the system initgroups() to initialize the group access list with all of\n\
6268the groups of which the specified username is a member, plus the specified\n\
6269group id.");
6270
Larry Hastings2f936352014-08-05 14:04:04 +10006271/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006272static PyObject *
6273posix_initgroups(PyObject *self, PyObject *args)
6274{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006275 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006276 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006277 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006278#ifdef __APPLE__
6279 int gid;
6280#else
6281 gid_t gid;
6282#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006283
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006284#ifdef __APPLE__
6285 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6286 PyUnicode_FSConverter, &oname,
6287 &gid))
6288#else
6289 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6290 PyUnicode_FSConverter, &oname,
6291 _Py_Gid_Converter, &gid))
6292#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006294 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006295
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006296 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006297 Py_DECREF(oname);
6298 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006300
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006301 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006302}
Larry Hastings2f936352014-08-05 14:04:04 +10006303#endif /* HAVE_INITGROUPS */
6304
Antoine Pitroub7572f02009-12-02 20:46:48 +00006305
Martin v. Löwis606edc12002-06-13 21:09:11 +00006306#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006307/*[clinic input]
6308os.getpgid
6309
6310 pid: pid_t
6311
6312Call the system call getpgid(), and return the result.
6313[clinic start generated code]*/
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006316os_getpgid_impl(PyObject *module, pid_t pid)
6317/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006318{
6319 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 if (pgid < 0)
6321 return posix_error();
6322 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006323}
6324#endif /* HAVE_GETPGID */
6325
6326
Guido van Rossumb6775db1994-08-01 11:34:53 +00006327#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006328/*[clinic input]
6329os.getpgrp
6330
6331Return the current process group id.
6332[clinic start generated code]*/
6333
Larry Hastings2f936352014-08-05 14:04:04 +10006334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006335os_getpgrp_impl(PyObject *module)
6336/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006337{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006338#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006340#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006342#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006343}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006344#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006346
Guido van Rossumb6775db1994-08-01 11:34:53 +00006347#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006348/*[clinic input]
6349os.setpgrp
6350
6351Make the current process the leader of its process group.
6352[clinic start generated code]*/
6353
Larry Hastings2f936352014-08-05 14:04:04 +10006354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006355os_setpgrp_impl(PyObject *module)
6356/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006357{
Guido van Rossum64933891994-10-20 21:56:42 +00006358#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006360#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006362#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006364 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006365}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006366#endif /* HAVE_SETPGRP */
6367
Guido van Rossumad0ee831995-03-01 10:34:45 +00006368#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006369
6370#ifdef MS_WINDOWS
6371#include <tlhelp32.h>
6372
6373static PyObject*
6374win32_getppid()
6375{
6376 HANDLE snapshot;
6377 pid_t mypid;
6378 PyObject* result = NULL;
6379 BOOL have_record;
6380 PROCESSENTRY32 pe;
6381
6382 mypid = getpid(); /* This function never fails */
6383
6384 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6385 if (snapshot == INVALID_HANDLE_VALUE)
6386 return PyErr_SetFromWindowsErr(GetLastError());
6387
6388 pe.dwSize = sizeof(pe);
6389 have_record = Process32First(snapshot, &pe);
6390 while (have_record) {
6391 if (mypid == (pid_t)pe.th32ProcessID) {
6392 /* We could cache the ulong value in a static variable. */
6393 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6394 break;
6395 }
6396
6397 have_record = Process32Next(snapshot, &pe);
6398 }
6399
6400 /* If our loop exits and our pid was not found (result will be NULL)
6401 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6402 * error anyway, so let's raise it. */
6403 if (!result)
6404 result = PyErr_SetFromWindowsErr(GetLastError());
6405
6406 CloseHandle(snapshot);
6407
6408 return result;
6409}
6410#endif /*MS_WINDOWS*/
6411
Larry Hastings2f936352014-08-05 14:04:04 +10006412
6413/*[clinic input]
6414os.getppid
6415
6416Return the parent's process id.
6417
6418If the parent process has already exited, Windows machines will still
6419return its id; others systems will return the id of the 'init' process (1).
6420[clinic start generated code]*/
6421
Larry Hastings2f936352014-08-05 14:04:04 +10006422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006423os_getppid_impl(PyObject *module)
6424/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006425{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006426#ifdef MS_WINDOWS
6427 return win32_getppid();
6428#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006430#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006431}
6432#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006433
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006434
Fred Drake12c6e2d1999-12-14 21:25:03 +00006435#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006436/*[clinic input]
6437os.getlogin
6438
6439Return the actual login name.
6440[clinic start generated code]*/
6441
Larry Hastings2f936352014-08-05 14:04:04 +10006442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006443os_getlogin_impl(PyObject *module)
6444/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006445{
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006447#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006448 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006449 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006450
6451 if (GetUserNameW(user_name, &num_chars)) {
6452 /* num_chars is the number of unicode chars plus null terminator */
6453 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006454 }
6455 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006456 result = PyErr_SetFromWindowsErr(GetLastError());
6457#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 char *name;
6459 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006460
Victor Stinner8c62be82010-05-06 00:08:46 +00006461 errno = 0;
6462 name = getlogin();
6463 if (name == NULL) {
6464 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006465 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006466 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006467 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 }
6469 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006470 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006471 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006472#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006473 return result;
6474}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006475#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006476
Larry Hastings2f936352014-08-05 14:04:04 +10006477
Guido van Rossumad0ee831995-03-01 10:34:45 +00006478#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006479/*[clinic input]
6480os.getuid
6481
6482Return the current process's user id.
6483[clinic start generated code]*/
6484
Larry Hastings2f936352014-08-05 14:04:04 +10006485static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006486os_getuid_impl(PyObject *module)
6487/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006488{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006489 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006490}
Larry Hastings2f936352014-08-05 14:04:04 +10006491#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006493
Brian Curtineb24d742010-04-12 17:16:38 +00006494#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006495#define HAVE_KILL
6496#endif /* MS_WINDOWS */
6497
6498#ifdef HAVE_KILL
6499/*[clinic input]
6500os.kill
6501
6502 pid: pid_t
6503 signal: Py_ssize_t
6504 /
6505
6506Kill a process with a signal.
6507[clinic start generated code]*/
6508
Larry Hastings2f936352014-08-05 14:04:04 +10006509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006510os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6511/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006512#ifndef MS_WINDOWS
6513{
6514 if (kill(pid, (int)signal) == -1)
6515 return posix_error();
6516 Py_RETURN_NONE;
6517}
6518#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006519{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006520 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006521 DWORD sig = (DWORD)signal;
6522 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006524
Victor Stinner8c62be82010-05-06 00:08:46 +00006525 /* Console processes which share a common console can be sent CTRL+C or
6526 CTRL+BREAK events, provided they handle said events. */
6527 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006528 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 err = GetLastError();
6530 PyErr_SetFromWindowsErr(err);
6531 }
6532 else
6533 Py_RETURN_NONE;
6534 }
Brian Curtineb24d742010-04-12 17:16:38 +00006535
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6537 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006538 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 if (handle == NULL) {
6540 err = GetLastError();
6541 return PyErr_SetFromWindowsErr(err);
6542 }
Brian Curtineb24d742010-04-12 17:16:38 +00006543
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 if (TerminateProcess(handle, sig) == 0) {
6545 err = GetLastError();
6546 result = PyErr_SetFromWindowsErr(err);
6547 } else {
6548 Py_INCREF(Py_None);
6549 result = Py_None;
6550 }
Brian Curtineb24d742010-04-12 17:16:38 +00006551
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 CloseHandle(handle);
6553 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006554}
Larry Hastings2f936352014-08-05 14:04:04 +10006555#endif /* !MS_WINDOWS */
6556#endif /* HAVE_KILL */
6557
6558
6559#ifdef HAVE_KILLPG
6560/*[clinic input]
6561os.killpg
6562
6563 pgid: pid_t
6564 signal: int
6565 /
6566
6567Kill a process group with a signal.
6568[clinic start generated code]*/
6569
Larry Hastings2f936352014-08-05 14:04:04 +10006570static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006571os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6572/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006573{
6574 /* XXX some man pages make the `pgid` parameter an int, others
6575 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6576 take the same type. Moreover, pid_t is always at least as wide as
6577 int (else compilation of this module fails), which is safe. */
6578 if (killpg(pgid, signal) == -1)
6579 return posix_error();
6580 Py_RETURN_NONE;
6581}
6582#endif /* HAVE_KILLPG */
6583
Brian Curtineb24d742010-04-12 17:16:38 +00006584
Guido van Rossumc0125471996-06-28 18:55:32 +00006585#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006586#ifdef HAVE_SYS_LOCK_H
6587#include <sys/lock.h>
6588#endif
6589
Larry Hastings2f936352014-08-05 14:04:04 +10006590/*[clinic input]
6591os.plock
6592 op: int
6593 /
6594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006595Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006596[clinic start generated code]*/
6597
Larry Hastings2f936352014-08-05 14:04:04 +10006598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006599os_plock_impl(PyObject *module, int op)
6600/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006601{
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 if (plock(op) == -1)
6603 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006604 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006605}
Larry Hastings2f936352014-08-05 14:04:04 +10006606#endif /* HAVE_PLOCK */
6607
Guido van Rossumc0125471996-06-28 18:55:32 +00006608
Guido van Rossumb6775db1994-08-01 11:34:53 +00006609#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006610/*[clinic input]
6611os.setuid
6612
6613 uid: uid_t
6614 /
6615
6616Set the current process's user id.
6617[clinic start generated code]*/
6618
Larry Hastings2f936352014-08-05 14:04:04 +10006619static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006620os_setuid_impl(PyObject *module, uid_t uid)
6621/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006622{
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 if (setuid(uid) < 0)
6624 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006625 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006626}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006627#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006629
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006630#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006631/*[clinic input]
6632os.seteuid
6633
6634 euid: uid_t
6635 /
6636
6637Set the current process's effective user id.
6638[clinic start generated code]*/
6639
Larry Hastings2f936352014-08-05 14:04:04 +10006640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006641os_seteuid_impl(PyObject *module, uid_t euid)
6642/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006643{
6644 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006645 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006646 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006647}
6648#endif /* HAVE_SETEUID */
6649
Larry Hastings2f936352014-08-05 14:04:04 +10006650
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006651#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006652/*[clinic input]
6653os.setegid
6654
6655 egid: gid_t
6656 /
6657
6658Set the current process's effective group id.
6659[clinic start generated code]*/
6660
Larry Hastings2f936352014-08-05 14:04:04 +10006661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006662os_setegid_impl(PyObject *module, gid_t egid)
6663/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006664{
6665 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006666 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006667 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006668}
6669#endif /* HAVE_SETEGID */
6670
Larry Hastings2f936352014-08-05 14:04:04 +10006671
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006672#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006673/*[clinic input]
6674os.setreuid
6675
6676 ruid: uid_t
6677 euid: uid_t
6678 /
6679
6680Set the current process's real and effective user ids.
6681[clinic start generated code]*/
6682
Larry Hastings2f936352014-08-05 14:04:04 +10006683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006684os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6685/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006686{
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 if (setreuid(ruid, euid) < 0) {
6688 return posix_error();
6689 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006690 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006692}
6693#endif /* HAVE_SETREUID */
6694
Larry Hastings2f936352014-08-05 14:04:04 +10006695
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006696#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006697/*[clinic input]
6698os.setregid
6699
6700 rgid: gid_t
6701 egid: gid_t
6702 /
6703
6704Set the current process's real and effective group ids.
6705[clinic start generated code]*/
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006708os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6709/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006710{
6711 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006713 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006714}
6715#endif /* HAVE_SETREGID */
6716
Larry Hastings2f936352014-08-05 14:04:04 +10006717
Guido van Rossumb6775db1994-08-01 11:34:53 +00006718#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006719/*[clinic input]
6720os.setgid
6721 gid: gid_t
6722 /
6723
6724Set the current process's group id.
6725[clinic start generated code]*/
6726
Larry Hastings2f936352014-08-05 14:04:04 +10006727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006728os_setgid_impl(PyObject *module, gid_t gid)
6729/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006730{
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 if (setgid(gid) < 0)
6732 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006733 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006734}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006735#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006736
Larry Hastings2f936352014-08-05 14:04:04 +10006737
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006738#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006739/*[clinic input]
6740os.setgroups
6741
6742 groups: object
6743 /
6744
6745Set the groups of the current process to list.
6746[clinic start generated code]*/
6747
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006748static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006749os_setgroups(PyObject *module, PyObject *groups)
6750/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006751{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006752 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006754
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 if (!PySequence_Check(groups)) {
6756 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6757 return NULL;
6758 }
6759 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006760 if (len < 0) {
6761 return NULL;
6762 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 if (len > MAX_GROUPS) {
6764 PyErr_SetString(PyExc_ValueError, "too many groups");
6765 return NULL;
6766 }
6767 for(i = 0; i < len; i++) {
6768 PyObject *elem;
6769 elem = PySequence_GetItem(groups, i);
6770 if (!elem)
6771 return NULL;
6772 if (!PyLong_Check(elem)) {
6773 PyErr_SetString(PyExc_TypeError,
6774 "groups must be integers");
6775 Py_DECREF(elem);
6776 return NULL;
6777 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006778 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 Py_DECREF(elem);
6780 return NULL;
6781 }
6782 }
6783 Py_DECREF(elem);
6784 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006785
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 if (setgroups(len, grouplist) < 0)
6787 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006788 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006789}
6790#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006791
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006792#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6793static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006794wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006795{
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 PyObject *result;
6797 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006798 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006799
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 if (pid == -1)
6801 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006802
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 if (struct_rusage == NULL) {
6804 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6805 if (m == NULL)
6806 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006807 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 Py_DECREF(m);
6809 if (struct_rusage == NULL)
6810 return NULL;
6811 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006812
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6814 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6815 if (!result)
6816 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006817
6818#ifndef doubletime
6819#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6820#endif
6821
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006823 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006825 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006826#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6828 SET_INT(result, 2, ru->ru_maxrss);
6829 SET_INT(result, 3, ru->ru_ixrss);
6830 SET_INT(result, 4, ru->ru_idrss);
6831 SET_INT(result, 5, ru->ru_isrss);
6832 SET_INT(result, 6, ru->ru_minflt);
6833 SET_INT(result, 7, ru->ru_majflt);
6834 SET_INT(result, 8, ru->ru_nswap);
6835 SET_INT(result, 9, ru->ru_inblock);
6836 SET_INT(result, 10, ru->ru_oublock);
6837 SET_INT(result, 11, ru->ru_msgsnd);
6838 SET_INT(result, 12, ru->ru_msgrcv);
6839 SET_INT(result, 13, ru->ru_nsignals);
6840 SET_INT(result, 14, ru->ru_nvcsw);
6841 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842#undef SET_INT
6843
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 if (PyErr_Occurred()) {
6845 Py_DECREF(result);
6846 return NULL;
6847 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006848
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006850}
6851#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6852
Larry Hastings2f936352014-08-05 14:04:04 +10006853
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006854#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006855/*[clinic input]
6856os.wait3
6857
6858 options: int
6859Wait for completion of a child process.
6860
6861Returns a tuple of information about the child process:
6862 (pid, status, rusage)
6863[clinic start generated code]*/
6864
Larry Hastings2f936352014-08-05 14:04:04 +10006865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006866os_wait3_impl(PyObject *module, int options)
6867/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868{
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006871 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 WAIT_TYPE status;
6873 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006875 do {
6876 Py_BEGIN_ALLOW_THREADS
6877 pid = wait3(&status, options, &ru);
6878 Py_END_ALLOW_THREADS
6879 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6880 if (pid < 0)
6881 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882
Victor Stinner4195b5c2012-02-08 23:03:19 +01006883 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006884}
6885#endif /* HAVE_WAIT3 */
6886
Larry Hastings2f936352014-08-05 14:04:04 +10006887
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006889/*[clinic input]
6890
6891os.wait4
6892
6893 pid: pid_t
6894 options: int
6895
6896Wait for completion of a specific child process.
6897
6898Returns a tuple of information about the child process:
6899 (pid, status, rusage)
6900[clinic start generated code]*/
6901
Larry Hastings2f936352014-08-05 14:04:04 +10006902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006903os_wait4_impl(PyObject *module, pid_t pid, int options)
6904/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006905{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006906 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006908 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 WAIT_TYPE status;
6910 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006912 do {
6913 Py_BEGIN_ALLOW_THREADS
6914 res = wait4(pid, &status, options, &ru);
6915 Py_END_ALLOW_THREADS
6916 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6917 if (res < 0)
6918 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006919
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006920 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921}
6922#endif /* HAVE_WAIT4 */
6923
Larry Hastings2f936352014-08-05 14:04:04 +10006924
Ross Lagerwall7807c352011-03-17 20:20:30 +02006925#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006926/*[clinic input]
6927os.waitid
6928
6929 idtype: idtype_t
6930 Must be one of be P_PID, P_PGID or P_ALL.
6931 id: id_t
6932 The id to wait on.
6933 options: int
6934 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6935 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6936 /
6937
6938Returns the result of waiting for a process or processes.
6939
6940Returns either waitid_result or None if WNOHANG is specified and there are
6941no children in a waitable state.
6942[clinic start generated code]*/
6943
Larry Hastings2f936352014-08-05 14:04:04 +10006944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006945os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6946/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006947{
6948 PyObject *result;
6949 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006950 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006951 siginfo_t si;
6952 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006953
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006954 do {
6955 Py_BEGIN_ALLOW_THREADS
6956 res = waitid(idtype, id, &si, options);
6957 Py_END_ALLOW_THREADS
6958 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6959 if (res < 0)
6960 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006961
6962 if (si.si_pid == 0)
6963 Py_RETURN_NONE;
6964
6965 result = PyStructSequence_New(&WaitidResultType);
6966 if (!result)
6967 return NULL;
6968
6969 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006970 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006971 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6972 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6973 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6974 if (PyErr_Occurred()) {
6975 Py_DECREF(result);
6976 return NULL;
6977 }
6978
6979 return result;
6980}
Larry Hastings2f936352014-08-05 14:04:04 +10006981#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006982
Larry Hastings2f936352014-08-05 14:04:04 +10006983
6984#if defined(HAVE_WAITPID)
6985/*[clinic input]
6986os.waitpid
6987 pid: pid_t
6988 options: int
6989 /
6990
6991Wait for completion of a given child process.
6992
6993Returns a tuple of information regarding the child process:
6994 (pid, status)
6995
6996The options argument is ignored on Windows.
6997[clinic start generated code]*/
6998
Larry Hastings2f936352014-08-05 14:04:04 +10006999static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007000os_waitpid_impl(PyObject *module, pid_t pid, int options)
7001/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007002{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007003 pid_t res;
7004 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 WAIT_TYPE status;
7006 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007007
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007008 do {
7009 Py_BEGIN_ALLOW_THREADS
7010 res = waitpid(pid, &status, options);
7011 Py_END_ALLOW_THREADS
7012 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7013 if (res < 0)
7014 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007015
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007016 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007017}
Tim Petersab034fa2002-02-01 11:27:43 +00007018#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007019/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007020/*[clinic input]
7021os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007022 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007023 options: int
7024 /
7025
7026Wait for completion of a given process.
7027
7028Returns a tuple of information regarding the process:
7029 (pid, status << 8)
7030
7031The options argument is ignored on Windows.
7032[clinic start generated code]*/
7033
Larry Hastings2f936352014-08-05 14:04:04 +10007034static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007035os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007036/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007037{
7038 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007039 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007040 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007041
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007042 do {
7043 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007044 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007045 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007046 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007047 Py_END_ALLOW_THREADS
7048 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007049 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007050 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007051
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007053 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007054}
Larry Hastings2f936352014-08-05 14:04:04 +10007055#endif
7056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007057
Guido van Rossumad0ee831995-03-01 10:34:45 +00007058#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007059/*[clinic input]
7060os.wait
7061
7062Wait for completion of a child process.
7063
7064Returns a tuple of information about the child process:
7065 (pid, status)
7066[clinic start generated code]*/
7067
Larry Hastings2f936352014-08-05 14:04:04 +10007068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007069os_wait_impl(PyObject *module)
7070/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007071{
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007073 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007074 WAIT_TYPE status;
7075 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007076
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007077 do {
7078 Py_BEGIN_ALLOW_THREADS
7079 pid = wait(&status);
7080 Py_END_ALLOW_THREADS
7081 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7082 if (pid < 0)
7083 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007084
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007086}
Larry Hastings2f936352014-08-05 14:04:04 +10007087#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007089
Larry Hastings9cf065c2012-06-22 16:30:09 -07007090#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7091PyDoc_STRVAR(readlink__doc__,
7092"readlink(path, *, dir_fd=None) -> path\n\n\
7093Return a string representing the path to which the symbolic link points.\n\
7094\n\
7095If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7096 and path should be relative; path will then be relative to that directory.\n\
7097dir_fd may not be implemented on your platform.\n\
7098 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007099#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007100
Guido van Rossumb6775db1994-08-01 11:34:53 +00007101#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007102
Larry Hastings2f936352014-08-05 14:04:04 +10007103/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007104static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007106{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007107 path_t path;
7108 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007109 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007110 ssize_t length;
7111 PyObject *return_value = NULL;
7112 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007113
Larry Hastings9cf065c2012-06-22 16:30:09 -07007114 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007115 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7117 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007118 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007119 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007120
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122#ifdef HAVE_READLINKAT
7123 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007124 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007125 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007127 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128 Py_END_ALLOW_THREADS
7129
7130 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007131 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007132 goto exit;
7133 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007134 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135
7136 if (PyUnicode_Check(path.object))
7137 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7138 else
7139 return_value = PyBytes_FromStringAndSize(buffer, length);
7140exit:
7141 path_cleanup(&path);
7142 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007143}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007144
Guido van Rossumb6775db1994-08-01 11:34:53 +00007145#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007146
Larry Hastings2f936352014-08-05 14:04:04 +10007147#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7148
7149static PyObject *
7150win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7151{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007152 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007153 DWORD n_bytes_returned;
7154 DWORD io_result;
7155 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007156 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007157 HANDLE reparse_point_handle;
7158
Martin Panter70214ad2016-08-04 02:38:59 +00007159 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7160 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007161 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007162
7163 static char *keywords[] = {"path", "dir_fd", NULL};
7164
7165 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7166 &po,
7167 dir_fd_unavailable, &dir_fd
7168 ))
7169 return NULL;
7170
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007171 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007172 if (path == NULL)
7173 return NULL;
7174
7175 /* First get a handle to the reparse point */
7176 Py_BEGIN_ALLOW_THREADS
7177 reparse_point_handle = CreateFileW(
7178 path,
7179 0,
7180 0,
7181 0,
7182 OPEN_EXISTING,
7183 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7184 0);
7185 Py_END_ALLOW_THREADS
7186
7187 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7188 return win32_error_object("readlink", po);
7189
7190 Py_BEGIN_ALLOW_THREADS
7191 /* New call DeviceIoControl to read the reparse point */
7192 io_result = DeviceIoControl(
7193 reparse_point_handle,
7194 FSCTL_GET_REPARSE_POINT,
7195 0, 0, /* in buffer */
7196 target_buffer, sizeof(target_buffer),
7197 &n_bytes_returned,
7198 0 /* we're not using OVERLAPPED_IO */
7199 );
7200 CloseHandle(reparse_point_handle);
7201 Py_END_ALLOW_THREADS
7202
7203 if (io_result==0)
7204 return win32_error_object("readlink", po);
7205
7206 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7207 {
7208 PyErr_SetString(PyExc_ValueError,
7209 "not a symbolic link");
7210 return NULL;
7211 }
7212 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7213 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7214
7215 result = PyUnicode_FromWideChar(print_name,
7216 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7217 return result;
7218}
7219
7220#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7221
7222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007223
Larry Hastings9cf065c2012-06-22 16:30:09 -07007224#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007225
7226#if defined(MS_WINDOWS)
7227
7228/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007229static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007230
Larry Hastings9cf065c2012-06-22 16:30:09 -07007231static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007232check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007233{
7234 HINSTANCE hKernel32;
7235 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007236 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007237 return 1;
7238 hKernel32 = GetModuleHandleW(L"KERNEL32");
7239 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7240 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007241 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007242}
7243
Victor Stinner31b3b922013-06-05 01:49:17 +02007244/* Remove the last portion of the path */
7245static void
7246_dirnameW(WCHAR *path)
7247{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007248 WCHAR *ptr;
7249
7250 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007251 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007252 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007253 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254 }
7255 *ptr = 0;
7256}
7257
Victor Stinner31b3b922013-06-05 01:49:17 +02007258/* Is this path absolute? */
7259static int
7260_is_absW(const WCHAR *path)
7261{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007262 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7263
7264}
7265
Victor Stinner31b3b922013-06-05 01:49:17 +02007266/* join root and rest with a backslash */
7267static void
7268_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7269{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007270 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007271
Victor Stinner31b3b922013-06-05 01:49:17 +02007272 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007273 wcscpy(dest_path, rest);
7274 return;
7275 }
7276
7277 root_len = wcslen(root);
7278
7279 wcscpy(dest_path, root);
7280 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007281 dest_path[root_len] = L'\\';
7282 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007283 }
7284 wcscpy(dest_path+root_len, rest);
7285}
7286
Victor Stinner31b3b922013-06-05 01:49:17 +02007287/* Return True if the path at src relative to dest is a directory */
7288static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007289_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007290{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291 WIN32_FILE_ATTRIBUTE_DATA src_info;
7292 WCHAR dest_parent[MAX_PATH];
7293 WCHAR src_resolved[MAX_PATH] = L"";
7294
7295 /* dest_parent = os.path.dirname(dest) */
7296 wcscpy(dest_parent, dest);
7297 _dirnameW(dest_parent);
7298 /* src_resolved = os.path.join(dest_parent, src) */
7299 _joinW(src_resolved, dest_parent, src);
7300 return (
7301 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7302 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7303 );
7304}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007305#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007306
Larry Hastings2f936352014-08-05 14:04:04 +10007307
7308/*[clinic input]
7309os.symlink
7310 src: path_t
7311 dst: path_t
7312 target_is_directory: bool = False
7313 *
7314 dir_fd: dir_fd(requires='symlinkat')=None
7315
7316# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7317
7318Create a symbolic link pointing to src named dst.
7319
7320target_is_directory is required on Windows if the target is to be
7321 interpreted as a directory. (On Windows, symlink requires
7322 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7323 target_is_directory is ignored on non-Windows platforms.
7324
7325If dir_fd is not None, it should be a file descriptor open to a directory,
7326 and path should be relative; path will then be relative to that directory.
7327dir_fd may not be implemented on your platform.
7328 If it is unavailable, using it will raise a NotImplementedError.
7329
7330[clinic start generated code]*/
7331
Larry Hastings2f936352014-08-05 14:04:04 +10007332static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007333os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007334 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007335/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007336{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007337#ifdef MS_WINDOWS
7338 DWORD result;
7339#else
7340 int result;
7341#endif
7342
Larry Hastings9cf065c2012-06-22 16:30:09 -07007343#ifdef MS_WINDOWS
7344 if (!check_CreateSymbolicLink()) {
7345 PyErr_SetString(PyExc_NotImplementedError,
7346 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007347 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007348 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007349 if (!win32_can_symlink) {
7350 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007351 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007352 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007353#endif
7354
Larry Hastings2f936352014-08-05 14:04:04 +10007355 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007356 PyErr_SetString(PyExc_ValueError,
7357 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007358 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007359 }
7360
7361#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007362
Larry Hastings9cf065c2012-06-22 16:30:09 -07007363 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007364 /* if src is a directory, ensure target_is_directory==1 */
7365 target_is_directory |= _check_dirW(src->wide, dst->wide);
7366 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7367 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007368 Py_END_ALLOW_THREADS
7369
Larry Hastings2f936352014-08-05 14:04:04 +10007370 if (!result)
7371 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007372
7373#else
7374
7375 Py_BEGIN_ALLOW_THREADS
7376#if HAVE_SYMLINKAT
7377 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007378 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007379 else
7380#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007381 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007382 Py_END_ALLOW_THREADS
7383
Larry Hastings2f936352014-08-05 14:04:04 +10007384 if (result)
7385 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386#endif
7387
Larry Hastings2f936352014-08-05 14:04:04 +10007388 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007389}
7390#endif /* HAVE_SYMLINK */
7391
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392
Brian Curtind40e6f72010-07-08 21:39:08 +00007393
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007394
Larry Hastings605a62d2012-06-24 04:33:36 -07007395static PyStructSequence_Field times_result_fields[] = {
7396 {"user", "user time"},
7397 {"system", "system time"},
7398 {"children_user", "user time of children"},
7399 {"children_system", "system time of children"},
7400 {"elapsed", "elapsed time since an arbitrary point in the past"},
7401 {NULL}
7402};
7403
7404PyDoc_STRVAR(times_result__doc__,
7405"times_result: Result from os.times().\n\n\
7406This object may be accessed either as a tuple of\n\
7407 (user, system, children_user, children_system, elapsed),\n\
7408or via the attributes user, system, children_user, children_system,\n\
7409and elapsed.\n\
7410\n\
7411See os.times for more information.");
7412
7413static PyStructSequence_Desc times_result_desc = {
7414 "times_result", /* name */
7415 times_result__doc__, /* doc */
7416 times_result_fields,
7417 5
7418};
7419
7420static PyTypeObject TimesResultType;
7421
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007422#ifdef MS_WINDOWS
7423#define HAVE_TIMES /* mandatory, for the method table */
7424#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007425
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007426#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007427
7428static PyObject *
7429build_times_result(double user, double system,
7430 double children_user, double children_system,
7431 double elapsed)
7432{
7433 PyObject *value = PyStructSequence_New(&TimesResultType);
7434 if (value == NULL)
7435 return NULL;
7436
7437#define SET(i, field) \
7438 { \
7439 PyObject *o = PyFloat_FromDouble(field); \
7440 if (!o) { \
7441 Py_DECREF(value); \
7442 return NULL; \
7443 } \
7444 PyStructSequence_SET_ITEM(value, i, o); \
7445 } \
7446
7447 SET(0, user);
7448 SET(1, system);
7449 SET(2, children_user);
7450 SET(3, children_system);
7451 SET(4, elapsed);
7452
7453#undef SET
7454
7455 return value;
7456}
7457
Larry Hastings605a62d2012-06-24 04:33:36 -07007458
Larry Hastings2f936352014-08-05 14:04:04 +10007459#ifndef MS_WINDOWS
7460#define NEED_TICKS_PER_SECOND
7461static long ticks_per_second = -1;
7462#endif /* MS_WINDOWS */
7463
7464/*[clinic input]
7465os.times
7466
7467Return a collection containing process timing information.
7468
7469The object returned behaves like a named tuple with these fields:
7470 (utime, stime, cutime, cstime, elapsed_time)
7471All fields are floating point numbers.
7472[clinic start generated code]*/
7473
Larry Hastings2f936352014-08-05 14:04:04 +10007474static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007475os_times_impl(PyObject *module)
7476/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007477#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007478{
Victor Stinner8c62be82010-05-06 00:08:46 +00007479 FILETIME create, exit, kernel, user;
7480 HANDLE hProc;
7481 hProc = GetCurrentProcess();
7482 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7483 /* The fields of a FILETIME structure are the hi and lo part
7484 of a 64-bit value expressed in 100 nanosecond units.
7485 1e7 is one second in such units; 1e-7 the inverse.
7486 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7487 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007488 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007489 (double)(user.dwHighDateTime*429.4967296 +
7490 user.dwLowDateTime*1e-7),
7491 (double)(kernel.dwHighDateTime*429.4967296 +
7492 kernel.dwLowDateTime*1e-7),
7493 (double)0,
7494 (double)0,
7495 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007496}
Larry Hastings2f936352014-08-05 14:04:04 +10007497#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007498{
Larry Hastings2f936352014-08-05 14:04:04 +10007499
7500
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007501 struct tms t;
7502 clock_t c;
7503 errno = 0;
7504 c = times(&t);
7505 if (c == (clock_t) -1)
7506 return posix_error();
7507 return build_times_result(
7508 (double)t.tms_utime / ticks_per_second,
7509 (double)t.tms_stime / ticks_per_second,
7510 (double)t.tms_cutime / ticks_per_second,
7511 (double)t.tms_cstime / ticks_per_second,
7512 (double)c / ticks_per_second);
7513}
Larry Hastings2f936352014-08-05 14:04:04 +10007514#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007515#endif /* HAVE_TIMES */
7516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007517
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007518#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007519/*[clinic input]
7520os.getsid
7521
7522 pid: pid_t
7523 /
7524
7525Call the system call getsid(pid) and return the result.
7526[clinic start generated code]*/
7527
Larry Hastings2f936352014-08-05 14:04:04 +10007528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007529os_getsid_impl(PyObject *module, pid_t pid)
7530/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007531{
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 sid = getsid(pid);
7534 if (sid < 0)
7535 return posix_error();
7536 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007537}
7538#endif /* HAVE_GETSID */
7539
7540
Guido van Rossumb6775db1994-08-01 11:34:53 +00007541#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007542/*[clinic input]
7543os.setsid
7544
7545Call the system call setsid().
7546[clinic start generated code]*/
7547
Larry Hastings2f936352014-08-05 14:04:04 +10007548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007549os_setsid_impl(PyObject *module)
7550/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007551{
Victor Stinner8c62be82010-05-06 00:08:46 +00007552 if (setsid() < 0)
7553 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007554 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007555}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007556#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007557
Larry Hastings2f936352014-08-05 14:04:04 +10007558
Guido van Rossumb6775db1994-08-01 11:34:53 +00007559#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007560/*[clinic input]
7561os.setpgid
7562
7563 pid: pid_t
7564 pgrp: pid_t
7565 /
7566
7567Call the system call setpgid(pid, pgrp).
7568[clinic start generated code]*/
7569
Larry Hastings2f936352014-08-05 14:04:04 +10007570static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007571os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7572/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007573{
Victor Stinner8c62be82010-05-06 00:08:46 +00007574 if (setpgid(pid, pgrp) < 0)
7575 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007576 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007577}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007578#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007580
Guido van Rossumb6775db1994-08-01 11:34:53 +00007581#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007582/*[clinic input]
7583os.tcgetpgrp
7584
7585 fd: int
7586 /
7587
7588Return the process group associated with the terminal specified by fd.
7589[clinic start generated code]*/
7590
Larry Hastings2f936352014-08-05 14:04:04 +10007591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007592os_tcgetpgrp_impl(PyObject *module, int fd)
7593/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007594{
7595 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007596 if (pgid < 0)
7597 return posix_error();
7598 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007599}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007600#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007602
Guido van Rossumb6775db1994-08-01 11:34:53 +00007603#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007604/*[clinic input]
7605os.tcsetpgrp
7606
7607 fd: int
7608 pgid: pid_t
7609 /
7610
7611Set the process group associated with the terminal specified by fd.
7612[clinic start generated code]*/
7613
Larry Hastings2f936352014-08-05 14:04:04 +10007614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007615os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7616/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007617{
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 if (tcsetpgrp(fd, pgid) < 0)
7619 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007620 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007621}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007622#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007623
Guido van Rossum687dd131993-05-17 08:34:16 +00007624/* Functions acting on file descriptors */
7625
Victor Stinnerdaf45552013-08-28 00:53:59 +02007626#ifdef O_CLOEXEC
7627extern int _Py_open_cloexec_works;
7628#endif
7629
Larry Hastings2f936352014-08-05 14:04:04 +10007630
7631/*[clinic input]
7632os.open -> int
7633 path: path_t
7634 flags: int
7635 mode: int = 0o777
7636 *
7637 dir_fd: dir_fd(requires='openat') = None
7638
7639# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7640
7641Open a file for low level IO. Returns a file descriptor (integer).
7642
7643If dir_fd is not None, it should be a file descriptor open to a directory,
7644 and path should be relative; path will then be relative to that directory.
7645dir_fd may not be implemented on your platform.
7646 If it is unavailable, using it will raise a NotImplementedError.
7647[clinic start generated code]*/
7648
Larry Hastings2f936352014-08-05 14:04:04 +10007649static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007650os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7651/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007652{
7653 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007654 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007655
Victor Stinnerdaf45552013-08-28 00:53:59 +02007656#ifdef O_CLOEXEC
7657 int *atomic_flag_works = &_Py_open_cloexec_works;
7658#elif !defined(MS_WINDOWS)
7659 int *atomic_flag_works = NULL;
7660#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007661
Victor Stinnerdaf45552013-08-28 00:53:59 +02007662#ifdef MS_WINDOWS
7663 flags |= O_NOINHERIT;
7664#elif defined(O_CLOEXEC)
7665 flags |= O_CLOEXEC;
7666#endif
7667
Steve Dower8fc89802015-04-12 00:26:27 -04007668 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007669 do {
7670 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007671#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007672 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007673#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007674#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007675 if (dir_fd != DEFAULT_DIR_FD)
7676 fd = openat(dir_fd, path->narrow, flags, mode);
7677 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007678#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007679 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007680#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007681 Py_END_ALLOW_THREADS
7682 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007683 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007684
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007685 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007686 if (!async_err)
7687 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007688 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007689 }
7690
Victor Stinnerdaf45552013-08-28 00:53:59 +02007691#ifndef MS_WINDOWS
7692 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7693 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007694 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007695 }
7696#endif
7697
Larry Hastings2f936352014-08-05 14:04:04 +10007698 return fd;
7699}
7700
7701
7702/*[clinic input]
7703os.close
7704
7705 fd: int
7706
7707Close a file descriptor.
7708[clinic start generated code]*/
7709
Barry Warsaw53699e91996-12-10 23:23:01 +00007710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007711os_close_impl(PyObject *module, int fd)
7712/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007713{
Larry Hastings2f936352014-08-05 14:04:04 +10007714 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007715 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7716 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7717 * for more details.
7718 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007720 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007721 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007722 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 Py_END_ALLOW_THREADS
7724 if (res < 0)
7725 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007726 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007727}
7728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007729
Larry Hastings2f936352014-08-05 14:04:04 +10007730/*[clinic input]
7731os.closerange
7732
7733 fd_low: int
7734 fd_high: int
7735 /
7736
7737Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7738[clinic start generated code]*/
7739
Larry Hastings2f936352014-08-05 14:04:04 +10007740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007741os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7742/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007743{
7744 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007746 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007747 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007748 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007749 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 Py_END_ALLOW_THREADS
7751 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007752}
7753
7754
Larry Hastings2f936352014-08-05 14:04:04 +10007755/*[clinic input]
7756os.dup -> int
7757
7758 fd: int
7759 /
7760
7761Return a duplicate of a file descriptor.
7762[clinic start generated code]*/
7763
Larry Hastings2f936352014-08-05 14:04:04 +10007764static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007765os_dup_impl(PyObject *module, int fd)
7766/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007767{
7768 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007769}
7770
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007771
Larry Hastings2f936352014-08-05 14:04:04 +10007772/*[clinic input]
7773os.dup2
7774 fd: int
7775 fd2: int
7776 inheritable: bool=True
7777
7778Duplicate file descriptor.
7779[clinic start generated code]*/
7780
Larry Hastings2f936352014-08-05 14:04:04 +10007781static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007782os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7783/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007784{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007785 int res;
7786#if defined(HAVE_DUP3) && \
7787 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7788 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7789 int dup3_works = -1;
7790#endif
7791
Steve Dower940f33a2016-09-08 11:21:54 -07007792 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007794
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007795 /* dup2() can fail with EINTR if the target FD is already open, because it
7796 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7797 * upon close(), and therefore below.
7798 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007799#ifdef MS_WINDOWS
7800 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007801 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007803 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007804 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 if (res < 0)
7806 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007807
7808 /* Character files like console cannot be make non-inheritable */
7809 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7810 close(fd2);
7811 return NULL;
7812 }
7813
7814#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7815 Py_BEGIN_ALLOW_THREADS
7816 if (!inheritable)
7817 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7818 else
7819 res = dup2(fd, fd2);
7820 Py_END_ALLOW_THREADS
7821 if (res < 0)
7822 return posix_error();
7823
7824#else
7825
7826#ifdef HAVE_DUP3
7827 if (!inheritable && dup3_works != 0) {
7828 Py_BEGIN_ALLOW_THREADS
7829 res = dup3(fd, fd2, O_CLOEXEC);
7830 Py_END_ALLOW_THREADS
7831 if (res < 0) {
7832 if (dup3_works == -1)
7833 dup3_works = (errno != ENOSYS);
7834 if (dup3_works)
7835 return posix_error();
7836 }
7837 }
7838
7839 if (inheritable || dup3_works == 0)
7840 {
7841#endif
7842 Py_BEGIN_ALLOW_THREADS
7843 res = dup2(fd, fd2);
7844 Py_END_ALLOW_THREADS
7845 if (res < 0)
7846 return posix_error();
7847
7848 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7849 close(fd2);
7850 return NULL;
7851 }
7852#ifdef HAVE_DUP3
7853 }
7854#endif
7855
7856#endif
7857
Larry Hastings2f936352014-08-05 14:04:04 +10007858 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007859}
7860
Larry Hastings2f936352014-08-05 14:04:04 +10007861
Ross Lagerwall7807c352011-03-17 20:20:30 +02007862#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007863/*[clinic input]
7864os.lockf
7865
7866 fd: int
7867 An open file descriptor.
7868 command: int
7869 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7870 length: Py_off_t
7871 The number of bytes to lock, starting at the current position.
7872 /
7873
7874Apply, test or remove a POSIX lock on an open file descriptor.
7875
7876[clinic start generated code]*/
7877
Larry Hastings2f936352014-08-05 14:04:04 +10007878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007879os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7880/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007881{
7882 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007883
7884 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007885 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007886 Py_END_ALLOW_THREADS
7887
7888 if (res < 0)
7889 return posix_error();
7890
7891 Py_RETURN_NONE;
7892}
Larry Hastings2f936352014-08-05 14:04:04 +10007893#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007895
Larry Hastings2f936352014-08-05 14:04:04 +10007896/*[clinic input]
7897os.lseek -> Py_off_t
7898
7899 fd: int
7900 position: Py_off_t
7901 how: int
7902 /
7903
7904Set the position of a file descriptor. Return the new position.
7905
7906Return the new cursor position in number of bytes
7907relative to the beginning of the file.
7908[clinic start generated code]*/
7909
Larry Hastings2f936352014-08-05 14:04:04 +10007910static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007911os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7912/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007913{
7914 Py_off_t result;
7915
Guido van Rossum687dd131993-05-17 08:34:16 +00007916#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007917 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7918 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007919 case 0: how = SEEK_SET; break;
7920 case 1: how = SEEK_CUR; break;
7921 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007922 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007923#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007924
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007926 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007927
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007929 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007930#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007931 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007932#else
Larry Hastings2f936352014-08-05 14:04:04 +10007933 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007934#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007935 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007937 if (result < 0)
7938 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007939
Larry Hastings2f936352014-08-05 14:04:04 +10007940 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007941}
7942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007943
Larry Hastings2f936352014-08-05 14:04:04 +10007944/*[clinic input]
7945os.read
7946 fd: int
7947 length: Py_ssize_t
7948 /
7949
7950Read from a file descriptor. Returns a bytes object.
7951[clinic start generated code]*/
7952
Larry Hastings2f936352014-08-05 14:04:04 +10007953static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007954os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7955/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007956{
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 Py_ssize_t n;
7958 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007959
7960 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007961 errno = EINVAL;
7962 return posix_error();
7963 }
Larry Hastings2f936352014-08-05 14:04:04 +10007964
7965#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007966 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007967 if (length > INT_MAX)
7968 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007969#endif
7970
7971 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 if (buffer == NULL)
7973 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007974
Victor Stinner66aab0c2015-03-19 22:53:20 +01007975 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7976 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007978 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 }
Larry Hastings2f936352014-08-05 14:04:04 +10007980
7981 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007983
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007985}
7986
Ross Lagerwall7807c352011-03-17 20:20:30 +02007987#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7988 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007989static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007990iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007991{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03007992 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007993 Py_ssize_t blen, total = 0;
7994
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007995 *iov = PyMem_New(struct iovec, cnt);
7996 if (*iov == NULL) {
7997 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007998 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007999 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008000
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008001 *buf = PyMem_New(Py_buffer, cnt);
8002 if (*buf == NULL) {
8003 PyMem_Del(*iov);
8004 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008005 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008006 }
8007
8008 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008009 PyObject *item = PySequence_GetItem(seq, i);
8010 if (item == NULL)
8011 goto fail;
8012 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8013 Py_DECREF(item);
8014 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008015 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008016 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008017 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008018 blen = (*buf)[i].len;
8019 (*iov)[i].iov_len = blen;
8020 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008021 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008022 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008023
8024fail:
8025 PyMem_Del(*iov);
8026 for (j = 0; j < i; j++) {
8027 PyBuffer_Release(&(*buf)[j]);
8028 }
8029 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008030 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008031}
8032
8033static void
8034iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8035{
8036 int i;
8037 PyMem_Del(iov);
8038 for (i = 0; i < cnt; i++) {
8039 PyBuffer_Release(&buf[i]);
8040 }
8041 PyMem_Del(buf);
8042}
8043#endif
8044
Larry Hastings2f936352014-08-05 14:04:04 +10008045
Ross Lagerwall7807c352011-03-17 20:20:30 +02008046#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008047/*[clinic input]
8048os.readv -> Py_ssize_t
8049
8050 fd: int
8051 buffers: object
8052 /
8053
8054Read from a file descriptor fd into an iterable of buffers.
8055
8056The buffers should be mutable buffers accepting bytes.
8057readv will transfer data into each buffer until it is full
8058and then move on to the next buffer in the sequence to hold
8059the rest of the data.
8060
8061readv returns the total number of bytes read,
8062which may be less than the total capacity of all the buffers.
8063[clinic start generated code]*/
8064
Larry Hastings2f936352014-08-05 14:04:04 +10008065static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008066os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8067/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008068{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008069 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008070 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008071 struct iovec *iov;
8072 Py_buffer *buf;
8073
Larry Hastings2f936352014-08-05 14:04:04 +10008074 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008075 PyErr_SetString(PyExc_TypeError,
8076 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008077 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008078 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008079
Larry Hastings2f936352014-08-05 14:04:04 +10008080 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008081 if (cnt < 0)
8082 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008083
8084 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8085 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008086
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008087 do {
8088 Py_BEGIN_ALLOW_THREADS
8089 n = readv(fd, iov, cnt);
8090 Py_END_ALLOW_THREADS
8091 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008092
8093 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008094 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008095 if (!async_err)
8096 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008097 return -1;
8098 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008099
Larry Hastings2f936352014-08-05 14:04:04 +10008100 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008101}
Larry Hastings2f936352014-08-05 14:04:04 +10008102#endif /* HAVE_READV */
8103
Ross Lagerwall7807c352011-03-17 20:20:30 +02008104
8105#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008106/*[clinic input]
8107# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8108os.pread
8109
8110 fd: int
8111 length: int
8112 offset: Py_off_t
8113 /
8114
8115Read a number of bytes from a file descriptor starting at a particular offset.
8116
8117Read length bytes from file descriptor fd, starting at offset bytes from
8118the beginning of the file. The file offset remains unchanged.
8119[clinic start generated code]*/
8120
Larry Hastings2f936352014-08-05 14:04:04 +10008121static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008122os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8123/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008124{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008126 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008127 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008128
Larry Hastings2f936352014-08-05 14:04:04 +10008129 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008130 errno = EINVAL;
8131 return posix_error();
8132 }
Larry Hastings2f936352014-08-05 14:04:04 +10008133 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008134 if (buffer == NULL)
8135 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008136
8137 do {
8138 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008139 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008140 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008141 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008142 Py_END_ALLOW_THREADS
8143 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8144
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145 if (n < 0) {
8146 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008147 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148 }
Larry Hastings2f936352014-08-05 14:04:04 +10008149 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150 _PyBytes_Resize(&buffer, n);
8151 return buffer;
8152}
Larry Hastings2f936352014-08-05 14:04:04 +10008153#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008154
Larry Hastings2f936352014-08-05 14:04:04 +10008155
8156/*[clinic input]
8157os.write -> Py_ssize_t
8158
8159 fd: int
8160 data: Py_buffer
8161 /
8162
8163Write a bytes object to a file descriptor.
8164[clinic start generated code]*/
8165
Larry Hastings2f936352014-08-05 14:04:04 +10008166static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008167os_write_impl(PyObject *module, int fd, Py_buffer *data)
8168/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008169{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008170 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171}
8172
8173#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008174PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008175"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008176sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008177 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008178Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008179
Larry Hastings2f936352014-08-05 14:04:04 +10008180/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008181static PyObject *
8182posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8183{
8184 int in, out;
8185 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008186 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008187 off_t offset;
8188
8189#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8190#ifndef __APPLE__
8191 Py_ssize_t len;
8192#endif
8193 PyObject *headers = NULL, *trailers = NULL;
8194 Py_buffer *hbuf, *tbuf;
8195 off_t sbytes;
8196 struct sf_hdtr sf;
8197 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008198 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008199 static char *keywords[] = {"out", "in",
8200 "offset", "count",
8201 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008202
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008203 sf.headers = NULL;
8204 sf.trailers = NULL;
8205
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008206#ifdef __APPLE__
8207 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008208 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008209#else
8210 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008211 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008212#endif
8213 &headers, &trailers, &flags))
8214 return NULL;
8215 if (headers != NULL) {
8216 if (!PySequence_Check(headers)) {
8217 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008218 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008219 return NULL;
8220 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008221 Py_ssize_t i = PySequence_Size(headers);
8222 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008223 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008224 if (i > INT_MAX) {
8225 PyErr_SetString(PyExc_OverflowError,
8226 "sendfile() header is too large");
8227 return NULL;
8228 }
8229 if (i > 0) {
8230 sf.hdr_cnt = (int)i;
8231 i = iov_setup(&(sf.headers), &hbuf,
8232 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8233 if (i < 0)
8234 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008235#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008236 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008237#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008238 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008239 }
8240 }
8241 if (trailers != NULL) {
8242 if (!PySequence_Check(trailers)) {
8243 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008244 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245 return NULL;
8246 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008247 Py_ssize_t i = PySequence_Size(trailers);
8248 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008249 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008250 if (i > INT_MAX) {
8251 PyErr_SetString(PyExc_OverflowError,
8252 "sendfile() trailer is too large");
8253 return NULL;
8254 }
8255 if (i > 0) {
8256 sf.trl_cnt = (int)i;
8257 i = iov_setup(&(sf.trailers), &tbuf,
8258 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8259 if (i < 0)
8260 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008261#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008262 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008263#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008264 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008265 }
8266 }
8267
Steve Dower8fc89802015-04-12 00:26:27 -04008268 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008269 do {
8270 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008271#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008272 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008273#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008274 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008275#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008276 Py_END_ALLOW_THREADS
8277 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008278 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008279
8280 if (sf.headers != NULL)
8281 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8282 if (sf.trailers != NULL)
8283 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8284
8285 if (ret < 0) {
8286 if ((errno == EAGAIN) || (errno == EBUSY)) {
8287 if (sbytes != 0) {
8288 // some data has been sent
8289 goto done;
8290 }
8291 else {
8292 // no data has been sent; upper application is supposed
8293 // to retry on EAGAIN or EBUSY
8294 return posix_error();
8295 }
8296 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008297 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008298 }
8299 goto done;
8300
8301done:
8302 #if !defined(HAVE_LARGEFILE_SUPPORT)
8303 return Py_BuildValue("l", sbytes);
8304 #else
8305 return Py_BuildValue("L", sbytes);
8306 #endif
8307
8308#else
8309 Py_ssize_t count;
8310 PyObject *offobj;
8311 static char *keywords[] = {"out", "in",
8312 "offset", "count", NULL};
8313 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8314 keywords, &out, &in, &offobj, &count))
8315 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008316#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008318 do {
8319 Py_BEGIN_ALLOW_THREADS
8320 ret = sendfile(out, in, NULL, count);
8321 Py_END_ALLOW_THREADS
8322 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008325 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008326 }
8327#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008328 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008329 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008330
8331 do {
8332 Py_BEGIN_ALLOW_THREADS
8333 ret = sendfile(out, in, &offset, count);
8334 Py_END_ALLOW_THREADS
8335 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008336 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008337 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008338 return Py_BuildValue("n", ret);
8339#endif
8340}
Larry Hastings2f936352014-08-05 14:04:04 +10008341#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008342
Larry Hastings2f936352014-08-05 14:04:04 +10008343
8344/*[clinic input]
8345os.fstat
8346
8347 fd : int
8348
8349Perform a stat system call on the given file descriptor.
8350
8351Like stat(), but for an open file descriptor.
8352Equivalent to os.stat(fd).
8353[clinic start generated code]*/
8354
Larry Hastings2f936352014-08-05 14:04:04 +10008355static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008356os_fstat_impl(PyObject *module, int fd)
8357/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008358{
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 STRUCT_STAT st;
8360 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008361 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008362
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008363 do {
8364 Py_BEGIN_ALLOW_THREADS
8365 res = FSTAT(fd, &st);
8366 Py_END_ALLOW_THREADS
8367 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008368 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008369#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008370 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008371#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008372 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008373#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 }
Tim Peters5aa91602002-01-30 05:46:57 +00008375
Victor Stinner4195b5c2012-02-08 23:03:19 +01008376 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008377}
8378
Larry Hastings2f936352014-08-05 14:04:04 +10008379
8380/*[clinic input]
8381os.isatty -> bool
8382 fd: int
8383 /
8384
8385Return True if the fd is connected to a terminal.
8386
8387Return True if the file descriptor is an open file descriptor
8388connected to the slave end of a terminal.
8389[clinic start generated code]*/
8390
Larry Hastings2f936352014-08-05 14:04:04 +10008391static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008392os_isatty_impl(PyObject *module, int fd)
8393/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008394{
Steve Dower8fc89802015-04-12 00:26:27 -04008395 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008396 _Py_BEGIN_SUPPRESS_IPH
8397 return_value = isatty(fd);
8398 _Py_END_SUPPRESS_IPH
8399 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008400}
8401
8402
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008403#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008404/*[clinic input]
8405os.pipe
8406
8407Create a pipe.
8408
8409Returns a tuple of two file descriptors:
8410 (read_fd, write_fd)
8411[clinic start generated code]*/
8412
Larry Hastings2f936352014-08-05 14:04:04 +10008413static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008414os_pipe_impl(PyObject *module)
8415/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008416{
Victor Stinner8c62be82010-05-06 00:08:46 +00008417 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008418#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008420 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008422#else
8423 int res;
8424#endif
8425
8426#ifdef MS_WINDOWS
8427 attr.nLength = sizeof(attr);
8428 attr.lpSecurityDescriptor = NULL;
8429 attr.bInheritHandle = FALSE;
8430
8431 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008432 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008433 ok = CreatePipe(&read, &write, &attr, 0);
8434 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008435 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8436 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008437 if (fds[0] == -1 || fds[1] == -1) {
8438 CloseHandle(read);
8439 CloseHandle(write);
8440 ok = 0;
8441 }
8442 }
Steve Dowerc3630612016-11-19 18:41:16 -08008443 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008444 Py_END_ALLOW_THREADS
8445
Victor Stinner8c62be82010-05-06 00:08:46 +00008446 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008447 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008448#else
8449
8450#ifdef HAVE_PIPE2
8451 Py_BEGIN_ALLOW_THREADS
8452 res = pipe2(fds, O_CLOEXEC);
8453 Py_END_ALLOW_THREADS
8454
8455 if (res != 0 && errno == ENOSYS)
8456 {
8457#endif
8458 Py_BEGIN_ALLOW_THREADS
8459 res = pipe(fds);
8460 Py_END_ALLOW_THREADS
8461
8462 if (res == 0) {
8463 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8464 close(fds[0]);
8465 close(fds[1]);
8466 return NULL;
8467 }
8468 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8469 close(fds[0]);
8470 close(fds[1]);
8471 return NULL;
8472 }
8473 }
8474#ifdef HAVE_PIPE2
8475 }
8476#endif
8477
8478 if (res != 0)
8479 return PyErr_SetFromErrno(PyExc_OSError);
8480#endif /* !MS_WINDOWS */
8481 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008482}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008483#endif /* HAVE_PIPE */
8484
Larry Hastings2f936352014-08-05 14:04:04 +10008485
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008486#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008487/*[clinic input]
8488os.pipe2
8489
8490 flags: int
8491 /
8492
8493Create a pipe with flags set atomically.
8494
8495Returns a tuple of two file descriptors:
8496 (read_fd, write_fd)
8497
8498flags can be constructed by ORing together one or more of these values:
8499O_NONBLOCK, O_CLOEXEC.
8500[clinic start generated code]*/
8501
Larry Hastings2f936352014-08-05 14:04:04 +10008502static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008503os_pipe2_impl(PyObject *module, int flags)
8504/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008505{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008506 int fds[2];
8507 int res;
8508
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008509 res = pipe2(fds, flags);
8510 if (res != 0)
8511 return posix_error();
8512 return Py_BuildValue("(ii)", fds[0], fds[1]);
8513}
8514#endif /* HAVE_PIPE2 */
8515
Larry Hastings2f936352014-08-05 14:04:04 +10008516
Ross Lagerwall7807c352011-03-17 20:20:30 +02008517#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008518/*[clinic input]
8519os.writev -> Py_ssize_t
8520 fd: int
8521 buffers: object
8522 /
8523
8524Iterate over buffers, and write the contents of each to a file descriptor.
8525
8526Returns the total number of bytes written.
8527buffers must be a sequence of bytes-like objects.
8528[clinic start generated code]*/
8529
Larry Hastings2f936352014-08-05 14:04:04 +10008530static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008531os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8532/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008533{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008534 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008535 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008536 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008537 struct iovec *iov;
8538 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008539
8540 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008541 PyErr_SetString(PyExc_TypeError,
8542 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008543 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008544 }
Larry Hastings2f936352014-08-05 14:04:04 +10008545 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008546 if (cnt < 0)
8547 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008548
Larry Hastings2f936352014-08-05 14:04:04 +10008549 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8550 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008551 }
8552
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008553 do {
8554 Py_BEGIN_ALLOW_THREADS
8555 result = writev(fd, iov, cnt);
8556 Py_END_ALLOW_THREADS
8557 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008558
8559 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008560 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008561 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008562
Georg Brandl306336b2012-06-24 12:55:33 +02008563 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008564}
Larry Hastings2f936352014-08-05 14:04:04 +10008565#endif /* HAVE_WRITEV */
8566
8567
8568#ifdef HAVE_PWRITE
8569/*[clinic input]
8570os.pwrite -> Py_ssize_t
8571
8572 fd: int
8573 buffer: Py_buffer
8574 offset: Py_off_t
8575 /
8576
8577Write bytes to a file descriptor starting at a particular offset.
8578
8579Write buffer to fd, starting at offset bytes from the beginning of
8580the file. Returns the number of bytes writte. Does not change the
8581current file offset.
8582[clinic start generated code]*/
8583
Larry Hastings2f936352014-08-05 14:04:04 +10008584static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008585os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8586/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008587{
8588 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008589 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008590
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008591 do {
8592 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008593 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008594 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008595 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008596 Py_END_ALLOW_THREADS
8597 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008598
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008599 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008600 posix_error();
8601 return size;
8602}
8603#endif /* HAVE_PWRITE */
8604
8605
8606#ifdef HAVE_MKFIFO
8607/*[clinic input]
8608os.mkfifo
8609
8610 path: path_t
8611 mode: int=0o666
8612 *
8613 dir_fd: dir_fd(requires='mkfifoat')=None
8614
8615Create a "fifo" (a POSIX named pipe).
8616
8617If dir_fd is not None, it should be a file descriptor open to a directory,
8618 and path should be relative; path will then be relative to that directory.
8619dir_fd may not be implemented on your platform.
8620 If it is unavailable, using it will raise a NotImplementedError.
8621[clinic start generated code]*/
8622
Larry Hastings2f936352014-08-05 14:04:04 +10008623static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008624os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8625/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008626{
8627 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008628 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008629
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008630 do {
8631 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008632#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008633 if (dir_fd != DEFAULT_DIR_FD)
8634 result = mkfifoat(dir_fd, path->narrow, mode);
8635 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008636#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008637 result = mkfifo(path->narrow, mode);
8638 Py_END_ALLOW_THREADS
8639 } while (result != 0 && errno == EINTR &&
8640 !(async_err = PyErr_CheckSignals()));
8641 if (result != 0)
8642 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008643
8644 Py_RETURN_NONE;
8645}
8646#endif /* HAVE_MKFIFO */
8647
8648
8649#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8650/*[clinic input]
8651os.mknod
8652
8653 path: path_t
8654 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008655 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008656 *
8657 dir_fd: dir_fd(requires='mknodat')=None
8658
8659Create a node in the file system.
8660
8661Create a node in the file system (file, device special file or named pipe)
8662at path. mode specifies both the permissions to use and the
8663type of node to be created, being combined (bitwise OR) with one of
8664S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8665device defines the newly created device special file (probably using
8666os.makedev()). Otherwise device is ignored.
8667
8668If dir_fd is not None, it should be a file descriptor open to a directory,
8669 and path should be relative; path will then be relative to that directory.
8670dir_fd may not be implemented on your platform.
8671 If it is unavailable, using it will raise a NotImplementedError.
8672[clinic start generated code]*/
8673
Larry Hastings2f936352014-08-05 14:04:04 +10008674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008675os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008676 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008677/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008678{
8679 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008681
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008682 do {
8683 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008684#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008685 if (dir_fd != DEFAULT_DIR_FD)
8686 result = mknodat(dir_fd, path->narrow, mode, device);
8687 else
Larry Hastings2f936352014-08-05 14:04:04 +10008688#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008689 result = mknod(path->narrow, mode, device);
8690 Py_END_ALLOW_THREADS
8691 } while (result != 0 && errno == EINTR &&
8692 !(async_err = PyErr_CheckSignals()));
8693 if (result != 0)
8694 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008695
8696 Py_RETURN_NONE;
8697}
8698#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8699
8700
8701#ifdef HAVE_DEVICE_MACROS
8702/*[clinic input]
8703os.major -> unsigned_int
8704
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008705 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008706 /
8707
8708Extracts a device major number from a raw device number.
8709[clinic start generated code]*/
8710
Larry Hastings2f936352014-08-05 14:04:04 +10008711static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008712os_major_impl(PyObject *module, dev_t device)
8713/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008714{
8715 return major(device);
8716}
8717
8718
8719/*[clinic input]
8720os.minor -> unsigned_int
8721
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008722 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008723 /
8724
8725Extracts a device minor number from a raw device number.
8726[clinic start generated code]*/
8727
Larry Hastings2f936352014-08-05 14:04:04 +10008728static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008729os_minor_impl(PyObject *module, dev_t device)
8730/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008731{
8732 return minor(device);
8733}
8734
8735
8736/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008737os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008738
8739 major: int
8740 minor: int
8741 /
8742
8743Composes a raw device number from the major and minor device numbers.
8744[clinic start generated code]*/
8745
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008746static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008747os_makedev_impl(PyObject *module, int major, int minor)
8748/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008749{
8750 return makedev(major, minor);
8751}
8752#endif /* HAVE_DEVICE_MACROS */
8753
8754
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008755#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008756/*[clinic input]
8757os.ftruncate
8758
8759 fd: int
8760 length: Py_off_t
8761 /
8762
8763Truncate a file, specified by file descriptor, to a specific length.
8764[clinic start generated code]*/
8765
Larry Hastings2f936352014-08-05 14:04:04 +10008766static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008767os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8768/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008769{
8770 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008771 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008772
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008773 do {
8774 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008775 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008776#ifdef MS_WINDOWS
8777 result = _chsize_s(fd, length);
8778#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008779 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008780#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008781 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008782 Py_END_ALLOW_THREADS
8783 } while (result != 0 && errno == EINTR &&
8784 !(async_err = PyErr_CheckSignals()));
8785 if (result != 0)
8786 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008787 Py_RETURN_NONE;
8788}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008789#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008790
8791
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008792#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008793/*[clinic input]
8794os.truncate
8795 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8796 length: Py_off_t
8797
8798Truncate a file, specified by path, to a specific length.
8799
8800On some platforms, path may also be specified as an open file descriptor.
8801 If this functionality is unavailable, using it raises an exception.
8802[clinic start generated code]*/
8803
Larry Hastings2f936352014-08-05 14:04:04 +10008804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008805os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8806/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008807{
8808 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008809#ifdef MS_WINDOWS
8810 int fd;
8811#endif
8812
8813 if (path->fd != -1)
8814 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008815
8816 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008817 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008818#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008819 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008820 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008821 result = -1;
8822 else {
8823 result = _chsize_s(fd, length);
8824 close(fd);
8825 if (result < 0)
8826 errno = result;
8827 }
8828#else
8829 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008830#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008831 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008832 Py_END_ALLOW_THREADS
8833 if (result < 0)
8834 return path_error(path);
8835
8836 Py_RETURN_NONE;
8837}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008838#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008839
Ross Lagerwall7807c352011-03-17 20:20:30 +02008840
Victor Stinnerd6b17692014-09-30 12:20:05 +02008841/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8842 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8843 defined, which is the case in Python on AIX. AIX bug report:
8844 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8845#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8846# define POSIX_FADVISE_AIX_BUG
8847#endif
8848
Victor Stinnerec39e262014-09-30 12:35:58 +02008849
Victor Stinnerd6b17692014-09-30 12:20:05 +02008850#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008851/*[clinic input]
8852os.posix_fallocate
8853
8854 fd: int
8855 offset: Py_off_t
8856 length: Py_off_t
8857 /
8858
8859Ensure a file has allocated at least a particular number of bytes on disk.
8860
8861Ensure that the file specified by fd encompasses a range of bytes
8862starting at offset bytes from the beginning and continuing for length bytes.
8863[clinic start generated code]*/
8864
Larry Hastings2f936352014-08-05 14:04:04 +10008865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008866os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008867 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008868/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008869{
8870 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008871 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008872
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008873 do {
8874 Py_BEGIN_ALLOW_THREADS
8875 result = posix_fallocate(fd, offset, length);
8876 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008877 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8878
8879 if (result == 0)
8880 Py_RETURN_NONE;
8881
8882 if (async_err)
8883 return NULL;
8884
8885 errno = result;
8886 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008887}
Victor Stinnerec39e262014-09-30 12:35:58 +02008888#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008889
Ross Lagerwall7807c352011-03-17 20:20:30 +02008890
Victor Stinnerd6b17692014-09-30 12:20:05 +02008891#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008892/*[clinic input]
8893os.posix_fadvise
8894
8895 fd: int
8896 offset: Py_off_t
8897 length: Py_off_t
8898 advice: int
8899 /
8900
8901Announce an intention to access data in a specific pattern.
8902
8903Announce an intention to access data in a specific pattern, thus allowing
8904the kernel to make optimizations.
8905The advice applies to the region of the file specified by fd starting at
8906offset and continuing for length bytes.
8907advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8908POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8909POSIX_FADV_DONTNEED.
8910[clinic start generated code]*/
8911
Larry Hastings2f936352014-08-05 14:04:04 +10008912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008913os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008914 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008915/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008916{
8917 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008918 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008919
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008920 do {
8921 Py_BEGIN_ALLOW_THREADS
8922 result = posix_fadvise(fd, offset, length, advice);
8923 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05008924 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
8925
8926 if (result == 0)
8927 Py_RETURN_NONE;
8928
8929 if (async_err)
8930 return NULL;
8931
8932 errno = result;
8933 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02008934}
Victor Stinnerec39e262014-09-30 12:35:58 +02008935#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008936
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008937#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008938
Fred Drake762e2061999-08-26 17:23:54 +00008939/* Save putenv() parameters as values here, so we can collect them when they
8940 * get re-set with another call for the same key. */
8941static PyObject *posix_putenv_garbage;
8942
Larry Hastings2f936352014-08-05 14:04:04 +10008943static void
8944posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008945{
Larry Hastings2f936352014-08-05 14:04:04 +10008946 /* Install the first arg and newstr in posix_putenv_garbage;
8947 * this will cause previous value to be collected. This has to
8948 * happen after the real putenv() call because the old value
8949 * was still accessible until then. */
8950 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8951 /* really not much we can do; just leak */
8952 PyErr_Clear();
8953 else
8954 Py_DECREF(value);
8955}
8956
8957
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008958#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008959/*[clinic input]
8960os.putenv
8961
8962 name: unicode
8963 value: unicode
8964 /
8965
8966Change or add an environment variable.
8967[clinic start generated code]*/
8968
Larry Hastings2f936352014-08-05 14:04:04 +10008969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008970os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8971/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008972{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008973 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008974 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10008975
Serhiy Storchaka77703942017-06-25 07:33:01 +03008976 /* Search from index 1 because on Windows starting '=' is allowed for
8977 defining hidden environment variables. */
8978 if (PyUnicode_GET_LENGTH(name) == 0 ||
8979 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
8980 {
8981 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
8982 return NULL;
8983 }
Larry Hastings2f936352014-08-05 14:04:04 +10008984 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8985 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10008986 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008987 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008988
8989 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
8990 if (env == NULL)
8991 goto error;
8992 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01008993 PyErr_Format(PyExc_ValueError,
8994 "the environment variable is longer than %u characters",
8995 _MAX_ENV);
8996 goto error;
8997 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03008998 if (wcslen(env) != (size_t)size) {
8999 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009000 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009001 }
9002
Larry Hastings2f936352014-08-05 14:04:04 +10009003 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009005 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009007
Larry Hastings2f936352014-08-05 14:04:04 +10009008 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009009 Py_RETURN_NONE;
9010
9011error:
Larry Hastings2f936352014-08-05 14:04:04 +10009012 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009013 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009014}
Larry Hastings2f936352014-08-05 14:04:04 +10009015#else /* MS_WINDOWS */
9016/*[clinic input]
9017os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009018
Larry Hastings2f936352014-08-05 14:04:04 +10009019 name: FSConverter
9020 value: FSConverter
9021 /
9022
9023Change or add an environment variable.
9024[clinic start generated code]*/
9025
Larry Hastings2f936352014-08-05 14:04:04 +10009026static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009027os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9028/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009029{
9030 PyObject *bytes = NULL;
9031 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009032 const char *name_string = PyBytes_AS_STRING(name);
9033 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009034
Serhiy Storchaka77703942017-06-25 07:33:01 +03009035 if (strchr(name_string, '=') != NULL) {
9036 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9037 return NULL;
9038 }
Larry Hastings2f936352014-08-05 14:04:04 +10009039 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9040 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009041 return NULL;
9042 }
9043
9044 env = PyBytes_AS_STRING(bytes);
9045 if (putenv(env)) {
9046 Py_DECREF(bytes);
9047 return posix_error();
9048 }
9049
9050 posix_putenv_garbage_setitem(name, bytes);
9051 Py_RETURN_NONE;
9052}
9053#endif /* MS_WINDOWS */
9054#endif /* HAVE_PUTENV */
9055
9056
9057#ifdef HAVE_UNSETENV
9058/*[clinic input]
9059os.unsetenv
9060 name: FSConverter
9061 /
9062
9063Delete an environment variable.
9064[clinic start generated code]*/
9065
Larry Hastings2f936352014-08-05 14:04:04 +10009066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009067os_unsetenv_impl(PyObject *module, PyObject *name)
9068/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009069{
Victor Stinner984890f2011-11-24 13:53:38 +01009070#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009071 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009072#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009073
Victor Stinner984890f2011-11-24 13:53:38 +01009074#ifdef HAVE_BROKEN_UNSETENV
9075 unsetenv(PyBytes_AS_STRING(name));
9076#else
Victor Stinner65170952011-11-22 22:16:17 +01009077 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009078 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009079 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009080#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009081
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 /* Remove the key from posix_putenv_garbage;
9083 * this will cause it to be collected. This has to
9084 * happen after the real unsetenv() call because the
9085 * old value was still accessible until then.
9086 */
Victor Stinner65170952011-11-22 22:16:17 +01009087 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 /* really not much we can do; just leak */
9089 PyErr_Clear();
9090 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009091 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009092}
Larry Hastings2f936352014-08-05 14:04:04 +10009093#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009094
Larry Hastings2f936352014-08-05 14:04:04 +10009095
9096/*[clinic input]
9097os.strerror
9098
9099 code: int
9100 /
9101
9102Translate an error code to a message string.
9103[clinic start generated code]*/
9104
Larry Hastings2f936352014-08-05 14:04:04 +10009105static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009106os_strerror_impl(PyObject *module, int code)
9107/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009108{
9109 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 if (message == NULL) {
9111 PyErr_SetString(PyExc_ValueError,
9112 "strerror() argument out of range");
9113 return NULL;
9114 }
Victor Stinner1b579672011-12-17 05:47:23 +01009115 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009116}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009117
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009118
Guido van Rossumc9641791998-08-04 15:26:23 +00009119#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009120#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009121/*[clinic input]
9122os.WCOREDUMP -> bool
9123
9124 status: int
9125 /
9126
9127Return True if the process returning status was dumped to a core file.
9128[clinic start generated code]*/
9129
Larry Hastings2f936352014-08-05 14:04:04 +10009130static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009131os_WCOREDUMP_impl(PyObject *module, int status)
9132/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009133{
9134 WAIT_TYPE wait_status;
9135 WAIT_STATUS_INT(wait_status) = status;
9136 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009137}
9138#endif /* WCOREDUMP */
9139
Larry Hastings2f936352014-08-05 14:04:04 +10009140
Fred Drake106c1a02002-04-23 15:58:02 +00009141#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009142/*[clinic input]
9143os.WIFCONTINUED -> bool
9144
9145 status: int
9146
9147Return True if a particular process was continued from a job control stop.
9148
9149Return True if the process returning status was continued from a
9150job control stop.
9151[clinic start generated code]*/
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009154os_WIFCONTINUED_impl(PyObject *module, int status)
9155/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009156{
9157 WAIT_TYPE wait_status;
9158 WAIT_STATUS_INT(wait_status) = status;
9159 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009160}
9161#endif /* WIFCONTINUED */
9162
Larry Hastings2f936352014-08-05 14:04:04 +10009163
Guido van Rossumc9641791998-08-04 15:26:23 +00009164#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009165/*[clinic input]
9166os.WIFSTOPPED -> bool
9167
9168 status: int
9169
9170Return True if the process returning status was stopped.
9171[clinic start generated code]*/
9172
Larry Hastings2f936352014-08-05 14:04:04 +10009173static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009174os_WIFSTOPPED_impl(PyObject *module, int status)
9175/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009176{
9177 WAIT_TYPE wait_status;
9178 WAIT_STATUS_INT(wait_status) = status;
9179 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009180}
9181#endif /* WIFSTOPPED */
9182
Larry Hastings2f936352014-08-05 14:04:04 +10009183
Guido van Rossumc9641791998-08-04 15:26:23 +00009184#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009185/*[clinic input]
9186os.WIFSIGNALED -> bool
9187
9188 status: int
9189
9190Return True if the process returning status was terminated by a signal.
9191[clinic start generated code]*/
9192
Larry Hastings2f936352014-08-05 14:04:04 +10009193static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009194os_WIFSIGNALED_impl(PyObject *module, int status)
9195/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009196{
9197 WAIT_TYPE wait_status;
9198 WAIT_STATUS_INT(wait_status) = status;
9199 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009200}
9201#endif /* WIFSIGNALED */
9202
Larry Hastings2f936352014-08-05 14:04:04 +10009203
Guido van Rossumc9641791998-08-04 15:26:23 +00009204#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009205/*[clinic input]
9206os.WIFEXITED -> bool
9207
9208 status: int
9209
9210Return True if the process returning status exited via the exit() system call.
9211[clinic start generated code]*/
9212
Larry Hastings2f936352014-08-05 14:04:04 +10009213static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009214os_WIFEXITED_impl(PyObject *module, int status)
9215/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009216{
9217 WAIT_TYPE wait_status;
9218 WAIT_STATUS_INT(wait_status) = status;
9219 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009220}
9221#endif /* WIFEXITED */
9222
Larry Hastings2f936352014-08-05 14:04:04 +10009223
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009224#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009225/*[clinic input]
9226os.WEXITSTATUS -> int
9227
9228 status: int
9229
9230Return the process return code from status.
9231[clinic start generated code]*/
9232
Larry Hastings2f936352014-08-05 14:04:04 +10009233static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009234os_WEXITSTATUS_impl(PyObject *module, int status)
9235/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009236{
9237 WAIT_TYPE wait_status;
9238 WAIT_STATUS_INT(wait_status) = status;
9239 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009240}
9241#endif /* WEXITSTATUS */
9242
Larry Hastings2f936352014-08-05 14:04:04 +10009243
Guido van Rossumc9641791998-08-04 15:26:23 +00009244#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009245/*[clinic input]
9246os.WTERMSIG -> int
9247
9248 status: int
9249
9250Return the signal that terminated the process that provided the status value.
9251[clinic start generated code]*/
9252
Larry Hastings2f936352014-08-05 14:04:04 +10009253static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009254os_WTERMSIG_impl(PyObject *module, int status)
9255/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009256{
9257 WAIT_TYPE wait_status;
9258 WAIT_STATUS_INT(wait_status) = status;
9259 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009260}
9261#endif /* WTERMSIG */
9262
Larry Hastings2f936352014-08-05 14:04:04 +10009263
Guido van Rossumc9641791998-08-04 15:26:23 +00009264#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009265/*[clinic input]
9266os.WSTOPSIG -> int
9267
9268 status: int
9269
9270Return the signal that stopped the process that provided the status value.
9271[clinic start generated code]*/
9272
Larry Hastings2f936352014-08-05 14:04:04 +10009273static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009274os_WSTOPSIG_impl(PyObject *module, int status)
9275/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009276{
9277 WAIT_TYPE wait_status;
9278 WAIT_STATUS_INT(wait_status) = status;
9279 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009280}
9281#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009282#endif /* HAVE_SYS_WAIT_H */
9283
9284
Thomas Wouters477c8d52006-05-27 19:21:47 +00009285#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009286#ifdef _SCO_DS
9287/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9288 needed definitions in sys/statvfs.h */
9289#define _SVID3
9290#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009291#include <sys/statvfs.h>
9292
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009293static PyObject*
9294_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9296 if (v == NULL)
9297 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009298
9299#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9301 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9302 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9303 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9304 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9305 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9306 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9307 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9308 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9309 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009310#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9312 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9313 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009314 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009316 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009318 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009320 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009321 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009322 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009324 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9326 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009327#endif
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009328 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009329 if (PyErr_Occurred()) {
9330 Py_DECREF(v);
9331 return NULL;
9332 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009333
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009335}
9336
Larry Hastings2f936352014-08-05 14:04:04 +10009337
9338/*[clinic input]
9339os.fstatvfs
9340 fd: int
9341 /
9342
9343Perform an fstatvfs system call on the given fd.
9344
9345Equivalent to statvfs(fd).
9346[clinic start generated code]*/
9347
Larry Hastings2f936352014-08-05 14:04:04 +10009348static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009349os_fstatvfs_impl(PyObject *module, int fd)
9350/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009351{
9352 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009353 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009355
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009356 do {
9357 Py_BEGIN_ALLOW_THREADS
9358 result = fstatvfs(fd, &st);
9359 Py_END_ALLOW_THREADS
9360 } while (result != 0 && errno == EINTR &&
9361 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009362 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009363 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009364
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009366}
Larry Hastings2f936352014-08-05 14:04:04 +10009367#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009368
9369
Thomas Wouters477c8d52006-05-27 19:21:47 +00009370#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009371#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009372/*[clinic input]
9373os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009374
Larry Hastings2f936352014-08-05 14:04:04 +10009375 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9376
9377Perform a statvfs system call on the given path.
9378
9379path may always be specified as a string.
9380On some platforms, path may also be specified as an open file descriptor.
9381 If this functionality is unavailable, using it raises an exception.
9382[clinic start generated code]*/
9383
Larry Hastings2f936352014-08-05 14:04:04 +10009384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009385os_statvfs_impl(PyObject *module, path_t *path)
9386/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009387{
9388 int result;
9389 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009390
9391 Py_BEGIN_ALLOW_THREADS
9392#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009393 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009394#ifdef __APPLE__
9395 /* handle weak-linking on Mac OS X 10.3 */
9396 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009397 fd_specified("statvfs", path->fd);
9398 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009399 }
9400#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009401 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009402 }
9403 else
9404#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009405 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009406 Py_END_ALLOW_THREADS
9407
9408 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009409 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009410 }
9411
Larry Hastings2f936352014-08-05 14:04:04 +10009412 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009413}
Larry Hastings2f936352014-08-05 14:04:04 +10009414#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9415
Guido van Rossum94f6f721999-01-06 18:42:14 +00009416
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009417#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009418/*[clinic input]
9419os._getdiskusage
9420
9421 path: Py_UNICODE
9422
9423Return disk usage statistics about the given path as a (total, free) tuple.
9424[clinic start generated code]*/
9425
Larry Hastings2f936352014-08-05 14:04:04 +10009426static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009427os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9428/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009429{
9430 BOOL retval;
9431 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009432
9433 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009434 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009435 Py_END_ALLOW_THREADS
9436 if (retval == 0)
9437 return PyErr_SetFromWindowsErr(0);
9438
9439 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9440}
Larry Hastings2f936352014-08-05 14:04:04 +10009441#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009442
9443
Fred Drakec9680921999-12-13 16:37:25 +00009444/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9445 * It maps strings representing configuration variable names to
9446 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009447 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009448 * rarely-used constants. There are three separate tables that use
9449 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009450 *
9451 * This code is always included, even if none of the interfaces that
9452 * need it are included. The #if hackery needed to avoid it would be
9453 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009454 */
9455struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009456 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009457 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009458};
9459
Fred Drake12c6e2d1999-12-14 21:25:03 +00009460static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009461conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009462 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009463{
Christian Heimes217cfd12007-12-02 14:31:20 +00009464 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009465 int value = _PyLong_AsInt(arg);
9466 if (value == -1 && PyErr_Occurred())
9467 return 0;
9468 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009469 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009470 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009471 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009472 /* look up the value in the table using a binary search */
9473 size_t lo = 0;
9474 size_t mid;
9475 size_t hi = tablesize;
9476 int cmp;
9477 const char *confname;
9478 if (!PyUnicode_Check(arg)) {
9479 PyErr_SetString(PyExc_TypeError,
9480 "configuration names must be strings or integers");
9481 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009483 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009484 if (confname == NULL)
9485 return 0;
9486 while (lo < hi) {
9487 mid = (lo + hi) / 2;
9488 cmp = strcmp(confname, table[mid].name);
9489 if (cmp < 0)
9490 hi = mid;
9491 else if (cmp > 0)
9492 lo = mid + 1;
9493 else {
9494 *valuep = table[mid].value;
9495 return 1;
9496 }
9497 }
9498 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9499 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009501}
9502
9503
9504#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9505static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009506#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009508#endif
9509#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009511#endif
Fred Drakec9680921999-12-13 16:37:25 +00009512#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009514#endif
9515#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009517#endif
9518#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009520#endif
9521#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
9524#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009526#endif
9527#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009529#endif
9530#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009532#endif
9533#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009535#endif
9536#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
9539#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009557#ifdef _PC_ACL_ENABLED
9558 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9559#endif
9560#ifdef _PC_MIN_HOLE_SIZE
9561 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9562#endif
9563#ifdef _PC_ALLOC_SIZE_MIN
9564 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9565#endif
9566#ifdef _PC_REC_INCR_XFER_SIZE
9567 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9568#endif
9569#ifdef _PC_REC_MAX_XFER_SIZE
9570 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9571#endif
9572#ifdef _PC_REC_MIN_XFER_SIZE
9573 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9574#endif
9575#ifdef _PC_REC_XFER_ALIGN
9576 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9577#endif
9578#ifdef _PC_SYMLINK_MAX
9579 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9580#endif
9581#ifdef _PC_XATTR_ENABLED
9582 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9583#endif
9584#ifdef _PC_XATTR_EXISTS
9585 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9586#endif
9587#ifdef _PC_TIMESTAMP_RESOLUTION
9588 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9589#endif
Fred Drakec9680921999-12-13 16:37:25 +00009590};
9591
Fred Drakec9680921999-12-13 16:37:25 +00009592static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009593conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009594{
9595 return conv_confname(arg, valuep, posix_constants_pathconf,
9596 sizeof(posix_constants_pathconf)
9597 / sizeof(struct constdef));
9598}
9599#endif
9600
Larry Hastings2f936352014-08-05 14:04:04 +10009601
Fred Drakec9680921999-12-13 16:37:25 +00009602#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009603/*[clinic input]
9604os.fpathconf -> long
9605
9606 fd: int
9607 name: path_confname
9608 /
9609
9610Return the configuration limit name for the file descriptor fd.
9611
9612If there is no limit, return -1.
9613[clinic start generated code]*/
9614
Larry Hastings2f936352014-08-05 14:04:04 +10009615static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009616os_fpathconf_impl(PyObject *module, int fd, int name)
9617/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009618{
9619 long limit;
9620
9621 errno = 0;
9622 limit = fpathconf(fd, name);
9623 if (limit == -1 && errno != 0)
9624 posix_error();
9625
9626 return limit;
9627}
9628#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009629
9630
9631#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009632/*[clinic input]
9633os.pathconf -> long
9634 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9635 name: path_confname
9636
9637Return the configuration limit name for the file or directory path.
9638
9639If there is no limit, return -1.
9640On some platforms, path may also be specified as an open file descriptor.
9641 If this functionality is unavailable, using it raises an exception.
9642[clinic start generated code]*/
9643
Larry Hastings2f936352014-08-05 14:04:04 +10009644static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009645os_pathconf_impl(PyObject *module, path_t *path, int name)
9646/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009647{
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009649
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009651#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009652 if (path->fd != -1)
9653 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009654 else
9655#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009656 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 if (limit == -1 && errno != 0) {
9658 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009659 /* could be a path or name problem */
9660 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009661 else
Larry Hastings2f936352014-08-05 14:04:04 +10009662 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 }
Larry Hastings2f936352014-08-05 14:04:04 +10009664
9665 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009666}
Larry Hastings2f936352014-08-05 14:04:04 +10009667#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009668
9669#ifdef HAVE_CONFSTR
9670static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009671#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009673#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009674#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009676#endif
9677#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009679#endif
Fred Draked86ed291999-12-15 15:34:33 +00009680#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009682#endif
9683#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009685#endif
9686#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009688#endif
9689#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009691#endif
Fred Drakec9680921999-12-13 16:37:25 +00009692#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
Fred Draked86ed291999-12-15 15:34:33 +00009716#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
Fred Drakec9680921999-12-13 16:37:25 +00009719#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
Fred Draked86ed291999-12-15 15:34:33 +00009722#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
9725#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009727#endif
9728#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009730#endif
9731#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009733#endif
Fred Drakec9680921999-12-13 16:37:25 +00009734#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
Fred Draked86ed291999-12-15 15:34:33 +00009782#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009784#endif
9785#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009787#endif
9788#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009790#endif
9791#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009793#endif
9794#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009796#endif
9797#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
9800#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009802#endif
9803#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009805#endif
9806#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009808#endif
9809#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009811#endif
9812#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009814#endif
9815#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009817#endif
9818#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009820#endif
Fred Drakec9680921999-12-13 16:37:25 +00009821};
9822
9823static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009824conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009825{
9826 return conv_confname(arg, valuep, posix_constants_confstr,
9827 sizeof(posix_constants_confstr)
9828 / sizeof(struct constdef));
9829}
9830
Larry Hastings2f936352014-08-05 14:04:04 +10009831
9832/*[clinic input]
9833os.confstr
9834
9835 name: confstr_confname
9836 /
9837
9838Return a string-valued system configuration variable.
9839[clinic start generated code]*/
9840
Larry Hastings2f936352014-08-05 14:04:04 +10009841static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009842os_confstr_impl(PyObject *module, int name)
9843/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009844{
9845 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009846 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009847 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009848
Victor Stinnercb043522010-09-10 23:49:04 +00009849 errno = 0;
9850 len = confstr(name, buffer, sizeof(buffer));
9851 if (len == 0) {
9852 if (errno) {
9853 posix_error();
9854 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009855 }
9856 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009857 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009858 }
9859 }
Victor Stinnercb043522010-09-10 23:49:04 +00009860
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009861 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009862 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009863 char *buf = PyMem_Malloc(len);
9864 if (buf == NULL)
9865 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009866 len2 = confstr(name, buf, len);
9867 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009868 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009869 PyMem_Free(buf);
9870 }
9871 else
9872 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009873 return result;
9874}
Larry Hastings2f936352014-08-05 14:04:04 +10009875#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009876
9877
9878#ifdef HAVE_SYSCONF
9879static struct constdef posix_constants_sysconf[] = {
9880#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
Fred Draked86ed291999-12-15 15:34:33 +00009910#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009912#endif
9913#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009915#endif
Fred Drakec9680921999-12-13 16:37:25 +00009916#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
Fred Drakec9680921999-12-13 16:37:25 +00009919#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
Fred Draked86ed291999-12-15 15:34:33 +00009934#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009936#endif
Fred Drakec9680921999-12-13 16:37:25 +00009937#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
Fred Draked86ed291999-12-15 15:34:33 +00009952#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009954#endif
Fred Drakec9680921999-12-13 16:37:25 +00009955#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
Fred Draked86ed291999-12-15 15:34:33 +000010024#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010026#endif
Fred Drakec9680921999-12-13 16:37:25 +000010027#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
Fred Draked86ed291999-12-15 15:34:33 +000010036#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010038#endif
Fred Drakec9680921999-12-13 16:37:25 +000010039#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
Fred Draked86ed291999-12-15 15:34:33 +000010042#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010044#endif
10045#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010047#endif
Fred Drakec9680921999-12-13 16:37:25 +000010048#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
Fred Draked86ed291999-12-15 15:34:33 +000010060#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010062#endif
Fred Drakec9680921999-12-13 16:37:25 +000010063#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
Fred Draked86ed291999-12-15 15:34:33 +000010084#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010086#endif
Fred Drakec9680921999-12-13 16:37:25 +000010087#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
Fred Draked86ed291999-12-15 15:34:33 +000010093#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010095#endif
Fred Drakec9680921999-12-13 16:37:25 +000010096#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
Fred Draked86ed291999-12-15 15:34:33 +000010123#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010125#endif
10126#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010128#endif
Fred Drakec9680921999-12-13 16:37:25 +000010129#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
Fred Draked86ed291999-12-15 15:34:33 +000010234#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010236#endif
Fred Drakec9680921999-12-13 16:37:25 +000010237#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372};
10373
10374static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010375conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010376{
10377 return conv_confname(arg, valuep, posix_constants_sysconf,
10378 sizeof(posix_constants_sysconf)
10379 / sizeof(struct constdef));
10380}
10381
Larry Hastings2f936352014-08-05 14:04:04 +100010382
10383/*[clinic input]
10384os.sysconf -> long
10385 name: sysconf_confname
10386 /
10387
10388Return an integer-valued system configuration variable.
10389[clinic start generated code]*/
10390
Larry Hastings2f936352014-08-05 14:04:04 +100010391static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010392os_sysconf_impl(PyObject *module, int name)
10393/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010394{
10395 long value;
10396
10397 errno = 0;
10398 value = sysconf(name);
10399 if (value == -1 && errno != 0)
10400 posix_error();
10401 return value;
10402}
10403#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010404
10405
Fred Drakebec628d1999-12-15 18:31:10 +000010406/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010407 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010408 * the exported dictionaries that are used to publish information about the
10409 * names available on the host platform.
10410 *
10411 * Sorting the table at runtime ensures that the table is properly ordered
10412 * when used, even for platforms we're not able to test on. It also makes
10413 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010414 */
Fred Drakebec628d1999-12-15 18:31:10 +000010415
10416static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010417cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010418{
10419 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010421 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010423
10424 return strcmp(c1->name, c2->name);
10425}
10426
10427static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010428setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010429 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010430{
Fred Drakebec628d1999-12-15 18:31:10 +000010431 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010432 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010433
10434 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10435 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010436 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010438
Barry Warsaw3155db32000-04-13 15:20:40 +000010439 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 PyObject *o = PyLong_FromLong(table[i].value);
10441 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10442 Py_XDECREF(o);
10443 Py_DECREF(d);
10444 return -1;
10445 }
10446 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010447 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010448 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010449}
10450
Fred Drakebec628d1999-12-15 18:31:10 +000010451/* Return -1 on failure, 0 on success. */
10452static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010453setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010454{
10455#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010456 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010457 sizeof(posix_constants_pathconf)
10458 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010459 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010460 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010461#endif
10462#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010463 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010464 sizeof(posix_constants_confstr)
10465 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010466 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010467 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010468#endif
10469#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010470 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010471 sizeof(posix_constants_sysconf)
10472 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010473 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010474 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010475#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010476 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010477}
Fred Draked86ed291999-12-15 15:34:33 +000010478
10479
Larry Hastings2f936352014-08-05 14:04:04 +100010480/*[clinic input]
10481os.abort
10482
10483Abort the interpreter immediately.
10484
10485This function 'dumps core' or otherwise fails in the hardest way possible
10486on the hosting operating system. This function never returns.
10487[clinic start generated code]*/
10488
Larry Hastings2f936352014-08-05 14:04:04 +100010489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010490os_abort_impl(PyObject *module)
10491/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010492{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010493 abort();
10494 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010495#ifndef __clang__
10496 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10497 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10498 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010499 Py_FatalError("abort() called from Python code didn't abort!");
10500 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010501#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010502}
Fred Drakebec628d1999-12-15 18:31:10 +000010503
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010504#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010505/* Grab ShellExecute dynamically from shell32 */
10506static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010507static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10508 LPCWSTR, INT);
10509static int
10510check_ShellExecute()
10511{
10512 HINSTANCE hShell32;
10513
10514 /* only recheck */
10515 if (-1 == has_ShellExecute) {
10516 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010517 /* Security note: this call is not vulnerable to "DLL hijacking".
10518 SHELL32 is part of "KnownDLLs" and so Windows always load
10519 the system SHELL32.DLL, even if there is another SHELL32.DLL
10520 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010521 hShell32 = LoadLibraryW(L"SHELL32");
10522 Py_END_ALLOW_THREADS
10523 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010524 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10525 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010526 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010527 } else {
10528 has_ShellExecute = 0;
10529 }
10530 }
10531 return has_ShellExecute;
10532}
10533
10534
Steve Dowercc16be82016-09-08 10:35:16 -070010535/*[clinic input]
10536os.startfile
10537 filepath: path_t
10538 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010539
Steve Dowercc16be82016-09-08 10:35:16 -070010540startfile(filepath [, operation])
10541
10542Start a file with its associated application.
10543
10544When "operation" is not specified or "open", this acts like
10545double-clicking the file in Explorer, or giving the file name as an
10546argument to the DOS "start" command: the file is opened with whatever
10547application (if any) its extension is associated.
10548When another "operation" is given, it specifies what should be done with
10549the file. A typical operation is "print".
10550
10551startfile returns as soon as the associated application is launched.
10552There is no option to wait for the application to close, and no way
10553to retrieve the application's exit status.
10554
10555The filepath is relative to the current directory. If you want to use
10556an absolute path, make sure the first character is not a slash ("/");
10557the underlying Win32 ShellExecute function doesn't work if it is.
10558[clinic start generated code]*/
10559
10560static PyObject *
10561os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10562/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10563{
10564 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010565
10566 if(!check_ShellExecute()) {
10567 /* If the OS doesn't have ShellExecute, return a
10568 NotImplementedError. */
10569 return PyErr_Format(PyExc_NotImplementedError,
10570 "startfile not available on this platform");
10571 }
10572
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010574 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010575 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 Py_END_ALLOW_THREADS
10577
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010579 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010580 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 }
Steve Dowercc16be82016-09-08 10:35:16 -070010582 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010583}
Larry Hastings2f936352014-08-05 14:04:04 +100010584#endif /* MS_WINDOWS */
10585
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010586
Martin v. Löwis438b5342002-12-27 10:16:42 +000010587#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010588/*[clinic input]
10589os.getloadavg
10590
10591Return average recent system load information.
10592
10593Return the number of processes in the system run queue averaged over
10594the last 1, 5, and 15 minutes as a tuple of three floats.
10595Raises OSError if the load average was unobtainable.
10596[clinic start generated code]*/
10597
Larry Hastings2f936352014-08-05 14:04:04 +100010598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010599os_getloadavg_impl(PyObject *module)
10600/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010601{
10602 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010603 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010604 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10605 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010606 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010607 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010608}
Larry Hastings2f936352014-08-05 14:04:04 +100010609#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010610
Larry Hastings2f936352014-08-05 14:04:04 +100010611
10612/*[clinic input]
10613os.device_encoding
10614 fd: int
10615
10616Return a string describing the encoding of a terminal's file descriptor.
10617
10618The file descriptor must be attached to a terminal.
10619If the device is not a terminal, return None.
10620[clinic start generated code]*/
10621
Larry Hastings2f936352014-08-05 14:04:04 +100010622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010623os_device_encoding_impl(PyObject *module, int fd)
10624/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010625{
Brett Cannonefb00c02012-02-29 18:31:31 -050010626 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010627}
10628
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010629
Larry Hastings2f936352014-08-05 14:04:04 +100010630#ifdef HAVE_SETRESUID
10631/*[clinic input]
10632os.setresuid
10633
10634 ruid: uid_t
10635 euid: uid_t
10636 suid: uid_t
10637 /
10638
10639Set the current process's real, effective, and saved user ids.
10640[clinic start generated code]*/
10641
Larry Hastings2f936352014-08-05 14:04:04 +100010642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010643os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10644/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010645{
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 if (setresuid(ruid, euid, suid) < 0)
10647 return posix_error();
10648 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010649}
Larry Hastings2f936352014-08-05 14:04:04 +100010650#endif /* HAVE_SETRESUID */
10651
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010652
10653#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010654/*[clinic input]
10655os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010656
Larry Hastings2f936352014-08-05 14:04:04 +100010657 rgid: gid_t
10658 egid: gid_t
10659 sgid: gid_t
10660 /
10661
10662Set the current process's real, effective, and saved group ids.
10663[clinic start generated code]*/
10664
Larry Hastings2f936352014-08-05 14:04:04 +100010665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010666os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10667/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010668{
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 if (setresgid(rgid, egid, sgid) < 0)
10670 return posix_error();
10671 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010672}
Larry Hastings2f936352014-08-05 14:04:04 +100010673#endif /* HAVE_SETRESGID */
10674
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010675
10676#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010677/*[clinic input]
10678os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010679
Larry Hastings2f936352014-08-05 14:04:04 +100010680Return a tuple of the current process's real, effective, and saved user ids.
10681[clinic start generated code]*/
10682
Larry Hastings2f936352014-08-05 14:04:04 +100010683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010684os_getresuid_impl(PyObject *module)
10685/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010686{
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 if (getresuid(&ruid, &euid, &suid) < 0)
10689 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010690 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10691 _PyLong_FromUid(euid),
10692 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010693}
Larry Hastings2f936352014-08-05 14:04:04 +100010694#endif /* HAVE_GETRESUID */
10695
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010696
10697#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010698/*[clinic input]
10699os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010700
Larry Hastings2f936352014-08-05 14:04:04 +100010701Return a tuple of the current process's real, effective, and saved group ids.
10702[clinic start generated code]*/
10703
Larry Hastings2f936352014-08-05 14:04:04 +100010704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010705os_getresgid_impl(PyObject *module)
10706/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010707{
10708 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 if (getresgid(&rgid, &egid, &sgid) < 0)
10710 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010711 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10712 _PyLong_FromGid(egid),
10713 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010714}
Larry Hastings2f936352014-08-05 14:04:04 +100010715#endif /* HAVE_GETRESGID */
10716
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010717
Benjamin Peterson9428d532011-09-14 11:45:52 -040010718#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010719/*[clinic input]
10720os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010721
Larry Hastings2f936352014-08-05 14:04:04 +100010722 path: path_t(allow_fd=True)
10723 attribute: path_t
10724 *
10725 follow_symlinks: bool = True
10726
10727Return the value of extended attribute attribute on path.
10728
10729path may be either a string or an open file descriptor.
10730If follow_symlinks is False, and the last element of the path is a symbolic
10731 link, getxattr will examine the symbolic link itself instead of the file
10732 the link points to.
10733
10734[clinic start generated code]*/
10735
Larry Hastings2f936352014-08-05 14:04:04 +100010736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010737os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010738 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010739/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010740{
10741 Py_ssize_t i;
10742 PyObject *buffer = NULL;
10743
10744 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10745 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010746
Larry Hastings9cf065c2012-06-22 16:30:09 -070010747 for (i = 0; ; i++) {
10748 void *ptr;
10749 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010750 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 Py_ssize_t buffer_size = buffer_sizes[i];
10752 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010753 path_error(path);
10754 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 }
10756 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10757 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010758 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010759 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010760
Larry Hastings9cf065c2012-06-22 16:30:09 -070010761 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010762 if (path->fd >= 0)
10763 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010764 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010765 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010766 else
Larry Hastings2f936352014-08-05 14:04:04 +100010767 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010768 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010769
Larry Hastings9cf065c2012-06-22 16:30:09 -070010770 if (result < 0) {
10771 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010772 if (errno == ERANGE)
10773 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010774 path_error(path);
10775 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010776 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010777
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 if (result != buffer_size) {
10779 /* Can only shrink. */
10780 _PyBytes_Resize(&buffer, result);
10781 }
10782 break;
10783 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010784
Larry Hastings9cf065c2012-06-22 16:30:09 -070010785 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010786}
10787
Larry Hastings2f936352014-08-05 14:04:04 +100010788
10789/*[clinic input]
10790os.setxattr
10791
10792 path: path_t(allow_fd=True)
10793 attribute: path_t
10794 value: Py_buffer
10795 flags: int = 0
10796 *
10797 follow_symlinks: bool = True
10798
10799Set extended attribute attribute on path to value.
10800
10801path may be either a string or an open file descriptor.
10802If follow_symlinks is False, and the last element of the path is a symbolic
10803 link, setxattr will modify the symbolic link itself instead of the file
10804 the link points to.
10805
10806[clinic start generated code]*/
10807
Benjamin Peterson799bd802011-08-31 22:15:17 -040010808static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010809os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010810 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010811/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010812{
Larry Hastings2f936352014-08-05 14:04:04 +100010813 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010814
Larry Hastings2f936352014-08-05 14:04:04 +100010815 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010816 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010817
Benjamin Peterson799bd802011-08-31 22:15:17 -040010818 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010819 if (path->fd > -1)
10820 result = fsetxattr(path->fd, attribute->narrow,
10821 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010822 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010823 result = setxattr(path->narrow, attribute->narrow,
10824 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825 else
Larry Hastings2f936352014-08-05 14:04:04 +100010826 result = lsetxattr(path->narrow, attribute->narrow,
10827 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010828 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010829
Larry Hastings9cf065c2012-06-22 16:30:09 -070010830 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010831 path_error(path);
10832 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010833 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010834
Larry Hastings2f936352014-08-05 14:04:04 +100010835 Py_RETURN_NONE;
10836}
10837
10838
10839/*[clinic input]
10840os.removexattr
10841
10842 path: path_t(allow_fd=True)
10843 attribute: path_t
10844 *
10845 follow_symlinks: bool = True
10846
10847Remove extended attribute attribute on path.
10848
10849path may be either a string or an open file descriptor.
10850If follow_symlinks is False, and the last element of the path is a symbolic
10851 link, removexattr will modify the symbolic link itself instead of the file
10852 the link points to.
10853
10854[clinic start generated code]*/
10855
Larry Hastings2f936352014-08-05 14:04:04 +100010856static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010857os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010858 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010859/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010860{
10861 ssize_t result;
10862
10863 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10864 return NULL;
10865
10866 Py_BEGIN_ALLOW_THREADS;
10867 if (path->fd > -1)
10868 result = fremovexattr(path->fd, attribute->narrow);
10869 else if (follow_symlinks)
10870 result = removexattr(path->narrow, attribute->narrow);
10871 else
10872 result = lremovexattr(path->narrow, attribute->narrow);
10873 Py_END_ALLOW_THREADS;
10874
10875 if (result) {
10876 return path_error(path);
10877 }
10878
10879 Py_RETURN_NONE;
10880}
10881
10882
10883/*[clinic input]
10884os.listxattr
10885
10886 path: path_t(allow_fd=True, nullable=True) = None
10887 *
10888 follow_symlinks: bool = True
10889
10890Return a list of extended attributes on path.
10891
10892path may be either None, a string, or an open file descriptor.
10893if path is None, listxattr will examine the current directory.
10894If follow_symlinks is False, and the last element of the path is a symbolic
10895 link, listxattr will examine the symbolic link itself instead of the file
10896 the link points to.
10897[clinic start generated code]*/
10898
Larry Hastings2f936352014-08-05 14:04:04 +100010899static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010900os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10901/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010902{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010903 Py_ssize_t i;
10904 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010905 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010906 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010907
Larry Hastings2f936352014-08-05 14:04:04 +100010908 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010909 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910
Larry Hastings2f936352014-08-05 14:04:04 +100010911 name = path->narrow ? path->narrow : ".";
10912
Larry Hastings9cf065c2012-06-22 16:30:09 -070010913 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010914 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010915 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010916 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010917 Py_ssize_t buffer_size = buffer_sizes[i];
10918 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010919 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010920 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010921 break;
10922 }
10923 buffer = PyMem_MALLOC(buffer_size);
10924 if (!buffer) {
10925 PyErr_NoMemory();
10926 break;
10927 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010928
Larry Hastings9cf065c2012-06-22 16:30:09 -070010929 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010930 if (path->fd > -1)
10931 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010932 else if (follow_symlinks)
10933 length = listxattr(name, buffer, buffer_size);
10934 else
10935 length = llistxattr(name, buffer, buffer_size);
10936 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010937
Larry Hastings9cf065c2012-06-22 16:30:09 -070010938 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010939 if (errno == ERANGE) {
10940 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010941 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010942 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010943 }
Larry Hastings2f936352014-08-05 14:04:04 +100010944 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010945 break;
10946 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010947
Larry Hastings9cf065c2012-06-22 16:30:09 -070010948 result = PyList_New(0);
10949 if (!result) {
10950 goto exit;
10951 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010952
Larry Hastings9cf065c2012-06-22 16:30:09 -070010953 end = buffer + length;
10954 for (trace = start = buffer; trace != end; trace++) {
10955 if (!*trace) {
10956 int error;
10957 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10958 trace - start);
10959 if (!attribute) {
10960 Py_DECREF(result);
10961 result = NULL;
10962 goto exit;
10963 }
10964 error = PyList_Append(result, attribute);
10965 Py_DECREF(attribute);
10966 if (error) {
10967 Py_DECREF(result);
10968 result = NULL;
10969 goto exit;
10970 }
10971 start = trace + 1;
10972 }
10973 }
10974 break;
10975 }
10976exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010977 if (buffer)
10978 PyMem_FREE(buffer);
10979 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010980}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010981#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010982
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010983
Larry Hastings2f936352014-08-05 14:04:04 +100010984/*[clinic input]
10985os.urandom
10986
10987 size: Py_ssize_t
10988 /
10989
10990Return a bytes object containing random bytes suitable for cryptographic use.
10991[clinic start generated code]*/
10992
Larry Hastings2f936352014-08-05 14:04:04 +100010993static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010994os_urandom_impl(PyObject *module, Py_ssize_t size)
10995/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010996{
10997 PyObject *bytes;
10998 int result;
10999
Georg Brandl2fb477c2012-02-21 00:33:36 +010011000 if (size < 0)
11001 return PyErr_Format(PyExc_ValueError,
11002 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011003 bytes = PyBytes_FromStringAndSize(NULL, size);
11004 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011005 return NULL;
11006
Victor Stinnere66987e2016-09-06 16:33:52 -070011007 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011008 if (result == -1) {
11009 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011010 return NULL;
11011 }
Larry Hastings2f936352014-08-05 14:04:04 +100011012 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011013}
11014
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011015/* Terminal size querying */
11016
11017static PyTypeObject TerminalSizeType;
11018
11019PyDoc_STRVAR(TerminalSize_docstring,
11020 "A tuple of (columns, lines) for holding terminal window size");
11021
11022static PyStructSequence_Field TerminalSize_fields[] = {
11023 {"columns", "width of the terminal window in characters"},
11024 {"lines", "height of the terminal window in characters"},
11025 {NULL, NULL}
11026};
11027
11028static PyStructSequence_Desc TerminalSize_desc = {
11029 "os.terminal_size",
11030 TerminalSize_docstring,
11031 TerminalSize_fields,
11032 2,
11033};
11034
11035#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011036/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011037PyDoc_STRVAR(termsize__doc__,
11038 "Return the size of the terminal window as (columns, lines).\n" \
11039 "\n" \
11040 "The optional argument fd (default standard output) specifies\n" \
11041 "which file descriptor should be queried.\n" \
11042 "\n" \
11043 "If the file descriptor is not connected to a terminal, an OSError\n" \
11044 "is thrown.\n" \
11045 "\n" \
11046 "This function will only be defined if an implementation is\n" \
11047 "available for this system.\n" \
11048 "\n" \
11049 "shutil.get_terminal_size is the high-level function which should \n" \
11050 "normally be used, os.get_terminal_size is the low-level implementation.");
11051
11052static PyObject*
11053get_terminal_size(PyObject *self, PyObject *args)
11054{
11055 int columns, lines;
11056 PyObject *termsize;
11057
11058 int fd = fileno(stdout);
11059 /* Under some conditions stdout may not be connected and
11060 * fileno(stdout) may point to an invalid file descriptor. For example
11061 * GUI apps don't have valid standard streams by default.
11062 *
11063 * If this happens, and the optional fd argument is not present,
11064 * the ioctl below will fail returning EBADF. This is what we want.
11065 */
11066
11067 if (!PyArg_ParseTuple(args, "|i", &fd))
11068 return NULL;
11069
11070#ifdef TERMSIZE_USE_IOCTL
11071 {
11072 struct winsize w;
11073 if (ioctl(fd, TIOCGWINSZ, &w))
11074 return PyErr_SetFromErrno(PyExc_OSError);
11075 columns = w.ws_col;
11076 lines = w.ws_row;
11077 }
11078#endif /* TERMSIZE_USE_IOCTL */
11079
11080#ifdef TERMSIZE_USE_CONIO
11081 {
11082 DWORD nhandle;
11083 HANDLE handle;
11084 CONSOLE_SCREEN_BUFFER_INFO csbi;
11085 switch (fd) {
11086 case 0: nhandle = STD_INPUT_HANDLE;
11087 break;
11088 case 1: nhandle = STD_OUTPUT_HANDLE;
11089 break;
11090 case 2: nhandle = STD_ERROR_HANDLE;
11091 break;
11092 default:
11093 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11094 }
11095 handle = GetStdHandle(nhandle);
11096 if (handle == NULL)
11097 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11098 if (handle == INVALID_HANDLE_VALUE)
11099 return PyErr_SetFromWindowsErr(0);
11100
11101 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11102 return PyErr_SetFromWindowsErr(0);
11103
11104 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11105 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11106 }
11107#endif /* TERMSIZE_USE_CONIO */
11108
11109 termsize = PyStructSequence_New(&TerminalSizeType);
11110 if (termsize == NULL)
11111 return NULL;
11112 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11113 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11114 if (PyErr_Occurred()) {
11115 Py_DECREF(termsize);
11116 return NULL;
11117 }
11118 return termsize;
11119}
11120#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11121
Larry Hastings2f936352014-08-05 14:04:04 +100011122
11123/*[clinic input]
11124os.cpu_count
11125
Charles-François Natali80d62e62015-08-13 20:37:08 +010011126Return the number of CPUs in the system; return None if indeterminable.
11127
11128This number is not equivalent to the number of CPUs the current process can
11129use. The number of usable CPUs can be obtained with
11130``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011131[clinic start generated code]*/
11132
Larry Hastings2f936352014-08-05 14:04:04 +100011133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011134os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011135/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011136{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011137 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011138#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011139 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11140 Need to fallback to Vista behavior if this call isn't present */
11141 HINSTANCE hKernel32;
11142 hKernel32 = GetModuleHandleW(L"KERNEL32");
11143
11144 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11145 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11146 "GetMaximumProcessorCount");
11147 if (_GetMaximumProcessorCount != NULL) {
11148 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11149 }
11150 else {
11151 SYSTEM_INFO sysinfo;
11152 GetSystemInfo(&sysinfo);
11153 ncpu = sysinfo.dwNumberOfProcessors;
11154 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011155#elif defined(__hpux)
11156 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11157#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11158 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011159#elif defined(__DragonFly__) || \
11160 defined(__OpenBSD__) || \
11161 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011162 defined(__NetBSD__) || \
11163 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011164 int mib[2];
11165 size_t len = sizeof(ncpu);
11166 mib[0] = CTL_HW;
11167 mib[1] = HW_NCPU;
11168 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11169 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011170#endif
11171 if (ncpu >= 1)
11172 return PyLong_FromLong(ncpu);
11173 else
11174 Py_RETURN_NONE;
11175}
11176
Victor Stinnerdaf45552013-08-28 00:53:59 +020011177
Larry Hastings2f936352014-08-05 14:04:04 +100011178/*[clinic input]
11179os.get_inheritable -> bool
11180
11181 fd: int
11182 /
11183
11184Get the close-on-exe flag of the specified file descriptor.
11185[clinic start generated code]*/
11186
Larry Hastings2f936352014-08-05 14:04:04 +100011187static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011188os_get_inheritable_impl(PyObject *module, int fd)
11189/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011190{
Steve Dower8fc89802015-04-12 00:26:27 -040011191 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011192 _Py_BEGIN_SUPPRESS_IPH
11193 return_value = _Py_get_inheritable(fd);
11194 _Py_END_SUPPRESS_IPH
11195 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011196}
11197
11198
11199/*[clinic input]
11200os.set_inheritable
11201 fd: int
11202 inheritable: int
11203 /
11204
11205Set the inheritable flag of the specified file descriptor.
11206[clinic start generated code]*/
11207
Larry Hastings2f936352014-08-05 14:04:04 +100011208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011209os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11210/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011211{
Steve Dower8fc89802015-04-12 00:26:27 -040011212 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011213
Steve Dower8fc89802015-04-12 00:26:27 -040011214 _Py_BEGIN_SUPPRESS_IPH
11215 result = _Py_set_inheritable(fd, inheritable, NULL);
11216 _Py_END_SUPPRESS_IPH
11217 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011218 return NULL;
11219 Py_RETURN_NONE;
11220}
11221
11222
11223#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011224/*[clinic input]
11225os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011226 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011227 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011228
Larry Hastings2f936352014-08-05 14:04:04 +100011229Get the close-on-exe flag of the specified file descriptor.
11230[clinic start generated code]*/
11231
Larry Hastings2f936352014-08-05 14:04:04 +100011232static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011233os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011234/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011235{
11236 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011237
11238 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11239 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011240 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011241 }
11242
Larry Hastings2f936352014-08-05 14:04:04 +100011243 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011244}
11245
Victor Stinnerdaf45552013-08-28 00:53:59 +020011246
Larry Hastings2f936352014-08-05 14:04:04 +100011247/*[clinic input]
11248os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011249 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011250 inheritable: bool
11251 /
11252
11253Set the inheritable flag of the specified handle.
11254[clinic start generated code]*/
11255
Larry Hastings2f936352014-08-05 14:04:04 +100011256static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011257os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011258 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011259/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011260{
11261 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011262 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11263 PyErr_SetFromWindowsErr(0);
11264 return NULL;
11265 }
11266 Py_RETURN_NONE;
11267}
Larry Hastings2f936352014-08-05 14:04:04 +100011268#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011269
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011270#ifndef MS_WINDOWS
11271PyDoc_STRVAR(get_blocking__doc__,
11272 "get_blocking(fd) -> bool\n" \
11273 "\n" \
11274 "Get the blocking mode of the file descriptor:\n" \
11275 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11276
11277static PyObject*
11278posix_get_blocking(PyObject *self, PyObject *args)
11279{
11280 int fd;
11281 int blocking;
11282
11283 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11284 return NULL;
11285
Steve Dower8fc89802015-04-12 00:26:27 -040011286 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011287 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011288 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011289 if (blocking < 0)
11290 return NULL;
11291 return PyBool_FromLong(blocking);
11292}
11293
11294PyDoc_STRVAR(set_blocking__doc__,
11295 "set_blocking(fd, blocking)\n" \
11296 "\n" \
11297 "Set the blocking mode of the specified file descriptor.\n" \
11298 "Set the O_NONBLOCK flag if blocking is False,\n" \
11299 "clear the O_NONBLOCK flag otherwise.");
11300
11301static PyObject*
11302posix_set_blocking(PyObject *self, PyObject *args)
11303{
Steve Dower8fc89802015-04-12 00:26:27 -040011304 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011305
11306 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11307 return NULL;
11308
Steve Dower8fc89802015-04-12 00:26:27 -040011309 _Py_BEGIN_SUPPRESS_IPH
11310 result = _Py_set_blocking(fd, blocking);
11311 _Py_END_SUPPRESS_IPH
11312 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011313 return NULL;
11314 Py_RETURN_NONE;
11315}
11316#endif /* !MS_WINDOWS */
11317
11318
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011319/*[clinic input]
11320class os.DirEntry "DirEntry *" "&DirEntryType"
11321[clinic start generated code]*/
11322/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011323
11324typedef struct {
11325 PyObject_HEAD
11326 PyObject *name;
11327 PyObject *path;
11328 PyObject *stat;
11329 PyObject *lstat;
11330#ifdef MS_WINDOWS
11331 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011332 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011333 int got_file_index;
11334#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011335#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011336 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011337#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011338 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011339 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011340#endif
11341} DirEntry;
11342
11343static void
11344DirEntry_dealloc(DirEntry *entry)
11345{
11346 Py_XDECREF(entry->name);
11347 Py_XDECREF(entry->path);
11348 Py_XDECREF(entry->stat);
11349 Py_XDECREF(entry->lstat);
11350 Py_TYPE(entry)->tp_free((PyObject *)entry);
11351}
11352
11353/* Forward reference */
11354static int
11355DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11356
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011357/*[clinic input]
11358os.DirEntry.is_symlink -> bool
11359
11360Return True if the entry is a symbolic link; cached per entry.
11361[clinic start generated code]*/
11362
Victor Stinner6036e442015-03-08 01:58:04 +010011363static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011364os_DirEntry_is_symlink_impl(DirEntry *self)
11365/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011366{
11367#ifdef MS_WINDOWS
11368 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011369#elif defined(HAVE_DIRENT_D_TYPE)
11370 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011371 if (self->d_type != DT_UNKNOWN)
11372 return self->d_type == DT_LNK;
11373 else
11374 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011375#else
11376 /* POSIX without d_type */
11377 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011378#endif
11379}
11380
11381static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011382DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11383{
11384 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011385 STRUCT_STAT st;
11386 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011387
11388#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011389 if (!PyUnicode_FSDecoder(self->path, &ub))
11390 return NULL;
11391 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011392#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011393 if (!PyUnicode_FSConverter(self->path, &ub))
11394 return NULL;
11395 const char *path = PyBytes_AS_STRING(ub);
11396 if (self->dir_fd != DEFAULT_DIR_FD) {
11397#ifdef HAVE_FSTATAT
11398 result = fstatat(self->dir_fd, path, &st,
11399 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11400#else
11401 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11402 return NULL;
11403#endif /* HAVE_FSTATAT */
11404 }
11405 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011406#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011407 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011408 if (follow_symlinks)
11409 result = STAT(path, &st);
11410 else
11411 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011412 }
11413 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011414
11415 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011416 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011417
11418 return _pystat_fromstructstat(&st);
11419}
11420
11421static PyObject *
11422DirEntry_get_lstat(DirEntry *self)
11423{
11424 if (!self->lstat) {
11425#ifdef MS_WINDOWS
11426 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11427#else /* POSIX */
11428 self->lstat = DirEntry_fetch_stat(self, 0);
11429#endif
11430 }
11431 Py_XINCREF(self->lstat);
11432 return self->lstat;
11433}
11434
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011435/*[clinic input]
11436os.DirEntry.stat
11437 *
11438 follow_symlinks: bool = True
11439
11440Return stat_result object for the entry; cached per entry.
11441[clinic start generated code]*/
11442
Victor Stinner6036e442015-03-08 01:58:04 +010011443static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011444os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11445/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011446{
11447 if (!follow_symlinks)
11448 return DirEntry_get_lstat(self);
11449
11450 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011451 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011452 if (result == -1)
11453 return NULL;
11454 else if (result)
11455 self->stat = DirEntry_fetch_stat(self, 1);
11456 else
11457 self->stat = DirEntry_get_lstat(self);
11458 }
11459
11460 Py_XINCREF(self->stat);
11461 return self->stat;
11462}
11463
Victor Stinner6036e442015-03-08 01:58:04 +010011464/* Set exception and return -1 on error, 0 for False, 1 for True */
11465static int
11466DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11467{
11468 PyObject *stat = NULL;
11469 PyObject *st_mode = NULL;
11470 long mode;
11471 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011472#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011473 int is_symlink;
11474 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011475#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011476#ifdef MS_WINDOWS
11477 unsigned long dir_bits;
11478#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011479 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011480
11481#ifdef MS_WINDOWS
11482 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11483 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011484#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011485 is_symlink = self->d_type == DT_LNK;
11486 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11487#endif
11488
Victor Stinner35a97c02015-03-08 02:59:09 +010011489#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011490 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011491#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011492 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011493 if (!stat) {
11494 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11495 /* If file doesn't exist (anymore), then return False
11496 (i.e., say it's not a file/directory) */
11497 PyErr_Clear();
11498 return 0;
11499 }
11500 goto error;
11501 }
11502 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11503 if (!st_mode)
11504 goto error;
11505
11506 mode = PyLong_AsLong(st_mode);
11507 if (mode == -1 && PyErr_Occurred())
11508 goto error;
11509 Py_CLEAR(st_mode);
11510 Py_CLEAR(stat);
11511 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011512#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011513 }
11514 else if (is_symlink) {
11515 assert(mode_bits != S_IFLNK);
11516 result = 0;
11517 }
11518 else {
11519 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11520#ifdef MS_WINDOWS
11521 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11522 if (mode_bits == S_IFDIR)
11523 result = dir_bits != 0;
11524 else
11525 result = dir_bits == 0;
11526#else /* POSIX */
11527 if (mode_bits == S_IFDIR)
11528 result = self->d_type == DT_DIR;
11529 else
11530 result = self->d_type == DT_REG;
11531#endif
11532 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011533#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011534
11535 return result;
11536
11537error:
11538 Py_XDECREF(st_mode);
11539 Py_XDECREF(stat);
11540 return -1;
11541}
11542
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011543/*[clinic input]
11544os.DirEntry.is_dir -> bool
11545 *
11546 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011547
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011548Return True if the entry is a directory; cached per entry.
11549[clinic start generated code]*/
11550
11551static int
11552os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11553/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11554{
11555 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011556}
11557
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011558/*[clinic input]
11559os.DirEntry.is_file -> bool
11560 *
11561 follow_symlinks: bool = True
11562
11563Return True if the entry is a file; cached per entry.
11564[clinic start generated code]*/
11565
11566static int
11567os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11568/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011569{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011570 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011571}
11572
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011573/*[clinic input]
11574os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011575
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011576Return inode of the entry; cached per entry.
11577[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011578
11579static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011580os_DirEntry_inode_impl(DirEntry *self)
11581/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011582{
11583#ifdef MS_WINDOWS
11584 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011585 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011586 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011587 STRUCT_STAT stat;
11588 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011589
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011590 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011591 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011592 path = PyUnicode_AsUnicode(unicode);
11593 result = LSTAT(path, &stat);
11594 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011595
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011596 if (result != 0)
11597 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011598
11599 self->win32_file_index = stat.st_ino;
11600 self->got_file_index = 1;
11601 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011602 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11603 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011604#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011605 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11606 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011607#endif
11608}
11609
11610static PyObject *
11611DirEntry_repr(DirEntry *self)
11612{
11613 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11614}
11615
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011616/*[clinic input]
11617os.DirEntry.__fspath__
11618
11619Returns the path for the entry.
11620[clinic start generated code]*/
11621
Brett Cannon96881cd2016-06-10 14:37:21 -070011622static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011623os_DirEntry___fspath___impl(DirEntry *self)
11624/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011625{
11626 Py_INCREF(self->path);
11627 return self->path;
11628}
11629
Victor Stinner6036e442015-03-08 01:58:04 +010011630static PyMemberDef DirEntry_members[] = {
11631 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11632 "the entry's base filename, relative to scandir() \"path\" argument"},
11633 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11634 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11635 {NULL}
11636};
11637
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011638#include "clinic/posixmodule.c.h"
11639
Victor Stinner6036e442015-03-08 01:58:04 +010011640static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011641 OS_DIRENTRY_IS_DIR_METHODDEF
11642 OS_DIRENTRY_IS_FILE_METHODDEF
11643 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11644 OS_DIRENTRY_STAT_METHODDEF
11645 OS_DIRENTRY_INODE_METHODDEF
11646 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011647 {NULL}
11648};
11649
Benjamin Peterson5646de42015-04-12 17:56:34 -040011650static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011651 PyVarObject_HEAD_INIT(NULL, 0)
11652 MODNAME ".DirEntry", /* tp_name */
11653 sizeof(DirEntry), /* tp_basicsize */
11654 0, /* tp_itemsize */
11655 /* methods */
11656 (destructor)DirEntry_dealloc, /* tp_dealloc */
11657 0, /* tp_print */
11658 0, /* tp_getattr */
11659 0, /* tp_setattr */
11660 0, /* tp_compare */
11661 (reprfunc)DirEntry_repr, /* tp_repr */
11662 0, /* tp_as_number */
11663 0, /* tp_as_sequence */
11664 0, /* tp_as_mapping */
11665 0, /* tp_hash */
11666 0, /* tp_call */
11667 0, /* tp_str */
11668 0, /* tp_getattro */
11669 0, /* tp_setattro */
11670 0, /* tp_as_buffer */
11671 Py_TPFLAGS_DEFAULT, /* tp_flags */
11672 0, /* tp_doc */
11673 0, /* tp_traverse */
11674 0, /* tp_clear */
11675 0, /* tp_richcompare */
11676 0, /* tp_weaklistoffset */
11677 0, /* tp_iter */
11678 0, /* tp_iternext */
11679 DirEntry_methods, /* tp_methods */
11680 DirEntry_members, /* tp_members */
11681};
11682
11683#ifdef MS_WINDOWS
11684
11685static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011686join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011687{
11688 Py_ssize_t path_len;
11689 Py_ssize_t size;
11690 wchar_t *result;
11691 wchar_t ch;
11692
11693 if (!path_wide) { /* Default arg: "." */
11694 path_wide = L".";
11695 path_len = 1;
11696 }
11697 else {
11698 path_len = wcslen(path_wide);
11699 }
11700
11701 /* The +1's are for the path separator and the NUL */
11702 size = path_len + 1 + wcslen(filename) + 1;
11703 result = PyMem_New(wchar_t, size);
11704 if (!result) {
11705 PyErr_NoMemory();
11706 return NULL;
11707 }
11708 wcscpy(result, path_wide);
11709 if (path_len > 0) {
11710 ch = result[path_len - 1];
11711 if (ch != SEP && ch != ALTSEP && ch != L':')
11712 result[path_len++] = SEP;
11713 wcscpy(result + path_len, filename);
11714 }
11715 return result;
11716}
11717
11718static PyObject *
11719DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11720{
11721 DirEntry *entry;
11722 BY_HANDLE_FILE_INFORMATION file_info;
11723 ULONG reparse_tag;
11724 wchar_t *joined_path;
11725
11726 entry = PyObject_New(DirEntry, &DirEntryType);
11727 if (!entry)
11728 return NULL;
11729 entry->name = NULL;
11730 entry->path = NULL;
11731 entry->stat = NULL;
11732 entry->lstat = NULL;
11733 entry->got_file_index = 0;
11734
11735 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11736 if (!entry->name)
11737 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011738 if (path->narrow) {
11739 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11740 if (!entry->name)
11741 goto error;
11742 }
Victor Stinner6036e442015-03-08 01:58:04 +010011743
11744 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11745 if (!joined_path)
11746 goto error;
11747
11748 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11749 PyMem_Free(joined_path);
11750 if (!entry->path)
11751 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011752 if (path->narrow) {
11753 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11754 if (!entry->path)
11755 goto error;
11756 }
Victor Stinner6036e442015-03-08 01:58:04 +010011757
Steve Dowercc16be82016-09-08 10:35:16 -070011758 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011759 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11760
11761 return (PyObject *)entry;
11762
11763error:
11764 Py_DECREF(entry);
11765 return NULL;
11766}
11767
11768#else /* POSIX */
11769
11770static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011771join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011772{
11773 Py_ssize_t path_len;
11774 Py_ssize_t size;
11775 char *result;
11776
11777 if (!path_narrow) { /* Default arg: "." */
11778 path_narrow = ".";
11779 path_len = 1;
11780 }
11781 else {
11782 path_len = strlen(path_narrow);
11783 }
11784
11785 if (filename_len == -1)
11786 filename_len = strlen(filename);
11787
11788 /* The +1's are for the path separator and the NUL */
11789 size = path_len + 1 + filename_len + 1;
11790 result = PyMem_New(char, size);
11791 if (!result) {
11792 PyErr_NoMemory();
11793 return NULL;
11794 }
11795 strcpy(result, path_narrow);
11796 if (path_len > 0 && result[path_len - 1] != '/')
11797 result[path_len++] = '/';
11798 strcpy(result + path_len, filename);
11799 return result;
11800}
11801
11802static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011803DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011804 ino_t d_ino
11805#ifdef HAVE_DIRENT_D_TYPE
11806 , unsigned char d_type
11807#endif
11808 )
Victor Stinner6036e442015-03-08 01:58:04 +010011809{
11810 DirEntry *entry;
11811 char *joined_path;
11812
11813 entry = PyObject_New(DirEntry, &DirEntryType);
11814 if (!entry)
11815 return NULL;
11816 entry->name = NULL;
11817 entry->path = NULL;
11818 entry->stat = NULL;
11819 entry->lstat = NULL;
11820
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011821 if (path->fd != -1) {
11822 entry->dir_fd = path->fd;
11823 joined_path = NULL;
11824 }
11825 else {
11826 entry->dir_fd = DEFAULT_DIR_FD;
11827 joined_path = join_path_filename(path->narrow, name, name_len);
11828 if (!joined_path)
11829 goto error;
11830 }
Victor Stinner6036e442015-03-08 01:58:04 +010011831
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030011832 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010011833 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011834 if (joined_path)
11835 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011836 }
11837 else {
11838 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011839 if (joined_path)
11840 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010011841 }
11842 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011843 if (!entry->name)
11844 goto error;
11845
11846 if (path->fd != -1) {
11847 entry->path = entry->name;
11848 Py_INCREF(entry->path);
11849 }
11850 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010011851 goto error;
11852
Victor Stinner35a97c02015-03-08 02:59:09 +010011853#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011854 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011855#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011856 entry->d_ino = d_ino;
11857
11858 return (PyObject *)entry;
11859
11860error:
11861 Py_XDECREF(entry);
11862 return NULL;
11863}
11864
11865#endif
11866
11867
11868typedef struct {
11869 PyObject_HEAD
11870 path_t path;
11871#ifdef MS_WINDOWS
11872 HANDLE handle;
11873 WIN32_FIND_DATAW file_data;
11874 int first_time;
11875#else /* POSIX */
11876 DIR *dirp;
11877#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011878#ifdef HAVE_FDOPENDIR
11879 int fd;
11880#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011881} ScandirIterator;
11882
11883#ifdef MS_WINDOWS
11884
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011885static int
11886ScandirIterator_is_closed(ScandirIterator *iterator)
11887{
11888 return iterator->handle == INVALID_HANDLE_VALUE;
11889}
11890
Victor Stinner6036e442015-03-08 01:58:04 +010011891static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011892ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011893{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011894 HANDLE handle = iterator->handle;
11895
11896 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011897 return;
11898
Victor Stinner6036e442015-03-08 01:58:04 +010011899 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011900 Py_BEGIN_ALLOW_THREADS
11901 FindClose(handle);
11902 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011903}
11904
11905static PyObject *
11906ScandirIterator_iternext(ScandirIterator *iterator)
11907{
11908 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11909 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011910 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011911
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011912 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011913 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011914 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011915
11916 while (1) {
11917 if (!iterator->first_time) {
11918 Py_BEGIN_ALLOW_THREADS
11919 success = FindNextFileW(iterator->handle, file_data);
11920 Py_END_ALLOW_THREADS
11921 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011922 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011923 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011924 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011925 break;
11926 }
11927 }
11928 iterator->first_time = 0;
11929
11930 /* Skip over . and .. */
11931 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011932 wcscmp(file_data->cFileName, L"..") != 0) {
11933 entry = DirEntry_from_find_data(&iterator->path, file_data);
11934 if (!entry)
11935 break;
11936 return entry;
11937 }
Victor Stinner6036e442015-03-08 01:58:04 +010011938
11939 /* Loop till we get a non-dot directory or finish iterating */
11940 }
11941
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011942 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011943 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011944 return NULL;
11945}
11946
11947#else /* POSIX */
11948
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011949static int
11950ScandirIterator_is_closed(ScandirIterator *iterator)
11951{
11952 return !iterator->dirp;
11953}
11954
Victor Stinner6036e442015-03-08 01:58:04 +010011955static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011956ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011957{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011958 DIR *dirp = iterator->dirp;
11959
11960 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011961 return;
11962
Victor Stinner6036e442015-03-08 01:58:04 +010011963 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011964 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011965#ifdef HAVE_FDOPENDIR
11966 if (iterator->path.fd != -1)
11967 rewinddir(dirp);
11968#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011969 closedir(dirp);
11970 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011971 return;
11972}
11973
11974static PyObject *
11975ScandirIterator_iternext(ScandirIterator *iterator)
11976{
11977 struct dirent *direntp;
11978 Py_ssize_t name_len;
11979 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011980 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011981
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011982 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011983 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011984 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011985
11986 while (1) {
11987 errno = 0;
11988 Py_BEGIN_ALLOW_THREADS
11989 direntp = readdir(iterator->dirp);
11990 Py_END_ALLOW_THREADS
11991
11992 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011993 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011994 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011995 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011996 break;
11997 }
11998
11999 /* Skip over . and .. */
12000 name_len = NAMLEN(direntp);
12001 is_dot = direntp->d_name[0] == '.' &&
12002 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12003 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012004 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012005 name_len, direntp->d_ino
12006#ifdef HAVE_DIRENT_D_TYPE
12007 , direntp->d_type
12008#endif
12009 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012010 if (!entry)
12011 break;
12012 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012013 }
12014
12015 /* Loop till we get a non-dot directory or finish iterating */
12016 }
12017
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012018 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012019 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012020 return NULL;
12021}
12022
12023#endif
12024
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012025static PyObject *
12026ScandirIterator_close(ScandirIterator *self, PyObject *args)
12027{
12028 ScandirIterator_closedir(self);
12029 Py_RETURN_NONE;
12030}
12031
12032static PyObject *
12033ScandirIterator_enter(PyObject *self, PyObject *args)
12034{
12035 Py_INCREF(self);
12036 return self;
12037}
12038
12039static PyObject *
12040ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12041{
12042 ScandirIterator_closedir(self);
12043 Py_RETURN_NONE;
12044}
12045
Victor Stinner6036e442015-03-08 01:58:04 +010012046static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012047ScandirIterator_finalize(ScandirIterator *iterator)
12048{
12049 PyObject *error_type, *error_value, *error_traceback;
12050
12051 /* Save the current exception, if any. */
12052 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12053
12054 if (!ScandirIterator_is_closed(iterator)) {
12055 ScandirIterator_closedir(iterator);
12056
12057 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12058 "unclosed scandir iterator %R", iterator)) {
12059 /* Spurious errors can appear at shutdown */
12060 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12061 PyErr_WriteUnraisable((PyObject *) iterator);
12062 }
12063 }
12064 }
12065
Victor Stinner7bfa4092016-03-23 00:43:54 +010012066 path_cleanup(&iterator->path);
12067
12068 /* Restore the saved exception. */
12069 PyErr_Restore(error_type, error_value, error_traceback);
12070}
12071
12072static void
Victor Stinner6036e442015-03-08 01:58:04 +010012073ScandirIterator_dealloc(ScandirIterator *iterator)
12074{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012075 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12076 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012077
Victor Stinner6036e442015-03-08 01:58:04 +010012078 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12079}
12080
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012081static PyMethodDef ScandirIterator_methods[] = {
12082 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12083 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12084 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12085 {NULL}
12086};
12087
Benjamin Peterson5646de42015-04-12 17:56:34 -040012088static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012089 PyVarObject_HEAD_INIT(NULL, 0)
12090 MODNAME ".ScandirIterator", /* tp_name */
12091 sizeof(ScandirIterator), /* tp_basicsize */
12092 0, /* tp_itemsize */
12093 /* methods */
12094 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12095 0, /* tp_print */
12096 0, /* tp_getattr */
12097 0, /* tp_setattr */
12098 0, /* tp_compare */
12099 0, /* tp_repr */
12100 0, /* tp_as_number */
12101 0, /* tp_as_sequence */
12102 0, /* tp_as_mapping */
12103 0, /* tp_hash */
12104 0, /* tp_call */
12105 0, /* tp_str */
12106 0, /* tp_getattro */
12107 0, /* tp_setattro */
12108 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012109 Py_TPFLAGS_DEFAULT
12110 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012111 0, /* tp_doc */
12112 0, /* tp_traverse */
12113 0, /* tp_clear */
12114 0, /* tp_richcompare */
12115 0, /* tp_weaklistoffset */
12116 PyObject_SelfIter, /* tp_iter */
12117 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012118 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012119 0, /* tp_members */
12120 0, /* tp_getset */
12121 0, /* tp_base */
12122 0, /* tp_dict */
12123 0, /* tp_descr_get */
12124 0, /* tp_descr_set */
12125 0, /* tp_dictoffset */
12126 0, /* tp_init */
12127 0, /* tp_alloc */
12128 0, /* tp_new */
12129 0, /* tp_free */
12130 0, /* tp_is_gc */
12131 0, /* tp_bases */
12132 0, /* tp_mro */
12133 0, /* tp_cache */
12134 0, /* tp_subclasses */
12135 0, /* tp_weaklist */
12136 0, /* tp_del */
12137 0, /* tp_version_tag */
12138 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012139};
12140
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012141/*[clinic input]
12142os.scandir
12143
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012144 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012145
12146Return an iterator of DirEntry objects for given path.
12147
12148path can be specified as either str, bytes or path-like object. If path
12149is bytes, the names of yielded DirEntry objects will also be bytes; in
12150all other circumstances they will be str.
12151
12152If path is None, uses the path='.'.
12153[clinic start generated code]*/
12154
Victor Stinner6036e442015-03-08 01:58:04 +010012155static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012156os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012157/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012158{
12159 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012160#ifdef MS_WINDOWS
12161 wchar_t *path_strW;
12162#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012163 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012164#ifdef HAVE_FDOPENDIR
12165 int fd = -1;
12166#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012167#endif
12168
12169 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12170 if (!iterator)
12171 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012172
12173#ifdef MS_WINDOWS
12174 iterator->handle = INVALID_HANDLE_VALUE;
12175#else
12176 iterator->dirp = NULL;
12177#endif
12178
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012179 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012180 /* Move the ownership to iterator->path */
12181 path->object = NULL;
12182 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012183
12184#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012185 iterator->first_time = 1;
12186
12187 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12188 if (!path_strW)
12189 goto error;
12190
12191 Py_BEGIN_ALLOW_THREADS
12192 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12193 Py_END_ALLOW_THREADS
12194
12195 PyMem_Free(path_strW);
12196
12197 if (iterator->handle == INVALID_HANDLE_VALUE) {
12198 path_error(&iterator->path);
12199 goto error;
12200 }
12201#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012202 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012203#ifdef HAVE_FDOPENDIR
12204 if (path->fd != -1) {
12205 /* closedir() closes the FD, so we duplicate it */
12206 fd = _Py_dup(path->fd);
12207 if (fd == -1)
12208 goto error;
12209
12210 Py_BEGIN_ALLOW_THREADS
12211 iterator->dirp = fdopendir(fd);
12212 Py_END_ALLOW_THREADS
12213 }
12214 else
12215#endif
12216 {
12217 if (iterator->path.narrow)
12218 path_str = iterator->path.narrow;
12219 else
12220 path_str = ".";
12221
12222 Py_BEGIN_ALLOW_THREADS
12223 iterator->dirp = opendir(path_str);
12224 Py_END_ALLOW_THREADS
12225 }
Victor Stinner6036e442015-03-08 01:58:04 +010012226
12227 if (!iterator->dirp) {
12228 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012229#ifdef HAVE_FDOPENDIR
12230 if (fd != -1) {
12231 Py_BEGIN_ALLOW_THREADS
12232 close(fd);
12233 Py_END_ALLOW_THREADS
12234 }
12235#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012236 goto error;
12237 }
12238#endif
12239
12240 return (PyObject *)iterator;
12241
12242error:
12243 Py_DECREF(iterator);
12244 return NULL;
12245}
12246
Ethan Furman410ef8e2016-06-04 12:06:26 -070012247/*
12248 Return the file system path representation of the object.
12249
12250 If the object is str or bytes, then allow it to pass through with
12251 an incremented refcount. If the object defines __fspath__(), then
12252 return the result of that method. All other types raise a TypeError.
12253*/
12254PyObject *
12255PyOS_FSPath(PyObject *path)
12256{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012257 /* For error message reasons, this function is manually inlined in
12258 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012259 _Py_IDENTIFIER(__fspath__);
12260 PyObject *func = NULL;
12261 PyObject *path_repr = NULL;
12262
12263 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12264 Py_INCREF(path);
12265 return path;
12266 }
12267
12268 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12269 if (NULL == func) {
12270 return PyErr_Format(PyExc_TypeError,
12271 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012272 "not %.200s",
12273 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012274 }
12275
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012276 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012277 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012278 if (NULL == path_repr) {
12279 return NULL;
12280 }
12281
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012282 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12283 PyErr_Format(PyExc_TypeError,
12284 "expected %.200s.__fspath__() to return str or bytes, "
12285 "not %.200s", Py_TYPE(path)->tp_name,
12286 Py_TYPE(path_repr)->tp_name);
12287 Py_DECREF(path_repr);
12288 return NULL;
12289 }
12290
Ethan Furman410ef8e2016-06-04 12:06:26 -070012291 return path_repr;
12292}
12293
12294/*[clinic input]
12295os.fspath
12296
12297 path: object
12298
12299Return the file system path representation of the object.
12300
Brett Cannonb4f43e92016-06-09 14:32:08 -070012301If the object is str or bytes, then allow it to pass through as-is. If the
12302object defines __fspath__(), then return the result of that method. All other
12303types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012304[clinic start generated code]*/
12305
12306static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012307os_fspath_impl(PyObject *module, PyObject *path)
12308/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012309{
12310 return PyOS_FSPath(path);
12311}
Victor Stinner6036e442015-03-08 01:58:04 +010012312
Victor Stinner9b1f4742016-09-06 16:18:52 -070012313#ifdef HAVE_GETRANDOM_SYSCALL
12314/*[clinic input]
12315os.getrandom
12316
12317 size: Py_ssize_t
12318 flags: int=0
12319
12320Obtain a series of random bytes.
12321[clinic start generated code]*/
12322
12323static PyObject *
12324os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12325/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12326{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012327 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012328 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012329
12330 if (size < 0) {
12331 errno = EINVAL;
12332 return posix_error();
12333 }
12334
Victor Stinnerec2319c2016-09-20 23:00:59 +020012335 bytes = PyBytes_FromStringAndSize(NULL, size);
12336 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012337 PyErr_NoMemory();
12338 return NULL;
12339 }
12340
12341 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012342 n = syscall(SYS_getrandom,
12343 PyBytes_AS_STRING(bytes),
12344 PyBytes_GET_SIZE(bytes),
12345 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012346 if (n < 0 && errno == EINTR) {
12347 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012348 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012349 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012350
12351 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012352 continue;
12353 }
12354 break;
12355 }
12356
12357 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012358 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012359 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012360 }
12361
Victor Stinnerec2319c2016-09-20 23:00:59 +020012362 if (n != size) {
12363 _PyBytes_Resize(&bytes, n);
12364 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012365
12366 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012367
12368error:
12369 Py_DECREF(bytes);
12370 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012371}
12372#endif /* HAVE_GETRANDOM_SYSCALL */
12373
Larry Hastings31826802013-10-19 00:09:25 -070012374
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012375static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012376
12377 OS_STAT_METHODDEF
12378 OS_ACCESS_METHODDEF
12379 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012380 OS_CHDIR_METHODDEF
12381 OS_CHFLAGS_METHODDEF
12382 OS_CHMOD_METHODDEF
12383 OS_FCHMOD_METHODDEF
12384 OS_LCHMOD_METHODDEF
12385 OS_CHOWN_METHODDEF
12386 OS_FCHOWN_METHODDEF
12387 OS_LCHOWN_METHODDEF
12388 OS_LCHFLAGS_METHODDEF
12389 OS_CHROOT_METHODDEF
12390 OS_CTERMID_METHODDEF
12391 OS_GETCWD_METHODDEF
12392 OS_GETCWDB_METHODDEF
12393 OS_LINK_METHODDEF
12394 OS_LISTDIR_METHODDEF
12395 OS_LSTAT_METHODDEF
12396 OS_MKDIR_METHODDEF
12397 OS_NICE_METHODDEF
12398 OS_GETPRIORITY_METHODDEF
12399 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012400#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012401 {"readlink", (PyCFunction)posix_readlink,
12402 METH_VARARGS | METH_KEYWORDS,
12403 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012404#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012405#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012406 {"readlink", (PyCFunction)win_readlink,
12407 METH_VARARGS | METH_KEYWORDS,
12408 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012409#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012410 OS_RENAME_METHODDEF
12411 OS_REPLACE_METHODDEF
12412 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012413 OS_SYMLINK_METHODDEF
12414 OS_SYSTEM_METHODDEF
12415 OS_UMASK_METHODDEF
12416 OS_UNAME_METHODDEF
12417 OS_UNLINK_METHODDEF
12418 OS_REMOVE_METHODDEF
12419 OS_UTIME_METHODDEF
12420 OS_TIMES_METHODDEF
12421 OS__EXIT_METHODDEF
12422 OS_EXECV_METHODDEF
12423 OS_EXECVE_METHODDEF
12424 OS_SPAWNV_METHODDEF
12425 OS_SPAWNVE_METHODDEF
12426 OS_FORK1_METHODDEF
12427 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012428 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012429 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12430 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12431 OS_SCHED_GETPARAM_METHODDEF
12432 OS_SCHED_GETSCHEDULER_METHODDEF
12433 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12434 OS_SCHED_SETPARAM_METHODDEF
12435 OS_SCHED_SETSCHEDULER_METHODDEF
12436 OS_SCHED_YIELD_METHODDEF
12437 OS_SCHED_SETAFFINITY_METHODDEF
12438 OS_SCHED_GETAFFINITY_METHODDEF
12439 OS_OPENPTY_METHODDEF
12440 OS_FORKPTY_METHODDEF
12441 OS_GETEGID_METHODDEF
12442 OS_GETEUID_METHODDEF
12443 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012444#ifdef HAVE_GETGROUPLIST
12445 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12446#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012447 OS_GETGROUPS_METHODDEF
12448 OS_GETPID_METHODDEF
12449 OS_GETPGRP_METHODDEF
12450 OS_GETPPID_METHODDEF
12451 OS_GETUID_METHODDEF
12452 OS_GETLOGIN_METHODDEF
12453 OS_KILL_METHODDEF
12454 OS_KILLPG_METHODDEF
12455 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012456#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012457 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012458#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012459 OS_SETUID_METHODDEF
12460 OS_SETEUID_METHODDEF
12461 OS_SETREUID_METHODDEF
12462 OS_SETGID_METHODDEF
12463 OS_SETEGID_METHODDEF
12464 OS_SETREGID_METHODDEF
12465 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012466#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012467 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012468#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012469 OS_GETPGID_METHODDEF
12470 OS_SETPGRP_METHODDEF
12471 OS_WAIT_METHODDEF
12472 OS_WAIT3_METHODDEF
12473 OS_WAIT4_METHODDEF
12474 OS_WAITID_METHODDEF
12475 OS_WAITPID_METHODDEF
12476 OS_GETSID_METHODDEF
12477 OS_SETSID_METHODDEF
12478 OS_SETPGID_METHODDEF
12479 OS_TCGETPGRP_METHODDEF
12480 OS_TCSETPGRP_METHODDEF
12481 OS_OPEN_METHODDEF
12482 OS_CLOSE_METHODDEF
12483 OS_CLOSERANGE_METHODDEF
12484 OS_DEVICE_ENCODING_METHODDEF
12485 OS_DUP_METHODDEF
12486 OS_DUP2_METHODDEF
12487 OS_LOCKF_METHODDEF
12488 OS_LSEEK_METHODDEF
12489 OS_READ_METHODDEF
12490 OS_READV_METHODDEF
12491 OS_PREAD_METHODDEF
12492 OS_WRITE_METHODDEF
12493 OS_WRITEV_METHODDEF
12494 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012495#ifdef HAVE_SENDFILE
12496 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12497 posix_sendfile__doc__},
12498#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012499 OS_FSTAT_METHODDEF
12500 OS_ISATTY_METHODDEF
12501 OS_PIPE_METHODDEF
12502 OS_PIPE2_METHODDEF
12503 OS_MKFIFO_METHODDEF
12504 OS_MKNOD_METHODDEF
12505 OS_MAJOR_METHODDEF
12506 OS_MINOR_METHODDEF
12507 OS_MAKEDEV_METHODDEF
12508 OS_FTRUNCATE_METHODDEF
12509 OS_TRUNCATE_METHODDEF
12510 OS_POSIX_FALLOCATE_METHODDEF
12511 OS_POSIX_FADVISE_METHODDEF
12512 OS_PUTENV_METHODDEF
12513 OS_UNSETENV_METHODDEF
12514 OS_STRERROR_METHODDEF
12515 OS_FCHDIR_METHODDEF
12516 OS_FSYNC_METHODDEF
12517 OS_SYNC_METHODDEF
12518 OS_FDATASYNC_METHODDEF
12519 OS_WCOREDUMP_METHODDEF
12520 OS_WIFCONTINUED_METHODDEF
12521 OS_WIFSTOPPED_METHODDEF
12522 OS_WIFSIGNALED_METHODDEF
12523 OS_WIFEXITED_METHODDEF
12524 OS_WEXITSTATUS_METHODDEF
12525 OS_WTERMSIG_METHODDEF
12526 OS_WSTOPSIG_METHODDEF
12527 OS_FSTATVFS_METHODDEF
12528 OS_STATVFS_METHODDEF
12529 OS_CONFSTR_METHODDEF
12530 OS_SYSCONF_METHODDEF
12531 OS_FPATHCONF_METHODDEF
12532 OS_PATHCONF_METHODDEF
12533 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012534 OS__GETFULLPATHNAME_METHODDEF
12535 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012536 OS__GETDISKUSAGE_METHODDEF
12537 OS__GETFINALPATHNAME_METHODDEF
12538 OS__GETVOLUMEPATHNAME_METHODDEF
12539 OS_GETLOADAVG_METHODDEF
12540 OS_URANDOM_METHODDEF
12541 OS_SETRESUID_METHODDEF
12542 OS_SETRESGID_METHODDEF
12543 OS_GETRESUID_METHODDEF
12544 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012545
Larry Hastings2f936352014-08-05 14:04:04 +100012546 OS_GETXATTR_METHODDEF
12547 OS_SETXATTR_METHODDEF
12548 OS_REMOVEXATTR_METHODDEF
12549 OS_LISTXATTR_METHODDEF
12550
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012551#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12552 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12553#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012554 OS_CPU_COUNT_METHODDEF
12555 OS_GET_INHERITABLE_METHODDEF
12556 OS_SET_INHERITABLE_METHODDEF
12557 OS_GET_HANDLE_INHERITABLE_METHODDEF
12558 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012559#ifndef MS_WINDOWS
12560 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12561 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12562#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012563 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012564 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012565 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012566 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012567};
12568
12569
Brian Curtin52173d42010-12-02 18:29:18 +000012570#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012571static int
Brian Curtin52173d42010-12-02 18:29:18 +000012572enable_symlink()
12573{
12574 HANDLE tok;
12575 TOKEN_PRIVILEGES tok_priv;
12576 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012577
12578 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012579 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012580
12581 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012582 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012583
12584 tok_priv.PrivilegeCount = 1;
12585 tok_priv.Privileges[0].Luid = luid;
12586 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12587
12588 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12589 sizeof(TOKEN_PRIVILEGES),
12590 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012591 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012592
Brian Curtin3b4499c2010-12-28 14:31:47 +000012593 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12594 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012595}
12596#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12597
Barry Warsaw4a342091996-12-19 23:50:02 +000012598static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012600{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012601#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012603#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012604#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012606#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012607#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012609#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012610#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012612#endif
Fred Drakec9680921999-12-13 16:37:25 +000012613#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012614 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012615#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012616#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012618#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012619#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012620 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012621#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012622#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012623 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012624#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012625#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012626 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012627#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012628#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012629 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012630#endif
12631#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012633#endif
12634#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012636#endif
12637#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012639#endif
12640#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012642#endif
12643#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012645#endif
12646#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012648#endif
12649#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012651#endif
12652#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012654#endif
12655#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012657#endif
12658#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012660#endif
12661#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012663#endif
12664#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012666#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012667#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012669#endif
12670#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012672#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012673#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012675#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012676#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012678#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012679#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012680#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012682#endif
12683#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012685#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012686#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012687#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012689#endif
12690#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012692#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012693#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012695#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012696#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012698#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012699#ifdef O_TMPFILE
12700 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12701#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012702#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012704#endif
12705#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012707#endif
12708#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012709 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012710#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012711#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012712 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012713#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012714#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012715 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012716#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012717
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012718
Jesus Cea94363612012-06-22 18:32:07 +020012719#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012721#endif
12722#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012724#endif
12725
Tim Peters5aa91602002-01-30 05:46:57 +000012726/* MS Windows */
12727#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012728 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012730#endif
12731#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012732 /* Optimize for short life (keep in memory). */
12733 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012735#endif
12736#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012737 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012739#endif
12740#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012741 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012742 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012743#endif
12744#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012745 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012747#endif
12748
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012749/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012750#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012751 /* Send a SIGIO signal whenever input or output
12752 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012754#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012755#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012756 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012758#endif
12759#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012760 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012762#endif
12763#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012764 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012766#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012767#ifdef O_NOLINKS
12768 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012770#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012771#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012772 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012774#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012775
Victor Stinner8c62be82010-05-06 00:08:46 +000012776 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012777#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012778 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012779#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012780#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012781 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012782#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012783#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012784 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012785#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012786#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012787 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012788#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012789#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012790 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012791#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012792#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012793 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012794#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012795#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012796 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012797#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012798#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012799 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012800#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012801#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012802 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012803#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012804#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012805 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012806#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012807#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012808 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012809#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012810#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012812#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012813#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012814 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012815#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012816#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012817 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012818#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012819#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012820 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012821#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012822#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012823 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012824#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012825#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012826 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012827#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012828
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012829 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012830#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012831 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012832#endif /* ST_RDONLY */
12833#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012834 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012835#endif /* ST_NOSUID */
12836
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012837 /* GNU extensions */
12838#ifdef ST_NODEV
12839 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12840#endif /* ST_NODEV */
12841#ifdef ST_NOEXEC
12842 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12843#endif /* ST_NOEXEC */
12844#ifdef ST_SYNCHRONOUS
12845 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12846#endif /* ST_SYNCHRONOUS */
12847#ifdef ST_MANDLOCK
12848 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12849#endif /* ST_MANDLOCK */
12850#ifdef ST_WRITE
12851 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12852#endif /* ST_WRITE */
12853#ifdef ST_APPEND
12854 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12855#endif /* ST_APPEND */
12856#ifdef ST_NOATIME
12857 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12858#endif /* ST_NOATIME */
12859#ifdef ST_NODIRATIME
12860 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12861#endif /* ST_NODIRATIME */
12862#ifdef ST_RELATIME
12863 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12864#endif /* ST_RELATIME */
12865
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012866 /* FreeBSD sendfile() constants */
12867#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012868 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012869#endif
12870#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012871 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012872#endif
12873#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012874 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012875#endif
12876
Ross Lagerwall7807c352011-03-17 20:20:30 +020012877 /* constants for posix_fadvise */
12878#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012880#endif
12881#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012883#endif
12884#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012885 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012886#endif
12887#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012888 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012889#endif
12890#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012891 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012892#endif
12893#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012894 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012895#endif
12896
12897 /* constants for waitid */
12898#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12900 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12901 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012902#endif
12903#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012904 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012905#endif
12906#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012907 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012908#endif
12909#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012910 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012911#endif
12912#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012914#endif
12915#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012916 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012917#endif
12918#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012919 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012920#endif
12921#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012922 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012923#endif
12924
12925 /* constants for lockf */
12926#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012928#endif
12929#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012930 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012931#endif
12932#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012934#endif
12935#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012937#endif
12938
Guido van Rossum246bc171999-02-01 23:54:31 +000012939#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12941 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12942 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12943 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12944 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012945#endif
12946
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012947#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012948#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012950#endif
12951#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012953#endif
12954#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012955 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012956#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012957#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080012958 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012959#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012960#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012961 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012962#endif
12963#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012964 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012965#endif
12966#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012967 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012968#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012969#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012970 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012971#endif
12972#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012973 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012974#endif
12975#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012976 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012977#endif
12978#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012980#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012981#endif
12982
Benjamin Peterson9428d532011-09-14 11:45:52 -040012983#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012984 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12985 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12986 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012987#endif
12988
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012989#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012991#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012992#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012993 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012994#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012995#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012996 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012997#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012998#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012999 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013000#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013001#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013002 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013003#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013004#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013005 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013006#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013007#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013008 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013009#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013010#if HAVE_DECL_RTLD_MEMBER
13011 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13012#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013013
Victor Stinner9b1f4742016-09-06 16:18:52 -070013014#ifdef HAVE_GETRANDOM_SYSCALL
13015 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13016 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13017#endif
13018
Victor Stinner8c62be82010-05-06 00:08:46 +000013019 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013020}
13021
13022
Martin v. Löwis1a214512008-06-11 05:26:20 +000013023static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013024 PyModuleDef_HEAD_INIT,
13025 MODNAME,
13026 posix__doc__,
13027 -1,
13028 posix_methods,
13029 NULL,
13030 NULL,
13031 NULL,
13032 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013033};
13034
13035
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013036static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013037
13038#ifdef HAVE_FACCESSAT
13039 "HAVE_FACCESSAT",
13040#endif
13041
13042#ifdef HAVE_FCHDIR
13043 "HAVE_FCHDIR",
13044#endif
13045
13046#ifdef HAVE_FCHMOD
13047 "HAVE_FCHMOD",
13048#endif
13049
13050#ifdef HAVE_FCHMODAT
13051 "HAVE_FCHMODAT",
13052#endif
13053
13054#ifdef HAVE_FCHOWN
13055 "HAVE_FCHOWN",
13056#endif
13057
Larry Hastings00964ed2013-08-12 13:49:30 -040013058#ifdef HAVE_FCHOWNAT
13059 "HAVE_FCHOWNAT",
13060#endif
13061
Larry Hastings9cf065c2012-06-22 16:30:09 -070013062#ifdef HAVE_FEXECVE
13063 "HAVE_FEXECVE",
13064#endif
13065
13066#ifdef HAVE_FDOPENDIR
13067 "HAVE_FDOPENDIR",
13068#endif
13069
Georg Brandl306336b2012-06-24 12:55:33 +020013070#ifdef HAVE_FPATHCONF
13071 "HAVE_FPATHCONF",
13072#endif
13073
Larry Hastings9cf065c2012-06-22 16:30:09 -070013074#ifdef HAVE_FSTATAT
13075 "HAVE_FSTATAT",
13076#endif
13077
13078#ifdef HAVE_FSTATVFS
13079 "HAVE_FSTATVFS",
13080#endif
13081
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013082#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013083 "HAVE_FTRUNCATE",
13084#endif
13085
Larry Hastings9cf065c2012-06-22 16:30:09 -070013086#ifdef HAVE_FUTIMENS
13087 "HAVE_FUTIMENS",
13088#endif
13089
13090#ifdef HAVE_FUTIMES
13091 "HAVE_FUTIMES",
13092#endif
13093
13094#ifdef HAVE_FUTIMESAT
13095 "HAVE_FUTIMESAT",
13096#endif
13097
13098#ifdef HAVE_LINKAT
13099 "HAVE_LINKAT",
13100#endif
13101
13102#ifdef HAVE_LCHFLAGS
13103 "HAVE_LCHFLAGS",
13104#endif
13105
13106#ifdef HAVE_LCHMOD
13107 "HAVE_LCHMOD",
13108#endif
13109
13110#ifdef HAVE_LCHOWN
13111 "HAVE_LCHOWN",
13112#endif
13113
13114#ifdef HAVE_LSTAT
13115 "HAVE_LSTAT",
13116#endif
13117
13118#ifdef HAVE_LUTIMES
13119 "HAVE_LUTIMES",
13120#endif
13121
13122#ifdef HAVE_MKDIRAT
13123 "HAVE_MKDIRAT",
13124#endif
13125
13126#ifdef HAVE_MKFIFOAT
13127 "HAVE_MKFIFOAT",
13128#endif
13129
13130#ifdef HAVE_MKNODAT
13131 "HAVE_MKNODAT",
13132#endif
13133
13134#ifdef HAVE_OPENAT
13135 "HAVE_OPENAT",
13136#endif
13137
13138#ifdef HAVE_READLINKAT
13139 "HAVE_READLINKAT",
13140#endif
13141
13142#ifdef HAVE_RENAMEAT
13143 "HAVE_RENAMEAT",
13144#endif
13145
13146#ifdef HAVE_SYMLINKAT
13147 "HAVE_SYMLINKAT",
13148#endif
13149
13150#ifdef HAVE_UNLINKAT
13151 "HAVE_UNLINKAT",
13152#endif
13153
13154#ifdef HAVE_UTIMENSAT
13155 "HAVE_UTIMENSAT",
13156#endif
13157
13158#ifdef MS_WINDOWS
13159 "MS_WINDOWS",
13160#endif
13161
13162 NULL
13163};
13164
13165
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013166PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013167INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013168{
Victor Stinner8c62be82010-05-06 00:08:46 +000013169 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013170 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013171 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013172
Brian Curtin52173d42010-12-02 18:29:18 +000013173#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013174 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013175#endif
13176
Victor Stinner8c62be82010-05-06 00:08:46 +000013177 m = PyModule_Create(&posixmodule);
13178 if (m == NULL)
13179 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013180
Victor Stinner8c62be82010-05-06 00:08:46 +000013181 /* Initialize environ dictionary */
13182 v = convertenviron();
13183 Py_XINCREF(v);
13184 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13185 return NULL;
13186 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013187
Victor Stinner8c62be82010-05-06 00:08:46 +000013188 if (all_ins(m))
13189 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013190
Victor Stinner8c62be82010-05-06 00:08:46 +000013191 if (setup_confname_tables(m))
13192 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013193
Victor Stinner8c62be82010-05-06 00:08:46 +000013194 Py_INCREF(PyExc_OSError);
13195 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013196
Guido van Rossumb3d39562000-01-31 18:41:26 +000013197#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013198 if (posix_putenv_garbage == NULL)
13199 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013200#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013201
Victor Stinner8c62be82010-05-06 00:08:46 +000013202 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013203#if defined(HAVE_WAITID) && !defined(__APPLE__)
13204 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013205 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13206 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013207#endif
13208
Christian Heimes25827622013-10-12 01:27:08 +020013209 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013210 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13211 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13212 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013213 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13214 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013215 structseq_new = StatResultType.tp_new;
13216 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013217
Christian Heimes25827622013-10-12 01:27:08 +020013218 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013219 if (PyStructSequence_InitType2(&StatVFSResultType,
13220 &statvfs_result_desc) < 0)
13221 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013222#ifdef NEED_TICKS_PER_SECOND
13223# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013224 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013225# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013226 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013227# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013228 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013229# endif
13230#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013231
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013232#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013233 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013234 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13235 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013236 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013237#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013238
13239 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013240 if (PyStructSequence_InitType2(&TerminalSizeType,
13241 &TerminalSize_desc) < 0)
13242 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013243
13244 /* initialize scandir types */
13245 if (PyType_Ready(&ScandirIteratorType) < 0)
13246 return NULL;
13247 if (PyType_Ready(&DirEntryType) < 0)
13248 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013249 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013250#if defined(HAVE_WAITID) && !defined(__APPLE__)
13251 Py_INCREF((PyObject*) &WaitidResultType);
13252 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13253#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013254 Py_INCREF((PyObject*) &StatResultType);
13255 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13256 Py_INCREF((PyObject*) &StatVFSResultType);
13257 PyModule_AddObject(m, "statvfs_result",
13258 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013259
13260#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013261 Py_INCREF(&SchedParamType);
13262 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013263#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013264
Larry Hastings605a62d2012-06-24 04:33:36 -070013265 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013266 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13267 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013268 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13269
13270 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013271 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13272 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013273 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13274
Thomas Wouters477c8d52006-05-27 19:21:47 +000013275#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013276 /*
13277 * Step 2 of weak-linking support on Mac OS X.
13278 *
13279 * The code below removes functions that are not available on the
13280 * currently active platform.
13281 *
13282 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013283 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013284 * OSX 10.4.
13285 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013286#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013287 if (fstatvfs == NULL) {
13288 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13289 return NULL;
13290 }
13291 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013292#endif /* HAVE_FSTATVFS */
13293
13294#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013295 if (statvfs == NULL) {
13296 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13297 return NULL;
13298 }
13299 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013300#endif /* HAVE_STATVFS */
13301
13302# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013303 if (lchown == NULL) {
13304 if (PyObject_DelAttrString(m, "lchown") == -1) {
13305 return NULL;
13306 }
13307 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013308#endif /* HAVE_LCHOWN */
13309
13310
13311#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013312
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013313 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013314 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13315
Larry Hastings6fe20b32012-04-19 15:07:49 -070013316 billion = PyLong_FromLong(1000000000);
13317 if (!billion)
13318 return NULL;
13319
Larry Hastings9cf065c2012-06-22 16:30:09 -070013320 /* suppress "function not used" warnings */
13321 {
13322 int ignored;
13323 fd_specified("", -1);
13324 follow_symlinks_specified("", 1);
13325 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13326 dir_fd_converter(Py_None, &ignored);
13327 dir_fd_unavailable(Py_None, &ignored);
13328 }
13329
13330 /*
13331 * provide list of locally available functions
13332 * so os.py can populate support_* lists
13333 */
13334 list = PyList_New(0);
13335 if (!list)
13336 return NULL;
13337 for (trace = have_functions; *trace; trace++) {
13338 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13339 if (!unicode)
13340 return NULL;
13341 if (PyList_Append(list, unicode))
13342 return NULL;
13343 Py_DECREF(unicode);
13344 }
13345 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013346
13347 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013348 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013349
13350 initialized = 1;
13351
Victor Stinner8c62be82010-05-06 00:08:46 +000013352 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013353}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013354
13355#ifdef __cplusplus
13356}
13357#endif