blob: a1a38ebda387f5e9621bfbfcdd6c56e42602f197 [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. Kuchling8d2f2b22000-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. Kuchling8d2f2b22000-07-13 01:26:58 +00006647}
6648#endif /* HAVE_SETEUID */
6649
Larry Hastings2f936352014-08-05 14:04:04 +10006650
Andrew M. Kuchling8d2f2b22000-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. Kuchling8d2f2b22000-07-13 01:26:58 +00006668}
6669#endif /* HAVE_SETEGID */
6670
Larry Hastings2f936352014-08-05 14:04:04 +10006671
Andrew M. Kuchling8d2f2b22000-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. Kuchling8d2f2b22000-07-13 01:26:58 +00006692}
6693#endif /* HAVE_SETREUID */
6694
Larry Hastings2f936352014-08-05 14:04:04 +10006695
Andrew M. Kuchling8d2f2b22000-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. Kuchling8d2f2b22000-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]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007773os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007774 fd: int
7775 fd2: int
7776 inheritable: bool=True
7777
7778Duplicate file descriptor.
7779[clinic start generated code]*/
7780
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007781static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007782os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007783/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
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
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007792 if (fd < 0 || fd2 < 0) {
7793 posix_error();
7794 return -1;
7795 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007796
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007797 /* dup2() can fail with EINTR if the target FD is already open, because it
7798 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7799 * upon close(), and therefore below.
7800 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007801#ifdef MS_WINDOWS
7802 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007803 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007805 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007806 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007807 if (res < 0) {
7808 posix_error();
7809 return -1;
7810 }
7811 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007812
7813 /* Character files like console cannot be make non-inheritable */
7814 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7815 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007816 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007817 }
7818
7819#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7820 Py_BEGIN_ALLOW_THREADS
7821 if (!inheritable)
7822 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7823 else
7824 res = dup2(fd, fd2);
7825 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007826 if (res < 0) {
7827 posix_error();
7828 return -1;
7829 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007830
7831#else
7832
7833#ifdef HAVE_DUP3
7834 if (!inheritable && dup3_works != 0) {
7835 Py_BEGIN_ALLOW_THREADS
7836 res = dup3(fd, fd2, O_CLOEXEC);
7837 Py_END_ALLOW_THREADS
7838 if (res < 0) {
7839 if (dup3_works == -1)
7840 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007841 if (dup3_works) {
7842 posix_error();
7843 return -1;
7844 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007845 }
7846 }
7847
7848 if (inheritable || dup3_works == 0)
7849 {
7850#endif
7851 Py_BEGIN_ALLOW_THREADS
7852 res = dup2(fd, fd2);
7853 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007854 if (res < 0) {
7855 posix_error();
7856 return -1;
7857 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007858
7859 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7860 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007861 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007862 }
7863#ifdef HAVE_DUP3
7864 }
7865#endif
7866
7867#endif
7868
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007869 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007870}
7871
Larry Hastings2f936352014-08-05 14:04:04 +10007872
Ross Lagerwall7807c352011-03-17 20:20:30 +02007873#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007874/*[clinic input]
7875os.lockf
7876
7877 fd: int
7878 An open file descriptor.
7879 command: int
7880 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7881 length: Py_off_t
7882 The number of bytes to lock, starting at the current position.
7883 /
7884
7885Apply, test or remove a POSIX lock on an open file descriptor.
7886
7887[clinic start generated code]*/
7888
Larry Hastings2f936352014-08-05 14:04:04 +10007889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007890os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7891/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007892{
7893 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007894
7895 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007896 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007897 Py_END_ALLOW_THREADS
7898
7899 if (res < 0)
7900 return posix_error();
7901
7902 Py_RETURN_NONE;
7903}
Larry Hastings2f936352014-08-05 14:04:04 +10007904#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007906
Larry Hastings2f936352014-08-05 14:04:04 +10007907/*[clinic input]
7908os.lseek -> Py_off_t
7909
7910 fd: int
7911 position: Py_off_t
7912 how: int
7913 /
7914
7915Set the position of a file descriptor. Return the new position.
7916
7917Return the new cursor position in number of bytes
7918relative to the beginning of the file.
7919[clinic start generated code]*/
7920
Larry Hastings2f936352014-08-05 14:04:04 +10007921static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007922os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7923/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007924{
7925 Py_off_t result;
7926
Guido van Rossum687dd131993-05-17 08:34:16 +00007927#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7929 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007930 case 0: how = SEEK_SET; break;
7931 case 1: how = SEEK_CUR; break;
7932 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007934#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007935
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007937 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007938
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007940 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007941#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007942 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007943#else
Larry Hastings2f936352014-08-05 14:04:04 +10007944 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007945#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007946 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007948 if (result < 0)
7949 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007950
Larry Hastings2f936352014-08-05 14:04:04 +10007951 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007952}
7953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007954
Larry Hastings2f936352014-08-05 14:04:04 +10007955/*[clinic input]
7956os.read
7957 fd: int
7958 length: Py_ssize_t
7959 /
7960
7961Read from a file descriptor. Returns a bytes object.
7962[clinic start generated code]*/
7963
Larry Hastings2f936352014-08-05 14:04:04 +10007964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007965os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7966/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007967{
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 Py_ssize_t n;
7969 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007970
7971 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 errno = EINVAL;
7973 return posix_error();
7974 }
Larry Hastings2f936352014-08-05 14:04:04 +10007975
7976#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007977 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007978 if (length > INT_MAX)
7979 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007980#endif
7981
7982 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 if (buffer == NULL)
7984 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007985
Victor Stinner66aab0c2015-03-19 22:53:20 +01007986 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7987 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007989 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007990 }
Larry Hastings2f936352014-08-05 14:04:04 +10007991
7992 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007994
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007996}
7997
Ross Lagerwall7807c352011-03-17 20:20:30 +02007998#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7999 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008000static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008001iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008002{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008003 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008004 Py_ssize_t blen, total = 0;
8005
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008006 *iov = PyMem_New(struct iovec, cnt);
8007 if (*iov == NULL) {
8008 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008009 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008010 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008011
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008012 *buf = PyMem_New(Py_buffer, cnt);
8013 if (*buf == NULL) {
8014 PyMem_Del(*iov);
8015 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008016 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008017 }
8018
8019 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008020 PyObject *item = PySequence_GetItem(seq, i);
8021 if (item == NULL)
8022 goto fail;
8023 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8024 Py_DECREF(item);
8025 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008026 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008027 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008028 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008029 blen = (*buf)[i].len;
8030 (*iov)[i].iov_len = blen;
8031 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008033 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008034
8035fail:
8036 PyMem_Del(*iov);
8037 for (j = 0; j < i; j++) {
8038 PyBuffer_Release(&(*buf)[j]);
8039 }
8040 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008041 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042}
8043
8044static void
8045iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8046{
8047 int i;
8048 PyMem_Del(iov);
8049 for (i = 0; i < cnt; i++) {
8050 PyBuffer_Release(&buf[i]);
8051 }
8052 PyMem_Del(buf);
8053}
8054#endif
8055
Larry Hastings2f936352014-08-05 14:04:04 +10008056
Ross Lagerwall7807c352011-03-17 20:20:30 +02008057#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008058/*[clinic input]
8059os.readv -> Py_ssize_t
8060
8061 fd: int
8062 buffers: object
8063 /
8064
8065Read from a file descriptor fd into an iterable of buffers.
8066
8067The buffers should be mutable buffers accepting bytes.
8068readv will transfer data into each buffer until it is full
8069and then move on to the next buffer in the sequence to hold
8070the rest of the data.
8071
8072readv returns the total number of bytes read,
8073which may be less than the total capacity of all the buffers.
8074[clinic start generated code]*/
8075
Larry Hastings2f936352014-08-05 14:04:04 +10008076static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008077os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8078/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008079{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008080 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008081 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008082 struct iovec *iov;
8083 Py_buffer *buf;
8084
Larry Hastings2f936352014-08-05 14:04:04 +10008085 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008086 PyErr_SetString(PyExc_TypeError,
8087 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008088 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008089 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008090
Larry Hastings2f936352014-08-05 14:04:04 +10008091 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008092 if (cnt < 0)
8093 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008094
8095 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8096 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008097
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008098 do {
8099 Py_BEGIN_ALLOW_THREADS
8100 n = readv(fd, iov, cnt);
8101 Py_END_ALLOW_THREADS
8102 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008103
8104 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008105 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008106 if (!async_err)
8107 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008108 return -1;
8109 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008110
Larry Hastings2f936352014-08-05 14:04:04 +10008111 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008112}
Larry Hastings2f936352014-08-05 14:04:04 +10008113#endif /* HAVE_READV */
8114
Ross Lagerwall7807c352011-03-17 20:20:30 +02008115
8116#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008117/*[clinic input]
8118# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8119os.pread
8120
8121 fd: int
8122 length: int
8123 offset: Py_off_t
8124 /
8125
8126Read a number of bytes from a file descriptor starting at a particular offset.
8127
8128Read length bytes from file descriptor fd, starting at offset bytes from
8129the beginning of the file. The file offset remains unchanged.
8130[clinic start generated code]*/
8131
Larry Hastings2f936352014-08-05 14:04:04 +10008132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008133os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8134/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008135{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008137 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008138 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008139
Larry Hastings2f936352014-08-05 14:04:04 +10008140 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008141 errno = EINVAL;
8142 return posix_error();
8143 }
Larry Hastings2f936352014-08-05 14:04:04 +10008144 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145 if (buffer == NULL)
8146 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008147
8148 do {
8149 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008150 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008151 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008152 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008153 Py_END_ALLOW_THREADS
8154 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8155
Ross Lagerwall7807c352011-03-17 20:20:30 +02008156 if (n < 0) {
8157 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008158 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008159 }
Larry Hastings2f936352014-08-05 14:04:04 +10008160 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008161 _PyBytes_Resize(&buffer, n);
8162 return buffer;
8163}
Larry Hastings2f936352014-08-05 14:04:04 +10008164#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008165
Pablo Galindo4defba32018-01-27 16:16:37 +00008166#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8167/*[clinic input]
8168os.preadv -> Py_ssize_t
8169
8170 fd: int
8171 buffers: object
8172 offset: Py_off_t
8173 flags: int = 0
8174 /
8175
8176Reads from a file descriptor into a number of mutable bytes-like objects.
8177
8178Combines the functionality of readv() and pread(). As readv(), it will
8179transfer data into each buffer until it is full and then move on to the next
8180buffer in the sequence to hold the rest of the data. Its fourth argument,
8181specifies the file offset at which the input operation is to be performed. It
8182will return the total number of bytes read (which can be less than the total
8183capacity of all the objects).
8184
8185The flags argument contains a bitwise OR of zero or more of the following flags:
8186
8187- RWF_HIPRI
8188- RWF_NOWAIT
8189
8190Using non-zero flags requires Linux 4.6 or newer.
8191[clinic start generated code]*/
8192
8193static Py_ssize_t
8194os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8195 int flags)
8196/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8197{
8198 Py_ssize_t cnt, n;
8199 int async_err = 0;
8200 struct iovec *iov;
8201 Py_buffer *buf;
8202
8203 if (!PySequence_Check(buffers)) {
8204 PyErr_SetString(PyExc_TypeError,
8205 "preadv2() arg 2 must be a sequence");
8206 return -1;
8207 }
8208
8209 cnt = PySequence_Size(buffers);
8210 if (cnt < 0) {
8211 return -1;
8212 }
8213
8214#ifndef HAVE_PREADV2
8215 if(flags != 0) {
8216 argument_unavailable_error("preadv2", "flags");
8217 return -1;
8218 }
8219#endif
8220
8221 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8222 return -1;
8223 }
8224#ifdef HAVE_PREADV2
8225 do {
8226 Py_BEGIN_ALLOW_THREADS
8227 _Py_BEGIN_SUPPRESS_IPH
8228 n = preadv2(fd, iov, cnt, offset, flags);
8229 _Py_END_SUPPRESS_IPH
8230 Py_END_ALLOW_THREADS
8231 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8232#else
8233 do {
8234 Py_BEGIN_ALLOW_THREADS
8235 _Py_BEGIN_SUPPRESS_IPH
8236 n = preadv(fd, iov, cnt, offset);
8237 _Py_END_SUPPRESS_IPH
8238 Py_END_ALLOW_THREADS
8239 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8240#endif
8241
8242 iov_cleanup(iov, buf, cnt);
8243 if (n < 0) {
8244 if (!async_err) {
8245 posix_error();
8246 }
8247 return -1;
8248 }
8249
8250 return n;
8251}
8252#endif /* HAVE_PREADV */
8253
Larry Hastings2f936352014-08-05 14:04:04 +10008254
8255/*[clinic input]
8256os.write -> Py_ssize_t
8257
8258 fd: int
8259 data: Py_buffer
8260 /
8261
8262Write a bytes object to a file descriptor.
8263[clinic start generated code]*/
8264
Larry Hastings2f936352014-08-05 14:04:04 +10008265static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008266os_write_impl(PyObject *module, int fd, Py_buffer *data)
8267/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008268{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008269 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008270}
8271
8272#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008273PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008274"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008275sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008276 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008277Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008278
Larry Hastings2f936352014-08-05 14:04:04 +10008279/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280static PyObject *
8281posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8282{
8283 int in, out;
8284 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008285 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008286 off_t offset;
8287
8288#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8289#ifndef __APPLE__
8290 Py_ssize_t len;
8291#endif
8292 PyObject *headers = NULL, *trailers = NULL;
8293 Py_buffer *hbuf, *tbuf;
8294 off_t sbytes;
8295 struct sf_hdtr sf;
8296 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008297 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008298 static char *keywords[] = {"out", "in",
8299 "offset", "count",
8300 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008301
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008302 sf.headers = NULL;
8303 sf.trailers = NULL;
8304
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008305#ifdef __APPLE__
8306 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008307 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308#else
8309 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008310 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311#endif
8312 &headers, &trailers, &flags))
8313 return NULL;
8314 if (headers != NULL) {
8315 if (!PySequence_Check(headers)) {
8316 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008317 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318 return NULL;
8319 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008320 Py_ssize_t i = PySequence_Size(headers);
8321 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008323 if (i > INT_MAX) {
8324 PyErr_SetString(PyExc_OverflowError,
8325 "sendfile() header is too large");
8326 return NULL;
8327 }
8328 if (i > 0) {
8329 sf.hdr_cnt = (int)i;
8330 i = iov_setup(&(sf.headers), &hbuf,
8331 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8332 if (i < 0)
8333 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008334#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008335 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008336#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008337 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008338 }
8339 }
8340 if (trailers != NULL) {
8341 if (!PySequence_Check(trailers)) {
8342 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008343 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008344 return NULL;
8345 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008346 Py_ssize_t i = PySequence_Size(trailers);
8347 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008348 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008349 if (i > INT_MAX) {
8350 PyErr_SetString(PyExc_OverflowError,
8351 "sendfile() trailer is too large");
8352 return NULL;
8353 }
8354 if (i > 0) {
8355 sf.trl_cnt = (int)i;
8356 i = iov_setup(&(sf.trailers), &tbuf,
8357 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8358 if (i < 0)
8359 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008360#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008361 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008362#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008363 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008364 }
8365 }
8366
Steve Dower8fc89802015-04-12 00:26:27 -04008367 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008368 do {
8369 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008370#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008371 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008372#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008373 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008374#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008375 Py_END_ALLOW_THREADS
8376 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008377 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008378
8379 if (sf.headers != NULL)
8380 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8381 if (sf.trailers != NULL)
8382 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8383
8384 if (ret < 0) {
8385 if ((errno == EAGAIN) || (errno == EBUSY)) {
8386 if (sbytes != 0) {
8387 // some data has been sent
8388 goto done;
8389 }
8390 else {
8391 // no data has been sent; upper application is supposed
8392 // to retry on EAGAIN or EBUSY
8393 return posix_error();
8394 }
8395 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008396 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008397 }
8398 goto done;
8399
8400done:
8401 #if !defined(HAVE_LARGEFILE_SUPPORT)
8402 return Py_BuildValue("l", sbytes);
8403 #else
8404 return Py_BuildValue("L", sbytes);
8405 #endif
8406
8407#else
8408 Py_ssize_t count;
8409 PyObject *offobj;
8410 static char *keywords[] = {"out", "in",
8411 "offset", "count", NULL};
8412 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8413 keywords, &out, &in, &offobj, &count))
8414 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008415#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008416 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008417 do {
8418 Py_BEGIN_ALLOW_THREADS
8419 ret = sendfile(out, in, NULL, count);
8420 Py_END_ALLOW_THREADS
8421 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008422 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008423 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008424 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008425 }
8426#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008427 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008428 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008429
8430 do {
8431 Py_BEGIN_ALLOW_THREADS
8432 ret = sendfile(out, in, &offset, count);
8433 Py_END_ALLOW_THREADS
8434 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008435 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008436 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008437 return Py_BuildValue("n", ret);
8438#endif
8439}
Larry Hastings2f936352014-08-05 14:04:04 +10008440#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008441
Larry Hastings2f936352014-08-05 14:04:04 +10008442
8443/*[clinic input]
8444os.fstat
8445
8446 fd : int
8447
8448Perform a stat system call on the given file descriptor.
8449
8450Like stat(), but for an open file descriptor.
8451Equivalent to os.stat(fd).
8452[clinic start generated code]*/
8453
Larry Hastings2f936352014-08-05 14:04:04 +10008454static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008455os_fstat_impl(PyObject *module, int fd)
8456/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008457{
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 STRUCT_STAT st;
8459 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008460 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008461
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008462 do {
8463 Py_BEGIN_ALLOW_THREADS
8464 res = FSTAT(fd, &st);
8465 Py_END_ALLOW_THREADS
8466 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008468#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008469 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008470#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008471 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008472#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 }
Tim Peters5aa91602002-01-30 05:46:57 +00008474
Victor Stinner4195b5c2012-02-08 23:03:19 +01008475 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008476}
8477
Larry Hastings2f936352014-08-05 14:04:04 +10008478
8479/*[clinic input]
8480os.isatty -> bool
8481 fd: int
8482 /
8483
8484Return True if the fd is connected to a terminal.
8485
8486Return True if the file descriptor is an open file descriptor
8487connected to the slave end of a terminal.
8488[clinic start generated code]*/
8489
Larry Hastings2f936352014-08-05 14:04:04 +10008490static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008491os_isatty_impl(PyObject *module, int fd)
8492/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008493{
Steve Dower8fc89802015-04-12 00:26:27 -04008494 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008495 _Py_BEGIN_SUPPRESS_IPH
8496 return_value = isatty(fd);
8497 _Py_END_SUPPRESS_IPH
8498 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008499}
8500
8501
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008502#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008503/*[clinic input]
8504os.pipe
8505
8506Create a pipe.
8507
8508Returns a tuple of two file descriptors:
8509 (read_fd, write_fd)
8510[clinic start generated code]*/
8511
Larry Hastings2f936352014-08-05 14:04:04 +10008512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008513os_pipe_impl(PyObject *module)
8514/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008515{
Victor Stinner8c62be82010-05-06 00:08:46 +00008516 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008517#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008519 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008521#else
8522 int res;
8523#endif
8524
8525#ifdef MS_WINDOWS
8526 attr.nLength = sizeof(attr);
8527 attr.lpSecurityDescriptor = NULL;
8528 attr.bInheritHandle = FALSE;
8529
8530 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008531 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008532 ok = CreatePipe(&read, &write, &attr, 0);
8533 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008534 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8535 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008536 if (fds[0] == -1 || fds[1] == -1) {
8537 CloseHandle(read);
8538 CloseHandle(write);
8539 ok = 0;
8540 }
8541 }
Steve Dowerc3630612016-11-19 18:41:16 -08008542 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008543 Py_END_ALLOW_THREADS
8544
Victor Stinner8c62be82010-05-06 00:08:46 +00008545 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008546 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008547#else
8548
8549#ifdef HAVE_PIPE2
8550 Py_BEGIN_ALLOW_THREADS
8551 res = pipe2(fds, O_CLOEXEC);
8552 Py_END_ALLOW_THREADS
8553
8554 if (res != 0 && errno == ENOSYS)
8555 {
8556#endif
8557 Py_BEGIN_ALLOW_THREADS
8558 res = pipe(fds);
8559 Py_END_ALLOW_THREADS
8560
8561 if (res == 0) {
8562 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8563 close(fds[0]);
8564 close(fds[1]);
8565 return NULL;
8566 }
8567 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8568 close(fds[0]);
8569 close(fds[1]);
8570 return NULL;
8571 }
8572 }
8573#ifdef HAVE_PIPE2
8574 }
8575#endif
8576
8577 if (res != 0)
8578 return PyErr_SetFromErrno(PyExc_OSError);
8579#endif /* !MS_WINDOWS */
8580 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008581}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008582#endif /* HAVE_PIPE */
8583
Larry Hastings2f936352014-08-05 14:04:04 +10008584
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008585#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008586/*[clinic input]
8587os.pipe2
8588
8589 flags: int
8590 /
8591
8592Create a pipe with flags set atomically.
8593
8594Returns a tuple of two file descriptors:
8595 (read_fd, write_fd)
8596
8597flags can be constructed by ORing together one or more of these values:
8598O_NONBLOCK, O_CLOEXEC.
8599[clinic start generated code]*/
8600
Larry Hastings2f936352014-08-05 14:04:04 +10008601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008602os_pipe2_impl(PyObject *module, int flags)
8603/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008604{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008605 int fds[2];
8606 int res;
8607
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008608 res = pipe2(fds, flags);
8609 if (res != 0)
8610 return posix_error();
8611 return Py_BuildValue("(ii)", fds[0], fds[1]);
8612}
8613#endif /* HAVE_PIPE2 */
8614
Larry Hastings2f936352014-08-05 14:04:04 +10008615
Ross Lagerwall7807c352011-03-17 20:20:30 +02008616#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008617/*[clinic input]
8618os.writev -> Py_ssize_t
8619 fd: int
8620 buffers: object
8621 /
8622
8623Iterate over buffers, and write the contents of each to a file descriptor.
8624
8625Returns the total number of bytes written.
8626buffers must be a sequence of bytes-like objects.
8627[clinic start generated code]*/
8628
Larry Hastings2f936352014-08-05 14:04:04 +10008629static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008630os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8631/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008632{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008633 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008634 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008636 struct iovec *iov;
8637 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008638
8639 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008640 PyErr_SetString(PyExc_TypeError,
8641 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008642 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008643 }
Larry Hastings2f936352014-08-05 14:04:04 +10008644 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008645 if (cnt < 0)
8646 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008647
Larry Hastings2f936352014-08-05 14:04:04 +10008648 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8649 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008650 }
8651
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008652 do {
8653 Py_BEGIN_ALLOW_THREADS
8654 result = writev(fd, iov, cnt);
8655 Py_END_ALLOW_THREADS
8656 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008657
8658 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008659 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008660 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008661
Georg Brandl306336b2012-06-24 12:55:33 +02008662 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008663}
Larry Hastings2f936352014-08-05 14:04:04 +10008664#endif /* HAVE_WRITEV */
8665
8666
8667#ifdef HAVE_PWRITE
8668/*[clinic input]
8669os.pwrite -> Py_ssize_t
8670
8671 fd: int
8672 buffer: Py_buffer
8673 offset: Py_off_t
8674 /
8675
8676Write bytes to a file descriptor starting at a particular offset.
8677
8678Write buffer to fd, starting at offset bytes from the beginning of
8679the file. Returns the number of bytes writte. Does not change the
8680current file offset.
8681[clinic start generated code]*/
8682
Larry Hastings2f936352014-08-05 14:04:04 +10008683static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008684os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8685/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008686{
8687 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008688 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008689
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008690 do {
8691 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008692 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008693 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008694 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008695 Py_END_ALLOW_THREADS
8696 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008697
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008698 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008699 posix_error();
8700 return size;
8701}
8702#endif /* HAVE_PWRITE */
8703
Pablo Galindo4defba32018-01-27 16:16:37 +00008704#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8705/*[clinic input]
8706os.pwritev -> Py_ssize_t
8707
8708 fd: int
8709 buffers: object
8710 offset: Py_off_t
8711 flags: int = 0
8712 /
8713
8714Writes the contents of bytes-like objects to a file descriptor at a given offset.
8715
8716Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8717of bytes-like objects. Buffers are processed in array order. Entire contents of first
8718buffer is written before proceeding to second, and so on. The operating system may
8719set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8720This function writes the contents of each object to the file descriptor and returns
8721the total number of bytes written.
8722
8723The flags argument contains a bitwise OR of zero or more of the following flags:
8724
8725- RWF_DSYNC
8726- RWF_SYNC
8727
8728Using non-zero flags requires Linux 4.7 or newer.
8729[clinic start generated code]*/
8730
8731static Py_ssize_t
8732os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8733 int flags)
8734/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8735{
8736 Py_ssize_t cnt;
8737 Py_ssize_t result;
8738 int async_err = 0;
8739 struct iovec *iov;
8740 Py_buffer *buf;
8741
8742 if (!PySequence_Check(buffers)) {
8743 PyErr_SetString(PyExc_TypeError,
8744 "pwritev() arg 2 must be a sequence");
8745 return -1;
8746 }
8747
8748 cnt = PySequence_Size(buffers);
8749 if (cnt < 0) {
8750 return -1;
8751 }
8752
8753#ifndef HAVE_PWRITEV2
8754 if(flags != 0) {
8755 argument_unavailable_error("pwritev2", "flags");
8756 return -1;
8757 }
8758#endif
8759
8760 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8761 return -1;
8762 }
8763#ifdef HAVE_PWRITEV2
8764 do {
8765 Py_BEGIN_ALLOW_THREADS
8766 _Py_BEGIN_SUPPRESS_IPH
8767 result = pwritev2(fd, iov, cnt, offset, flags);
8768 _Py_END_SUPPRESS_IPH
8769 Py_END_ALLOW_THREADS
8770 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8771#else
8772 do {
8773 Py_BEGIN_ALLOW_THREADS
8774 _Py_BEGIN_SUPPRESS_IPH
8775 result = pwritev(fd, iov, cnt, offset);
8776 _Py_END_SUPPRESS_IPH
8777 Py_END_ALLOW_THREADS
8778 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8779#endif
8780
8781 iov_cleanup(iov, buf, cnt);
8782 if (result < 0) {
8783 if (!async_err) {
8784 posix_error();
8785 }
8786 return -1;
8787 }
8788
8789 return result;
8790}
8791#endif /* HAVE_PWRITEV */
8792
8793
8794
Larry Hastings2f936352014-08-05 14:04:04 +10008795
8796#ifdef HAVE_MKFIFO
8797/*[clinic input]
8798os.mkfifo
8799
8800 path: path_t
8801 mode: int=0o666
8802 *
8803 dir_fd: dir_fd(requires='mkfifoat')=None
8804
8805Create a "fifo" (a POSIX named pipe).
8806
8807If dir_fd is not None, it should be a file descriptor open to a directory,
8808 and path should be relative; path will then be relative to that directory.
8809dir_fd may not be implemented on your platform.
8810 If it is unavailable, using it will raise a NotImplementedError.
8811[clinic start generated code]*/
8812
Larry Hastings2f936352014-08-05 14:04:04 +10008813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008814os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8815/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008816{
8817 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008818 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008819
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008820 do {
8821 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008822#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008823 if (dir_fd != DEFAULT_DIR_FD)
8824 result = mkfifoat(dir_fd, path->narrow, mode);
8825 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008826#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008827 result = mkfifo(path->narrow, mode);
8828 Py_END_ALLOW_THREADS
8829 } while (result != 0 && errno == EINTR &&
8830 !(async_err = PyErr_CheckSignals()));
8831 if (result != 0)
8832 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008833
8834 Py_RETURN_NONE;
8835}
8836#endif /* HAVE_MKFIFO */
8837
8838
8839#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8840/*[clinic input]
8841os.mknod
8842
8843 path: path_t
8844 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008845 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008846 *
8847 dir_fd: dir_fd(requires='mknodat')=None
8848
8849Create a node in the file system.
8850
8851Create a node in the file system (file, device special file or named pipe)
8852at path. mode specifies both the permissions to use and the
8853type of node to be created, being combined (bitwise OR) with one of
8854S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8855device defines the newly created device special file (probably using
8856os.makedev()). Otherwise device is ignored.
8857
8858If dir_fd is not None, it should be a file descriptor open to a directory,
8859 and path should be relative; path will then be relative to that directory.
8860dir_fd may not be implemented on your platform.
8861 If it is unavailable, using it will raise a NotImplementedError.
8862[clinic start generated code]*/
8863
Larry Hastings2f936352014-08-05 14:04:04 +10008864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008865os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008866 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008867/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008868{
8869 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008870 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008871
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008872 do {
8873 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008874#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008875 if (dir_fd != DEFAULT_DIR_FD)
8876 result = mknodat(dir_fd, path->narrow, mode, device);
8877 else
Larry Hastings2f936352014-08-05 14:04:04 +10008878#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008879 result = mknod(path->narrow, mode, device);
8880 Py_END_ALLOW_THREADS
8881 } while (result != 0 && errno == EINTR &&
8882 !(async_err = PyErr_CheckSignals()));
8883 if (result != 0)
8884 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008885
8886 Py_RETURN_NONE;
8887}
8888#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8889
8890
8891#ifdef HAVE_DEVICE_MACROS
8892/*[clinic input]
8893os.major -> unsigned_int
8894
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008895 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008896 /
8897
8898Extracts a device major number from a raw device number.
8899[clinic start generated code]*/
8900
Larry Hastings2f936352014-08-05 14:04:04 +10008901static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008902os_major_impl(PyObject *module, dev_t device)
8903/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008904{
8905 return major(device);
8906}
8907
8908
8909/*[clinic input]
8910os.minor -> unsigned_int
8911
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008912 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008913 /
8914
8915Extracts a device minor number from a raw device number.
8916[clinic start generated code]*/
8917
Larry Hastings2f936352014-08-05 14:04:04 +10008918static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008919os_minor_impl(PyObject *module, dev_t device)
8920/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008921{
8922 return minor(device);
8923}
8924
8925
8926/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008927os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008928
8929 major: int
8930 minor: int
8931 /
8932
8933Composes a raw device number from the major and minor device numbers.
8934[clinic start generated code]*/
8935
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008936static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008937os_makedev_impl(PyObject *module, int major, int minor)
8938/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008939{
8940 return makedev(major, minor);
8941}
8942#endif /* HAVE_DEVICE_MACROS */
8943
8944
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008945#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008946/*[clinic input]
8947os.ftruncate
8948
8949 fd: int
8950 length: Py_off_t
8951 /
8952
8953Truncate a file, specified by file descriptor, to a specific length.
8954[clinic start generated code]*/
8955
Larry Hastings2f936352014-08-05 14:04:04 +10008956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008957os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8958/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008959{
8960 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008961 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008962
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008963 do {
8964 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008965 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008966#ifdef MS_WINDOWS
8967 result = _chsize_s(fd, length);
8968#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008969 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008970#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008971 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008972 Py_END_ALLOW_THREADS
8973 } while (result != 0 && errno == EINTR &&
8974 !(async_err = PyErr_CheckSignals()));
8975 if (result != 0)
8976 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008977 Py_RETURN_NONE;
8978}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008979#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008980
8981
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008982#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008983/*[clinic input]
8984os.truncate
8985 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8986 length: Py_off_t
8987
8988Truncate a file, specified by path, to a specific length.
8989
8990On some platforms, path may also be specified as an open file descriptor.
8991 If this functionality is unavailable, using it raises an exception.
8992[clinic start generated code]*/
8993
Larry Hastings2f936352014-08-05 14:04:04 +10008994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008995os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8996/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008997{
8998 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008999#ifdef MS_WINDOWS
9000 int fd;
9001#endif
9002
9003 if (path->fd != -1)
9004 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009005
9006 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009007 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009008#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009009 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009010 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009011 result = -1;
9012 else {
9013 result = _chsize_s(fd, length);
9014 close(fd);
9015 if (result < 0)
9016 errno = result;
9017 }
9018#else
9019 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009020#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009021 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009022 Py_END_ALLOW_THREADS
9023 if (result < 0)
9024 return path_error(path);
9025
9026 Py_RETURN_NONE;
9027}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009028#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009029
Ross Lagerwall7807c352011-03-17 20:20:30 +02009030
Victor Stinnerd6b17692014-09-30 12:20:05 +02009031/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9032 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9033 defined, which is the case in Python on AIX. AIX bug report:
9034 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9035#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9036# define POSIX_FADVISE_AIX_BUG
9037#endif
9038
Victor Stinnerec39e262014-09-30 12:35:58 +02009039
Victor Stinnerd6b17692014-09-30 12:20:05 +02009040#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009041/*[clinic input]
9042os.posix_fallocate
9043
9044 fd: int
9045 offset: Py_off_t
9046 length: Py_off_t
9047 /
9048
9049Ensure a file has allocated at least a particular number of bytes on disk.
9050
9051Ensure that the file specified by fd encompasses a range of bytes
9052starting at offset bytes from the beginning and continuing for length bytes.
9053[clinic start generated code]*/
9054
Larry Hastings2f936352014-08-05 14:04:04 +10009055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009056os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009057 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009058/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009059{
9060 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009061 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009062
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009063 do {
9064 Py_BEGIN_ALLOW_THREADS
9065 result = posix_fallocate(fd, offset, length);
9066 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009067 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9068
9069 if (result == 0)
9070 Py_RETURN_NONE;
9071
9072 if (async_err)
9073 return NULL;
9074
9075 errno = result;
9076 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009077}
Victor Stinnerec39e262014-09-30 12:35:58 +02009078#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009079
Ross Lagerwall7807c352011-03-17 20:20:30 +02009080
Victor Stinnerd6b17692014-09-30 12:20:05 +02009081#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009082/*[clinic input]
9083os.posix_fadvise
9084
9085 fd: int
9086 offset: Py_off_t
9087 length: Py_off_t
9088 advice: int
9089 /
9090
9091Announce an intention to access data in a specific pattern.
9092
9093Announce an intention to access data in a specific pattern, thus allowing
9094the kernel to make optimizations.
9095The advice applies to the region of the file specified by fd starting at
9096offset and continuing for length bytes.
9097advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9098POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9099POSIX_FADV_DONTNEED.
9100[clinic start generated code]*/
9101
Larry Hastings2f936352014-08-05 14:04:04 +10009102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009103os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009104 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009105/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009106{
9107 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009108 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009109
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009110 do {
9111 Py_BEGIN_ALLOW_THREADS
9112 result = posix_fadvise(fd, offset, length, advice);
9113 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009114 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9115
9116 if (result == 0)
9117 Py_RETURN_NONE;
9118
9119 if (async_err)
9120 return NULL;
9121
9122 errno = result;
9123 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009124}
Victor Stinnerec39e262014-09-30 12:35:58 +02009125#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009126
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009127#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009128
Fred Drake762e2061999-08-26 17:23:54 +00009129/* Save putenv() parameters as values here, so we can collect them when they
9130 * get re-set with another call for the same key. */
9131static PyObject *posix_putenv_garbage;
9132
Larry Hastings2f936352014-08-05 14:04:04 +10009133static void
9134posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009135{
Larry Hastings2f936352014-08-05 14:04:04 +10009136 /* Install the first arg and newstr in posix_putenv_garbage;
9137 * this will cause previous value to be collected. This has to
9138 * happen after the real putenv() call because the old value
9139 * was still accessible until then. */
9140 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9141 /* really not much we can do; just leak */
9142 PyErr_Clear();
9143 else
9144 Py_DECREF(value);
9145}
9146
9147
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009148#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009149/*[clinic input]
9150os.putenv
9151
9152 name: unicode
9153 value: unicode
9154 /
9155
9156Change or add an environment variable.
9157[clinic start generated code]*/
9158
Larry Hastings2f936352014-08-05 14:04:04 +10009159static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009160os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9161/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009162{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009163 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009164 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009165
Serhiy Storchaka77703942017-06-25 07:33:01 +03009166 /* Search from index 1 because on Windows starting '=' is allowed for
9167 defining hidden environment variables. */
9168 if (PyUnicode_GET_LENGTH(name) == 0 ||
9169 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9170 {
9171 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9172 return NULL;
9173 }
Larry Hastings2f936352014-08-05 14:04:04 +10009174 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9175 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009176 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009177 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009178
9179 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9180 if (env == NULL)
9181 goto error;
9182 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009183 PyErr_Format(PyExc_ValueError,
9184 "the environment variable is longer than %u characters",
9185 _MAX_ENV);
9186 goto error;
9187 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009188 if (wcslen(env) != (size_t)size) {
9189 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009190 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009191 }
9192
Larry Hastings2f936352014-08-05 14:04:04 +10009193 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009195 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009196 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009197
Larry Hastings2f936352014-08-05 14:04:04 +10009198 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009199 Py_RETURN_NONE;
9200
9201error:
Larry Hastings2f936352014-08-05 14:04:04 +10009202 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009203 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009204}
Larry Hastings2f936352014-08-05 14:04:04 +10009205#else /* MS_WINDOWS */
9206/*[clinic input]
9207os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009208
Larry Hastings2f936352014-08-05 14:04:04 +10009209 name: FSConverter
9210 value: FSConverter
9211 /
9212
9213Change or add an environment variable.
9214[clinic start generated code]*/
9215
Larry Hastings2f936352014-08-05 14:04:04 +10009216static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009217os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9218/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009219{
9220 PyObject *bytes = NULL;
9221 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009222 const char *name_string = PyBytes_AS_STRING(name);
9223 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009224
Serhiy Storchaka77703942017-06-25 07:33:01 +03009225 if (strchr(name_string, '=') != NULL) {
9226 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9227 return NULL;
9228 }
Larry Hastings2f936352014-08-05 14:04:04 +10009229 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9230 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009231 return NULL;
9232 }
9233
9234 env = PyBytes_AS_STRING(bytes);
9235 if (putenv(env)) {
9236 Py_DECREF(bytes);
9237 return posix_error();
9238 }
9239
9240 posix_putenv_garbage_setitem(name, bytes);
9241 Py_RETURN_NONE;
9242}
9243#endif /* MS_WINDOWS */
9244#endif /* HAVE_PUTENV */
9245
9246
9247#ifdef HAVE_UNSETENV
9248/*[clinic input]
9249os.unsetenv
9250 name: FSConverter
9251 /
9252
9253Delete an environment variable.
9254[clinic start generated code]*/
9255
Larry Hastings2f936352014-08-05 14:04:04 +10009256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009257os_unsetenv_impl(PyObject *module, PyObject *name)
9258/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009259{
Victor Stinner984890f2011-11-24 13:53:38 +01009260#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009261 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009262#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009263
Victor Stinner984890f2011-11-24 13:53:38 +01009264#ifdef HAVE_BROKEN_UNSETENV
9265 unsetenv(PyBytes_AS_STRING(name));
9266#else
Victor Stinner65170952011-11-22 22:16:17 +01009267 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009268 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009269 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009270#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009271
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 /* Remove the key from posix_putenv_garbage;
9273 * this will cause it to be collected. This has to
9274 * happen after the real unsetenv() call because the
9275 * old value was still accessible until then.
9276 */
Victor Stinner65170952011-11-22 22:16:17 +01009277 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 /* really not much we can do; just leak */
9279 PyErr_Clear();
9280 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009281 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009282}
Larry Hastings2f936352014-08-05 14:04:04 +10009283#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009284
Larry Hastings2f936352014-08-05 14:04:04 +10009285
9286/*[clinic input]
9287os.strerror
9288
9289 code: int
9290 /
9291
9292Translate an error code to a message string.
9293[clinic start generated code]*/
9294
Larry Hastings2f936352014-08-05 14:04:04 +10009295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009296os_strerror_impl(PyObject *module, int code)
9297/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009298{
9299 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 if (message == NULL) {
9301 PyErr_SetString(PyExc_ValueError,
9302 "strerror() argument out of range");
9303 return NULL;
9304 }
Victor Stinner1b579672011-12-17 05:47:23 +01009305 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009306}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009307
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009308
Guido van Rossumc9641791998-08-04 15:26:23 +00009309#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009310#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009311/*[clinic input]
9312os.WCOREDUMP -> bool
9313
9314 status: int
9315 /
9316
9317Return True if the process returning status was dumped to a core file.
9318[clinic start generated code]*/
9319
Larry Hastings2f936352014-08-05 14:04:04 +10009320static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009321os_WCOREDUMP_impl(PyObject *module, int status)
9322/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009323{
9324 WAIT_TYPE wait_status;
9325 WAIT_STATUS_INT(wait_status) = status;
9326 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009327}
9328#endif /* WCOREDUMP */
9329
Larry Hastings2f936352014-08-05 14:04:04 +10009330
Fred Drake106c1a02002-04-23 15:58:02 +00009331#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009332/*[clinic input]
9333os.WIFCONTINUED -> bool
9334
9335 status: int
9336
9337Return True if a particular process was continued from a job control stop.
9338
9339Return True if the process returning status was continued from a
9340job control stop.
9341[clinic start generated code]*/
9342
Larry Hastings2f936352014-08-05 14:04:04 +10009343static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009344os_WIFCONTINUED_impl(PyObject *module, int status)
9345/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009346{
9347 WAIT_TYPE wait_status;
9348 WAIT_STATUS_INT(wait_status) = status;
9349 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009350}
9351#endif /* WIFCONTINUED */
9352
Larry Hastings2f936352014-08-05 14:04:04 +10009353
Guido van Rossumc9641791998-08-04 15:26:23 +00009354#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009355/*[clinic input]
9356os.WIFSTOPPED -> bool
9357
9358 status: int
9359
9360Return True if the process returning status was stopped.
9361[clinic start generated code]*/
9362
Larry Hastings2f936352014-08-05 14:04:04 +10009363static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009364os_WIFSTOPPED_impl(PyObject *module, int status)
9365/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009366{
9367 WAIT_TYPE wait_status;
9368 WAIT_STATUS_INT(wait_status) = status;
9369 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009370}
9371#endif /* WIFSTOPPED */
9372
Larry Hastings2f936352014-08-05 14:04:04 +10009373
Guido van Rossumc9641791998-08-04 15:26:23 +00009374#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009375/*[clinic input]
9376os.WIFSIGNALED -> bool
9377
9378 status: int
9379
9380Return True if the process returning status was terminated by a signal.
9381[clinic start generated code]*/
9382
Larry Hastings2f936352014-08-05 14:04:04 +10009383static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009384os_WIFSIGNALED_impl(PyObject *module, int status)
9385/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009386{
9387 WAIT_TYPE wait_status;
9388 WAIT_STATUS_INT(wait_status) = status;
9389 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009390}
9391#endif /* WIFSIGNALED */
9392
Larry Hastings2f936352014-08-05 14:04:04 +10009393
Guido van Rossumc9641791998-08-04 15:26:23 +00009394#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009395/*[clinic input]
9396os.WIFEXITED -> bool
9397
9398 status: int
9399
9400Return True if the process returning status exited via the exit() system call.
9401[clinic start generated code]*/
9402
Larry Hastings2f936352014-08-05 14:04:04 +10009403static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009404os_WIFEXITED_impl(PyObject *module, int status)
9405/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009406{
9407 WAIT_TYPE wait_status;
9408 WAIT_STATUS_INT(wait_status) = status;
9409 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009410}
9411#endif /* WIFEXITED */
9412
Larry Hastings2f936352014-08-05 14:04:04 +10009413
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009414#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009415/*[clinic input]
9416os.WEXITSTATUS -> int
9417
9418 status: int
9419
9420Return the process return code from status.
9421[clinic start generated code]*/
9422
Larry Hastings2f936352014-08-05 14:04:04 +10009423static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009424os_WEXITSTATUS_impl(PyObject *module, int status)
9425/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009426{
9427 WAIT_TYPE wait_status;
9428 WAIT_STATUS_INT(wait_status) = status;
9429 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009430}
9431#endif /* WEXITSTATUS */
9432
Larry Hastings2f936352014-08-05 14:04:04 +10009433
Guido van Rossumc9641791998-08-04 15:26:23 +00009434#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009435/*[clinic input]
9436os.WTERMSIG -> int
9437
9438 status: int
9439
9440Return the signal that terminated the process that provided the status value.
9441[clinic start generated code]*/
9442
Larry Hastings2f936352014-08-05 14:04:04 +10009443static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009444os_WTERMSIG_impl(PyObject *module, int status)
9445/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009446{
9447 WAIT_TYPE wait_status;
9448 WAIT_STATUS_INT(wait_status) = status;
9449 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009450}
9451#endif /* WTERMSIG */
9452
Larry Hastings2f936352014-08-05 14:04:04 +10009453
Guido van Rossumc9641791998-08-04 15:26:23 +00009454#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009455/*[clinic input]
9456os.WSTOPSIG -> int
9457
9458 status: int
9459
9460Return the signal that stopped the process that provided the status value.
9461[clinic start generated code]*/
9462
Larry Hastings2f936352014-08-05 14:04:04 +10009463static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009464os_WSTOPSIG_impl(PyObject *module, int status)
9465/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009466{
9467 WAIT_TYPE wait_status;
9468 WAIT_STATUS_INT(wait_status) = status;
9469 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009470}
9471#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009472#endif /* HAVE_SYS_WAIT_H */
9473
9474
Thomas Wouters477c8d52006-05-27 19:21:47 +00009475#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009476#ifdef _SCO_DS
9477/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9478 needed definitions in sys/statvfs.h */
9479#define _SVID3
9480#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009481#include <sys/statvfs.h>
9482
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009483static PyObject*
9484_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9486 if (v == NULL)
9487 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009488
9489#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9491 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9492 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9493 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9494 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9495 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9496 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9497 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9498 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9499 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009500#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9502 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9503 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009504 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009506 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009508 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009510 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009512 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009514 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9516 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009517#endif
Michael Felt502d5512018-01-05 13:01:58 +01009518/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9519 * (issue #32390). */
9520#if defined(_AIX) && defined(_ALL_SOURCE)
9521 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9522#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009523 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009524#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009525 if (PyErr_Occurred()) {
9526 Py_DECREF(v);
9527 return NULL;
9528 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009529
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009531}
9532
Larry Hastings2f936352014-08-05 14:04:04 +10009533
9534/*[clinic input]
9535os.fstatvfs
9536 fd: int
9537 /
9538
9539Perform an fstatvfs system call on the given fd.
9540
9541Equivalent to statvfs(fd).
9542[clinic start generated code]*/
9543
Larry Hastings2f936352014-08-05 14:04:04 +10009544static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009545os_fstatvfs_impl(PyObject *module, int fd)
9546/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009547{
9548 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009549 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009551
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009552 do {
9553 Py_BEGIN_ALLOW_THREADS
9554 result = fstatvfs(fd, &st);
9555 Py_END_ALLOW_THREADS
9556 } while (result != 0 && errno == EINTR &&
9557 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009558 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009559 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009560
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009562}
Larry Hastings2f936352014-08-05 14:04:04 +10009563#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009564
9565
Thomas Wouters477c8d52006-05-27 19:21:47 +00009566#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009567#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009568/*[clinic input]
9569os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009570
Larry Hastings2f936352014-08-05 14:04:04 +10009571 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9572
9573Perform a statvfs system call on the given path.
9574
9575path may always be specified as a string.
9576On some platforms, path may also be specified as an open file descriptor.
9577 If this functionality is unavailable, using it raises an exception.
9578[clinic start generated code]*/
9579
Larry Hastings2f936352014-08-05 14:04:04 +10009580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009581os_statvfs_impl(PyObject *module, path_t *path)
9582/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009583{
9584 int result;
9585 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009586
9587 Py_BEGIN_ALLOW_THREADS
9588#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009589 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009590#ifdef __APPLE__
9591 /* handle weak-linking on Mac OS X 10.3 */
9592 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009593 fd_specified("statvfs", path->fd);
9594 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009595 }
9596#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009597 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009598 }
9599 else
9600#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009601 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009602 Py_END_ALLOW_THREADS
9603
9604 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009605 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009606 }
9607
Larry Hastings2f936352014-08-05 14:04:04 +10009608 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009609}
Larry Hastings2f936352014-08-05 14:04:04 +10009610#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9611
Guido van Rossum94f6f721999-01-06 18:42:14 +00009612
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009613#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009614/*[clinic input]
9615os._getdiskusage
9616
9617 path: Py_UNICODE
9618
9619Return disk usage statistics about the given path as a (total, free) tuple.
9620[clinic start generated code]*/
9621
Larry Hastings2f936352014-08-05 14:04:04 +10009622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009623os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9624/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009625{
9626 BOOL retval;
9627 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009628
9629 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009630 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009631 Py_END_ALLOW_THREADS
9632 if (retval == 0)
9633 return PyErr_SetFromWindowsErr(0);
9634
9635 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9636}
Larry Hastings2f936352014-08-05 14:04:04 +10009637#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009638
9639
Fred Drakec9680921999-12-13 16:37:25 +00009640/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9641 * It maps strings representing configuration variable names to
9642 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009643 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009644 * rarely-used constants. There are three separate tables that use
9645 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009646 *
9647 * This code is always included, even if none of the interfaces that
9648 * need it are included. The #if hackery needed to avoid it would be
9649 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009650 */
9651struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009652 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009653 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009654};
9655
Fred Drake12c6e2d1999-12-14 21:25:03 +00009656static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009657conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009658 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009659{
Christian Heimes217cfd12007-12-02 14:31:20 +00009660 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009661 int value = _PyLong_AsInt(arg);
9662 if (value == -1 && PyErr_Occurred())
9663 return 0;
9664 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009665 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009666 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009667 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009668 /* look up the value in the table using a binary search */
9669 size_t lo = 0;
9670 size_t mid;
9671 size_t hi = tablesize;
9672 int cmp;
9673 const char *confname;
9674 if (!PyUnicode_Check(arg)) {
9675 PyErr_SetString(PyExc_TypeError,
9676 "configuration names must be strings or integers");
9677 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009679 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009680 if (confname == NULL)
9681 return 0;
9682 while (lo < hi) {
9683 mid = (lo + hi) / 2;
9684 cmp = strcmp(confname, table[mid].name);
9685 if (cmp < 0)
9686 hi = mid;
9687 else if (cmp > 0)
9688 lo = mid + 1;
9689 else {
9690 *valuep = table[mid].value;
9691 return 1;
9692 }
9693 }
9694 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9695 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009697}
9698
9699
9700#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9701static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009702#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009704#endif
9705#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009707#endif
Fred Drakec9680921999-12-13 16:37:25 +00009708#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
9714#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009716#endif
9717#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009753#ifdef _PC_ACL_ENABLED
9754 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9755#endif
9756#ifdef _PC_MIN_HOLE_SIZE
9757 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9758#endif
9759#ifdef _PC_ALLOC_SIZE_MIN
9760 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9761#endif
9762#ifdef _PC_REC_INCR_XFER_SIZE
9763 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9764#endif
9765#ifdef _PC_REC_MAX_XFER_SIZE
9766 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9767#endif
9768#ifdef _PC_REC_MIN_XFER_SIZE
9769 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9770#endif
9771#ifdef _PC_REC_XFER_ALIGN
9772 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9773#endif
9774#ifdef _PC_SYMLINK_MAX
9775 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9776#endif
9777#ifdef _PC_XATTR_ENABLED
9778 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9779#endif
9780#ifdef _PC_XATTR_EXISTS
9781 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9782#endif
9783#ifdef _PC_TIMESTAMP_RESOLUTION
9784 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9785#endif
Fred Drakec9680921999-12-13 16:37:25 +00009786};
9787
Fred Drakec9680921999-12-13 16:37:25 +00009788static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009789conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009790{
9791 return conv_confname(arg, valuep, posix_constants_pathconf,
9792 sizeof(posix_constants_pathconf)
9793 / sizeof(struct constdef));
9794}
9795#endif
9796
Larry Hastings2f936352014-08-05 14:04:04 +10009797
Fred Drakec9680921999-12-13 16:37:25 +00009798#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009799/*[clinic input]
9800os.fpathconf -> long
9801
9802 fd: int
9803 name: path_confname
9804 /
9805
9806Return the configuration limit name for the file descriptor fd.
9807
9808If there is no limit, return -1.
9809[clinic start generated code]*/
9810
Larry Hastings2f936352014-08-05 14:04:04 +10009811static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009812os_fpathconf_impl(PyObject *module, int fd, int name)
9813/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009814{
9815 long limit;
9816
9817 errno = 0;
9818 limit = fpathconf(fd, name);
9819 if (limit == -1 && errno != 0)
9820 posix_error();
9821
9822 return limit;
9823}
9824#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009825
9826
9827#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009828/*[clinic input]
9829os.pathconf -> long
9830 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9831 name: path_confname
9832
9833Return the configuration limit name for the file or directory path.
9834
9835If there is no limit, return -1.
9836On some platforms, path may also be specified as an open file descriptor.
9837 If this functionality is unavailable, using it raises an exception.
9838[clinic start generated code]*/
9839
Larry Hastings2f936352014-08-05 14:04:04 +10009840static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009841os_pathconf_impl(PyObject *module, path_t *path, int name)
9842/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009843{
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009845
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009847#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009848 if (path->fd != -1)
9849 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009850 else
9851#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009852 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 if (limit == -1 && errno != 0) {
9854 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009855 /* could be a path or name problem */
9856 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009857 else
Larry Hastings2f936352014-08-05 14:04:04 +10009858 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 }
Larry Hastings2f936352014-08-05 14:04:04 +10009860
9861 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009862}
Larry Hastings2f936352014-08-05 14:04:04 +10009863#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009864
9865#ifdef HAVE_CONFSTR
9866static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009867#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009869#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009870#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009872#endif
9873#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009875#endif
Fred Draked86ed291999-12-15 15:34:33 +00009876#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009878#endif
9879#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009881#endif
9882#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009884#endif
9885#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009887#endif
Fred Drakec9680921999-12-13 16:37:25 +00009888#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
Fred Draked86ed291999-12-15 15:34:33 +00009912#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009914#endif
Fred Drakec9680921999-12-13 16:37:25 +00009915#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
Fred Draked86ed291999-12-15 15:34:33 +00009918#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009920#endif
9921#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009923#endif
9924#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009926#endif
9927#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009929#endif
Fred Drakec9680921999-12-13 16:37:25 +00009930#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
Fred Draked86ed291999-12-15 15:34:33 +00009978#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009980#endif
9981#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009983#endif
9984#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009986#endif
9987#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009989#endif
9990#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009992#endif
9993#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009995#endif
9996#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009998#endif
9999#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010001#endif
10002#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010004#endif
10005#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010007#endif
10008#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010010#endif
10011#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010013#endif
10014#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010016#endif
Fred Drakec9680921999-12-13 16:37:25 +000010017};
10018
10019static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010020conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010021{
10022 return conv_confname(arg, valuep, posix_constants_confstr,
10023 sizeof(posix_constants_confstr)
10024 / sizeof(struct constdef));
10025}
10026
Larry Hastings2f936352014-08-05 14:04:04 +100010027
10028/*[clinic input]
10029os.confstr
10030
10031 name: confstr_confname
10032 /
10033
10034Return a string-valued system configuration variable.
10035[clinic start generated code]*/
10036
Larry Hastings2f936352014-08-05 14:04:04 +100010037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010038os_confstr_impl(PyObject *module, int name)
10039/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010040{
10041 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010042 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010043 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010044
Victor Stinnercb043522010-09-10 23:49:04 +000010045 errno = 0;
10046 len = confstr(name, buffer, sizeof(buffer));
10047 if (len == 0) {
10048 if (errno) {
10049 posix_error();
10050 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010051 }
10052 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010053 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010054 }
10055 }
Victor Stinnercb043522010-09-10 23:49:04 +000010056
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010057 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010058 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010059 char *buf = PyMem_Malloc(len);
10060 if (buf == NULL)
10061 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010062 len2 = confstr(name, buf, len);
10063 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010064 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010065 PyMem_Free(buf);
10066 }
10067 else
10068 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010069 return result;
10070}
Larry Hastings2f936352014-08-05 14:04:04 +100010071#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010072
10073
10074#ifdef HAVE_SYSCONF
10075static struct constdef posix_constants_sysconf[] = {
10076#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
Fred Draked86ed291999-12-15 15:34:33 +000010106#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010108#endif
10109#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010111#endif
Fred Drakec9680921999-12-13 16:37:25 +000010112#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
Fred Drakec9680921999-12-13 16:37:25 +000010115#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
Fred Draked86ed291999-12-15 15:34:33 +000010130#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010132#endif
Fred Drakec9680921999-12-13 16:37:25 +000010133#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
Fred Draked86ed291999-12-15 15:34:33 +000010148#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010150#endif
Fred Drakec9680921999-12-13 16:37:25 +000010151#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
Fred Draked86ed291999-12-15 15:34:33 +000010220#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010222#endif
Fred Drakec9680921999-12-13 16:37:25 +000010223#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
Fred Draked86ed291999-12-15 15:34:33 +000010232#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010234#endif
Fred Drakec9680921999-12-13 16:37:25 +000010235#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
Fred Draked86ed291999-12-15 15:34:33 +000010238#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010240#endif
10241#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010243#endif
Fred Drakec9680921999-12-13 16:37:25 +000010244#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
Fred Draked86ed291999-12-15 15:34:33 +000010256#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010258#endif
Fred Drakec9680921999-12-13 16:37:25 +000010259#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
Fred Draked86ed291999-12-15 15:34:33 +000010280#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010282#endif
Fred Drakec9680921999-12-13 16:37:25 +000010283#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
Fred Draked86ed291999-12-15 15:34:33 +000010289#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010291#endif
Fred Drakec9680921999-12-13 16:37:25 +000010292#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
Fred Draked86ed291999-12-15 15:34:33 +000010319#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010321#endif
10322#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010324#endif
Fred Drakec9680921999-12-13 16:37:25 +000010325#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
Fred Draked86ed291999-12-15 15:34:33 +000010430#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010432#endif
Fred Drakec9680921999-12-13 16:37:25 +000010433#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
10448#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010450#endif
10451#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010453#endif
10454#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010456#endif
10457#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010459#endif
10460#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010462#endif
10463#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010465#endif
10466#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010468#endif
10469#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010471#endif
10472#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010474#endif
10475#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010477#endif
10478#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010480#endif
10481#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010483#endif
10484#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
10511#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010513#endif
10514#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
10517#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010519#endif
10520#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010522#endif
10523#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010525#endif
10526#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010528#endif
10529#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010531#endif
10532#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010534#endif
10535#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010537#endif
10538#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010540#endif
10541#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010543#endif
10544#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010546#endif
10547#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568};
10569
10570static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010571conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010572{
10573 return conv_confname(arg, valuep, posix_constants_sysconf,
10574 sizeof(posix_constants_sysconf)
10575 / sizeof(struct constdef));
10576}
10577
Larry Hastings2f936352014-08-05 14:04:04 +100010578
10579/*[clinic input]
10580os.sysconf -> long
10581 name: sysconf_confname
10582 /
10583
10584Return an integer-valued system configuration variable.
10585[clinic start generated code]*/
10586
Larry Hastings2f936352014-08-05 14:04:04 +100010587static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010588os_sysconf_impl(PyObject *module, int name)
10589/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010590{
10591 long value;
10592
10593 errno = 0;
10594 value = sysconf(name);
10595 if (value == -1 && errno != 0)
10596 posix_error();
10597 return value;
10598}
10599#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010600
10601
Fred Drakebec628d1999-12-15 18:31:10 +000010602/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010603 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010604 * the exported dictionaries that are used to publish information about the
10605 * names available on the host platform.
10606 *
10607 * Sorting the table at runtime ensures that the table is properly ordered
10608 * when used, even for platforms we're not able to test on. It also makes
10609 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010610 */
Fred Drakebec628d1999-12-15 18:31:10 +000010611
10612static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010613cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010614{
10615 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010617 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010618 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010619
10620 return strcmp(c1->name, c2->name);
10621}
10622
10623static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010624setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010625 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010626{
Fred Drakebec628d1999-12-15 18:31:10 +000010627 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010628 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010629
10630 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10631 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010632 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010634
Barry Warsaw3155db32000-04-13 15:20:40 +000010635 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010636 PyObject *o = PyLong_FromLong(table[i].value);
10637 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10638 Py_XDECREF(o);
10639 Py_DECREF(d);
10640 return -1;
10641 }
10642 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010643 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010644 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010645}
10646
Fred Drakebec628d1999-12-15 18:31:10 +000010647/* Return -1 on failure, 0 on success. */
10648static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010649setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010650{
10651#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010652 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010653 sizeof(posix_constants_pathconf)
10654 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010655 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010656 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010657#endif
10658#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010659 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010660 sizeof(posix_constants_confstr)
10661 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010662 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010663 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010664#endif
10665#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010666 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010667 sizeof(posix_constants_sysconf)
10668 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010669 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010670 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010671#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010672 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010673}
Fred Draked86ed291999-12-15 15:34:33 +000010674
10675
Larry Hastings2f936352014-08-05 14:04:04 +100010676/*[clinic input]
10677os.abort
10678
10679Abort the interpreter immediately.
10680
10681This function 'dumps core' or otherwise fails in the hardest way possible
10682on the hosting operating system. This function never returns.
10683[clinic start generated code]*/
10684
Larry Hastings2f936352014-08-05 14:04:04 +100010685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010686os_abort_impl(PyObject *module)
10687/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010688{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010689 abort();
10690 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010691#ifndef __clang__
10692 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10693 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10694 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010695 Py_FatalError("abort() called from Python code didn't abort!");
10696 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010697#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010698}
Fred Drakebec628d1999-12-15 18:31:10 +000010699
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010700#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010701/* Grab ShellExecute dynamically from shell32 */
10702static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010703static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10704 LPCWSTR, INT);
10705static int
10706check_ShellExecute()
10707{
10708 HINSTANCE hShell32;
10709
10710 /* only recheck */
10711 if (-1 == has_ShellExecute) {
10712 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010713 /* Security note: this call is not vulnerable to "DLL hijacking".
10714 SHELL32 is part of "KnownDLLs" and so Windows always load
10715 the system SHELL32.DLL, even if there is another SHELL32.DLL
10716 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010717 hShell32 = LoadLibraryW(L"SHELL32");
10718 Py_END_ALLOW_THREADS
10719 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010720 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10721 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010722 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010723 } else {
10724 has_ShellExecute = 0;
10725 }
10726 }
10727 return has_ShellExecute;
10728}
10729
10730
Steve Dowercc16be82016-09-08 10:35:16 -070010731/*[clinic input]
10732os.startfile
10733 filepath: path_t
10734 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010735
Steve Dowercc16be82016-09-08 10:35:16 -070010736startfile(filepath [, operation])
10737
10738Start a file with its associated application.
10739
10740When "operation" is not specified or "open", this acts like
10741double-clicking the file in Explorer, or giving the file name as an
10742argument to the DOS "start" command: the file is opened with whatever
10743application (if any) its extension is associated.
10744When another "operation" is given, it specifies what should be done with
10745the file. A typical operation is "print".
10746
10747startfile returns as soon as the associated application is launched.
10748There is no option to wait for the application to close, and no way
10749to retrieve the application's exit status.
10750
10751The filepath is relative to the current directory. If you want to use
10752an absolute path, make sure the first character is not a slash ("/");
10753the underlying Win32 ShellExecute function doesn't work if it is.
10754[clinic start generated code]*/
10755
10756static PyObject *
10757os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10758/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10759{
10760 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010761
10762 if(!check_ShellExecute()) {
10763 /* If the OS doesn't have ShellExecute, return a
10764 NotImplementedError. */
10765 return PyErr_Format(PyExc_NotImplementedError,
10766 "startfile not available on this platform");
10767 }
10768
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010770 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010771 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 Py_END_ALLOW_THREADS
10773
Victor Stinner8c62be82010-05-06 00:08:46 +000010774 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010775 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010776 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010777 }
Steve Dowercc16be82016-09-08 10:35:16 -070010778 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010779}
Larry Hastings2f936352014-08-05 14:04:04 +100010780#endif /* MS_WINDOWS */
10781
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010782
Martin v. Löwis438b5342002-12-27 10:16:42 +000010783#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010784/*[clinic input]
10785os.getloadavg
10786
10787Return average recent system load information.
10788
10789Return the number of processes in the system run queue averaged over
10790the last 1, 5, and 15 minutes as a tuple of three floats.
10791Raises OSError if the load average was unobtainable.
10792[clinic start generated code]*/
10793
Larry Hastings2f936352014-08-05 14:04:04 +100010794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010795os_getloadavg_impl(PyObject *module)
10796/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010797{
10798 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010799 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010800 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10801 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010802 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010803 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010804}
Larry Hastings2f936352014-08-05 14:04:04 +100010805#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010806
Larry Hastings2f936352014-08-05 14:04:04 +100010807
10808/*[clinic input]
10809os.device_encoding
10810 fd: int
10811
10812Return a string describing the encoding of a terminal's file descriptor.
10813
10814The file descriptor must be attached to a terminal.
10815If the device is not a terminal, return None.
10816[clinic start generated code]*/
10817
Larry Hastings2f936352014-08-05 14:04:04 +100010818static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010819os_device_encoding_impl(PyObject *module, int fd)
10820/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010821{
Brett Cannonefb00c02012-02-29 18:31:31 -050010822 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010823}
10824
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010825
Larry Hastings2f936352014-08-05 14:04:04 +100010826#ifdef HAVE_SETRESUID
10827/*[clinic input]
10828os.setresuid
10829
10830 ruid: uid_t
10831 euid: uid_t
10832 suid: uid_t
10833 /
10834
10835Set the current process's real, effective, and saved user ids.
10836[clinic start generated code]*/
10837
Larry Hastings2f936352014-08-05 14:04:04 +100010838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010839os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10840/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010841{
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 if (setresuid(ruid, euid, suid) < 0)
10843 return posix_error();
10844 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010845}
Larry Hastings2f936352014-08-05 14:04:04 +100010846#endif /* HAVE_SETRESUID */
10847
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010848
10849#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010850/*[clinic input]
10851os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010852
Larry Hastings2f936352014-08-05 14:04:04 +100010853 rgid: gid_t
10854 egid: gid_t
10855 sgid: gid_t
10856 /
10857
10858Set the current process's real, effective, and saved group ids.
10859[clinic start generated code]*/
10860
Larry Hastings2f936352014-08-05 14:04:04 +100010861static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010862os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10863/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010864{
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 if (setresgid(rgid, egid, sgid) < 0)
10866 return posix_error();
10867 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010868}
Larry Hastings2f936352014-08-05 14:04:04 +100010869#endif /* HAVE_SETRESGID */
10870
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010871
10872#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010873/*[clinic input]
10874os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010875
Larry Hastings2f936352014-08-05 14:04:04 +100010876Return a tuple of the current process's real, effective, and saved user ids.
10877[clinic start generated code]*/
10878
Larry Hastings2f936352014-08-05 14:04:04 +100010879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010880os_getresuid_impl(PyObject *module)
10881/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010882{
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 if (getresuid(&ruid, &euid, &suid) < 0)
10885 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010886 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10887 _PyLong_FromUid(euid),
10888 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010889}
Larry Hastings2f936352014-08-05 14:04:04 +100010890#endif /* HAVE_GETRESUID */
10891
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010892
10893#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010894/*[clinic input]
10895os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010896
Larry Hastings2f936352014-08-05 14:04:04 +100010897Return a tuple of the current process's real, effective, and saved group ids.
10898[clinic start generated code]*/
10899
Larry Hastings2f936352014-08-05 14:04:04 +100010900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010901os_getresgid_impl(PyObject *module)
10902/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010903{
10904 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 if (getresgid(&rgid, &egid, &sgid) < 0)
10906 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010907 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10908 _PyLong_FromGid(egid),
10909 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010910}
Larry Hastings2f936352014-08-05 14:04:04 +100010911#endif /* HAVE_GETRESGID */
10912
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010913
Benjamin Peterson9428d532011-09-14 11:45:52 -040010914#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010915/*[clinic input]
10916os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010917
Larry Hastings2f936352014-08-05 14:04:04 +100010918 path: path_t(allow_fd=True)
10919 attribute: path_t
10920 *
10921 follow_symlinks: bool = True
10922
10923Return the value of extended attribute attribute on path.
10924
10925path may be either a string or an open file descriptor.
10926If follow_symlinks is False, and the last element of the path is a symbolic
10927 link, getxattr will examine the symbolic link itself instead of the file
10928 the link points to.
10929
10930[clinic start generated code]*/
10931
Larry Hastings2f936352014-08-05 14:04:04 +100010932static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010933os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010934 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010935/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010936{
10937 Py_ssize_t i;
10938 PyObject *buffer = NULL;
10939
10940 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10941 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010942
Larry Hastings9cf065c2012-06-22 16:30:09 -070010943 for (i = 0; ; i++) {
10944 void *ptr;
10945 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010946 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010947 Py_ssize_t buffer_size = buffer_sizes[i];
10948 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010949 path_error(path);
10950 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010951 }
10952 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10953 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010954 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010955 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010956
Larry Hastings9cf065c2012-06-22 16:30:09 -070010957 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010958 if (path->fd >= 0)
10959 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010960 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010961 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010962 else
Larry Hastings2f936352014-08-05 14:04:04 +100010963 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010964 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010965
Larry Hastings9cf065c2012-06-22 16:30:09 -070010966 if (result < 0) {
10967 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010968 if (errno == ERANGE)
10969 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010970 path_error(path);
10971 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010972 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010973
Larry Hastings9cf065c2012-06-22 16:30:09 -070010974 if (result != buffer_size) {
10975 /* Can only shrink. */
10976 _PyBytes_Resize(&buffer, result);
10977 }
10978 break;
10979 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010980
Larry Hastings9cf065c2012-06-22 16:30:09 -070010981 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010982}
10983
Larry Hastings2f936352014-08-05 14:04:04 +100010984
10985/*[clinic input]
10986os.setxattr
10987
10988 path: path_t(allow_fd=True)
10989 attribute: path_t
10990 value: Py_buffer
10991 flags: int = 0
10992 *
10993 follow_symlinks: bool = True
10994
10995Set extended attribute attribute on path to value.
10996
10997path may be either a string or an open file descriptor.
10998If follow_symlinks is False, and the last element of the path is a symbolic
10999 link, setxattr will modify the symbolic link itself instead of the file
11000 the link points to.
11001
11002[clinic start generated code]*/
11003
Benjamin Peterson799bd802011-08-31 22:15:17 -040011004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011005os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011006 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011007/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011008{
Larry Hastings2f936352014-08-05 14:04:04 +100011009 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011010
Larry Hastings2f936352014-08-05 14:04:04 +100011011 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013
Benjamin Peterson799bd802011-08-31 22:15:17 -040011014 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011015 if (path->fd > -1)
11016 result = fsetxattr(path->fd, attribute->narrow,
11017 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011018 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011019 result = setxattr(path->narrow, attribute->narrow,
11020 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 else
Larry Hastings2f936352014-08-05 14:04:04 +100011022 result = lsetxattr(path->narrow, attribute->narrow,
11023 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011024 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011025
Larry Hastings9cf065c2012-06-22 16:30:09 -070011026 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011027 path_error(path);
11028 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011029 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011030
Larry Hastings2f936352014-08-05 14:04:04 +100011031 Py_RETURN_NONE;
11032}
11033
11034
11035/*[clinic input]
11036os.removexattr
11037
11038 path: path_t(allow_fd=True)
11039 attribute: path_t
11040 *
11041 follow_symlinks: bool = True
11042
11043Remove extended attribute attribute on path.
11044
11045path may be either a string or an open file descriptor.
11046If follow_symlinks is False, and the last element of the path is a symbolic
11047 link, removexattr will modify the symbolic link itself instead of the file
11048 the link points to.
11049
11050[clinic start generated code]*/
11051
Larry Hastings2f936352014-08-05 14:04:04 +100011052static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011053os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011054 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011055/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011056{
11057 ssize_t result;
11058
11059 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11060 return NULL;
11061
11062 Py_BEGIN_ALLOW_THREADS;
11063 if (path->fd > -1)
11064 result = fremovexattr(path->fd, attribute->narrow);
11065 else if (follow_symlinks)
11066 result = removexattr(path->narrow, attribute->narrow);
11067 else
11068 result = lremovexattr(path->narrow, attribute->narrow);
11069 Py_END_ALLOW_THREADS;
11070
11071 if (result) {
11072 return path_error(path);
11073 }
11074
11075 Py_RETURN_NONE;
11076}
11077
11078
11079/*[clinic input]
11080os.listxattr
11081
11082 path: path_t(allow_fd=True, nullable=True) = None
11083 *
11084 follow_symlinks: bool = True
11085
11086Return a list of extended attributes on path.
11087
11088path may be either None, a string, or an open file descriptor.
11089if path is None, listxattr will examine the current directory.
11090If follow_symlinks is False, and the last element of the path is a symbolic
11091 link, listxattr will examine the symbolic link itself instead of the file
11092 the link points to.
11093[clinic start generated code]*/
11094
Larry Hastings2f936352014-08-05 14:04:04 +100011095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011096os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11097/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011098{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011099 Py_ssize_t i;
11100 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011101 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011102 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011103
Larry Hastings2f936352014-08-05 14:04:04 +100011104 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011105 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011106
Larry Hastings2f936352014-08-05 14:04:04 +100011107 name = path->narrow ? path->narrow : ".";
11108
Larry Hastings9cf065c2012-06-22 16:30:09 -070011109 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011110 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011111 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011112 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011113 Py_ssize_t buffer_size = buffer_sizes[i];
11114 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011115 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011116 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011117 break;
11118 }
11119 buffer = PyMem_MALLOC(buffer_size);
11120 if (!buffer) {
11121 PyErr_NoMemory();
11122 break;
11123 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011124
Larry Hastings9cf065c2012-06-22 16:30:09 -070011125 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011126 if (path->fd > -1)
11127 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011128 else if (follow_symlinks)
11129 length = listxattr(name, buffer, buffer_size);
11130 else
11131 length = llistxattr(name, buffer, buffer_size);
11132 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011133
Larry Hastings9cf065c2012-06-22 16:30:09 -070011134 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011135 if (errno == ERANGE) {
11136 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011137 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011138 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011139 }
Larry Hastings2f936352014-08-05 14:04:04 +100011140 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011141 break;
11142 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011143
Larry Hastings9cf065c2012-06-22 16:30:09 -070011144 result = PyList_New(0);
11145 if (!result) {
11146 goto exit;
11147 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011148
Larry Hastings9cf065c2012-06-22 16:30:09 -070011149 end = buffer + length;
11150 for (trace = start = buffer; trace != end; trace++) {
11151 if (!*trace) {
11152 int error;
11153 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11154 trace - start);
11155 if (!attribute) {
11156 Py_DECREF(result);
11157 result = NULL;
11158 goto exit;
11159 }
11160 error = PyList_Append(result, attribute);
11161 Py_DECREF(attribute);
11162 if (error) {
11163 Py_DECREF(result);
11164 result = NULL;
11165 goto exit;
11166 }
11167 start = trace + 1;
11168 }
11169 }
11170 break;
11171 }
11172exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011173 if (buffer)
11174 PyMem_FREE(buffer);
11175 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011176}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011177#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011178
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011179
Larry Hastings2f936352014-08-05 14:04:04 +100011180/*[clinic input]
11181os.urandom
11182
11183 size: Py_ssize_t
11184 /
11185
11186Return a bytes object containing random bytes suitable for cryptographic use.
11187[clinic start generated code]*/
11188
Larry Hastings2f936352014-08-05 14:04:04 +100011189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011190os_urandom_impl(PyObject *module, Py_ssize_t size)
11191/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011192{
11193 PyObject *bytes;
11194 int result;
11195
Georg Brandl2fb477c2012-02-21 00:33:36 +010011196 if (size < 0)
11197 return PyErr_Format(PyExc_ValueError,
11198 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011199 bytes = PyBytes_FromStringAndSize(NULL, size);
11200 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011201 return NULL;
11202
Victor Stinnere66987e2016-09-06 16:33:52 -070011203 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011204 if (result == -1) {
11205 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011206 return NULL;
11207 }
Larry Hastings2f936352014-08-05 14:04:04 +100011208 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011209}
11210
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011211/* Terminal size querying */
11212
11213static PyTypeObject TerminalSizeType;
11214
11215PyDoc_STRVAR(TerminalSize_docstring,
11216 "A tuple of (columns, lines) for holding terminal window size");
11217
11218static PyStructSequence_Field TerminalSize_fields[] = {
11219 {"columns", "width of the terminal window in characters"},
11220 {"lines", "height of the terminal window in characters"},
11221 {NULL, NULL}
11222};
11223
11224static PyStructSequence_Desc TerminalSize_desc = {
11225 "os.terminal_size",
11226 TerminalSize_docstring,
11227 TerminalSize_fields,
11228 2,
11229};
11230
11231#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011232/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011233PyDoc_STRVAR(termsize__doc__,
11234 "Return the size of the terminal window as (columns, lines).\n" \
11235 "\n" \
11236 "The optional argument fd (default standard output) specifies\n" \
11237 "which file descriptor should be queried.\n" \
11238 "\n" \
11239 "If the file descriptor is not connected to a terminal, an OSError\n" \
11240 "is thrown.\n" \
11241 "\n" \
11242 "This function will only be defined if an implementation is\n" \
11243 "available for this system.\n" \
11244 "\n" \
11245 "shutil.get_terminal_size is the high-level function which should \n" \
11246 "normally be used, os.get_terminal_size is the low-level implementation.");
11247
11248static PyObject*
11249get_terminal_size(PyObject *self, PyObject *args)
11250{
11251 int columns, lines;
11252 PyObject *termsize;
11253
11254 int fd = fileno(stdout);
11255 /* Under some conditions stdout may not be connected and
11256 * fileno(stdout) may point to an invalid file descriptor. For example
11257 * GUI apps don't have valid standard streams by default.
11258 *
11259 * If this happens, and the optional fd argument is not present,
11260 * the ioctl below will fail returning EBADF. This is what we want.
11261 */
11262
11263 if (!PyArg_ParseTuple(args, "|i", &fd))
11264 return NULL;
11265
11266#ifdef TERMSIZE_USE_IOCTL
11267 {
11268 struct winsize w;
11269 if (ioctl(fd, TIOCGWINSZ, &w))
11270 return PyErr_SetFromErrno(PyExc_OSError);
11271 columns = w.ws_col;
11272 lines = w.ws_row;
11273 }
11274#endif /* TERMSIZE_USE_IOCTL */
11275
11276#ifdef TERMSIZE_USE_CONIO
11277 {
11278 DWORD nhandle;
11279 HANDLE handle;
11280 CONSOLE_SCREEN_BUFFER_INFO csbi;
11281 switch (fd) {
11282 case 0: nhandle = STD_INPUT_HANDLE;
11283 break;
11284 case 1: nhandle = STD_OUTPUT_HANDLE;
11285 break;
11286 case 2: nhandle = STD_ERROR_HANDLE;
11287 break;
11288 default:
11289 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11290 }
11291 handle = GetStdHandle(nhandle);
11292 if (handle == NULL)
11293 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11294 if (handle == INVALID_HANDLE_VALUE)
11295 return PyErr_SetFromWindowsErr(0);
11296
11297 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11298 return PyErr_SetFromWindowsErr(0);
11299
11300 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11301 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11302 }
11303#endif /* TERMSIZE_USE_CONIO */
11304
11305 termsize = PyStructSequence_New(&TerminalSizeType);
11306 if (termsize == NULL)
11307 return NULL;
11308 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11309 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11310 if (PyErr_Occurred()) {
11311 Py_DECREF(termsize);
11312 return NULL;
11313 }
11314 return termsize;
11315}
11316#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11317
Larry Hastings2f936352014-08-05 14:04:04 +100011318
11319/*[clinic input]
11320os.cpu_count
11321
Charles-François Natali80d62e62015-08-13 20:37:08 +010011322Return the number of CPUs in the system; return None if indeterminable.
11323
11324This number is not equivalent to the number of CPUs the current process can
11325use. The number of usable CPUs can be obtained with
11326``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011327[clinic start generated code]*/
11328
Larry Hastings2f936352014-08-05 14:04:04 +100011329static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011330os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011331/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011332{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011333 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011334#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011335 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11336 Need to fallback to Vista behavior if this call isn't present */
11337 HINSTANCE hKernel32;
11338 hKernel32 = GetModuleHandleW(L"KERNEL32");
11339
11340 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11341 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11342 "GetMaximumProcessorCount");
11343 if (_GetMaximumProcessorCount != NULL) {
11344 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11345 }
11346 else {
11347 SYSTEM_INFO sysinfo;
11348 GetSystemInfo(&sysinfo);
11349 ncpu = sysinfo.dwNumberOfProcessors;
11350 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011351#elif defined(__hpux)
11352 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11353#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11354 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011355#elif defined(__DragonFly__) || \
11356 defined(__OpenBSD__) || \
11357 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011358 defined(__NetBSD__) || \
11359 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011360 int mib[2];
11361 size_t len = sizeof(ncpu);
11362 mib[0] = CTL_HW;
11363 mib[1] = HW_NCPU;
11364 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11365 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011366#endif
11367 if (ncpu >= 1)
11368 return PyLong_FromLong(ncpu);
11369 else
11370 Py_RETURN_NONE;
11371}
11372
Victor Stinnerdaf45552013-08-28 00:53:59 +020011373
Larry Hastings2f936352014-08-05 14:04:04 +100011374/*[clinic input]
11375os.get_inheritable -> bool
11376
11377 fd: int
11378 /
11379
11380Get the close-on-exe flag of the specified file descriptor.
11381[clinic start generated code]*/
11382
Larry Hastings2f936352014-08-05 14:04:04 +100011383static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011384os_get_inheritable_impl(PyObject *module, int fd)
11385/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011386{
Steve Dower8fc89802015-04-12 00:26:27 -040011387 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011388 _Py_BEGIN_SUPPRESS_IPH
11389 return_value = _Py_get_inheritable(fd);
11390 _Py_END_SUPPRESS_IPH
11391 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011392}
11393
11394
11395/*[clinic input]
11396os.set_inheritable
11397 fd: int
11398 inheritable: int
11399 /
11400
11401Set the inheritable flag of the specified file descriptor.
11402[clinic start generated code]*/
11403
Larry Hastings2f936352014-08-05 14:04:04 +100011404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011405os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11406/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011407{
Steve Dower8fc89802015-04-12 00:26:27 -040011408 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011409
Steve Dower8fc89802015-04-12 00:26:27 -040011410 _Py_BEGIN_SUPPRESS_IPH
11411 result = _Py_set_inheritable(fd, inheritable, NULL);
11412 _Py_END_SUPPRESS_IPH
11413 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011414 return NULL;
11415 Py_RETURN_NONE;
11416}
11417
11418
11419#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011420/*[clinic input]
11421os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011422 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011423 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011424
Larry Hastings2f936352014-08-05 14:04:04 +100011425Get the close-on-exe flag of the specified file descriptor.
11426[clinic start generated code]*/
11427
Larry Hastings2f936352014-08-05 14:04:04 +100011428static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011429os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011430/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011431{
11432 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011433
11434 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11435 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011436 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011437 }
11438
Larry Hastings2f936352014-08-05 14:04:04 +100011439 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011440}
11441
Victor Stinnerdaf45552013-08-28 00:53:59 +020011442
Larry Hastings2f936352014-08-05 14:04:04 +100011443/*[clinic input]
11444os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011445 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011446 inheritable: bool
11447 /
11448
11449Set the inheritable flag of the specified handle.
11450[clinic start generated code]*/
11451
Larry Hastings2f936352014-08-05 14:04:04 +100011452static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011453os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011454 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011455/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011456{
11457 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011458 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11459 PyErr_SetFromWindowsErr(0);
11460 return NULL;
11461 }
11462 Py_RETURN_NONE;
11463}
Larry Hastings2f936352014-08-05 14:04:04 +100011464#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011465
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011466#ifndef MS_WINDOWS
11467PyDoc_STRVAR(get_blocking__doc__,
11468 "get_blocking(fd) -> bool\n" \
11469 "\n" \
11470 "Get the blocking mode of the file descriptor:\n" \
11471 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11472
11473static PyObject*
11474posix_get_blocking(PyObject *self, PyObject *args)
11475{
11476 int fd;
11477 int blocking;
11478
11479 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11480 return NULL;
11481
Steve Dower8fc89802015-04-12 00:26:27 -040011482 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011483 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011484 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011485 if (blocking < 0)
11486 return NULL;
11487 return PyBool_FromLong(blocking);
11488}
11489
11490PyDoc_STRVAR(set_blocking__doc__,
11491 "set_blocking(fd, blocking)\n" \
11492 "\n" \
11493 "Set the blocking mode of the specified file descriptor.\n" \
11494 "Set the O_NONBLOCK flag if blocking is False,\n" \
11495 "clear the O_NONBLOCK flag otherwise.");
11496
11497static PyObject*
11498posix_set_blocking(PyObject *self, PyObject *args)
11499{
Steve Dower8fc89802015-04-12 00:26:27 -040011500 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011501
11502 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11503 return NULL;
11504
Steve Dower8fc89802015-04-12 00:26:27 -040011505 _Py_BEGIN_SUPPRESS_IPH
11506 result = _Py_set_blocking(fd, blocking);
11507 _Py_END_SUPPRESS_IPH
11508 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011509 return NULL;
11510 Py_RETURN_NONE;
11511}
11512#endif /* !MS_WINDOWS */
11513
11514
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011515/*[clinic input]
11516class os.DirEntry "DirEntry *" "&DirEntryType"
11517[clinic start generated code]*/
11518/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011519
11520typedef struct {
11521 PyObject_HEAD
11522 PyObject *name;
11523 PyObject *path;
11524 PyObject *stat;
11525 PyObject *lstat;
11526#ifdef MS_WINDOWS
11527 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011528 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011529 int got_file_index;
11530#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011531#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011532 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011533#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011534 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011535 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011536#endif
11537} DirEntry;
11538
11539static void
11540DirEntry_dealloc(DirEntry *entry)
11541{
11542 Py_XDECREF(entry->name);
11543 Py_XDECREF(entry->path);
11544 Py_XDECREF(entry->stat);
11545 Py_XDECREF(entry->lstat);
11546 Py_TYPE(entry)->tp_free((PyObject *)entry);
11547}
11548
11549/* Forward reference */
11550static int
11551DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11552
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011553/*[clinic input]
11554os.DirEntry.is_symlink -> bool
11555
11556Return True if the entry is a symbolic link; cached per entry.
11557[clinic start generated code]*/
11558
Victor Stinner6036e442015-03-08 01:58:04 +010011559static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011560os_DirEntry_is_symlink_impl(DirEntry *self)
11561/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011562{
11563#ifdef MS_WINDOWS
11564 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011565#elif defined(HAVE_DIRENT_D_TYPE)
11566 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011567 if (self->d_type != DT_UNKNOWN)
11568 return self->d_type == DT_LNK;
11569 else
11570 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011571#else
11572 /* POSIX without d_type */
11573 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011574#endif
11575}
11576
11577static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011578DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11579{
11580 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011581 STRUCT_STAT st;
11582 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011583
11584#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011585 if (!PyUnicode_FSDecoder(self->path, &ub))
11586 return NULL;
11587 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011588#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011589 if (!PyUnicode_FSConverter(self->path, &ub))
11590 return NULL;
11591 const char *path = PyBytes_AS_STRING(ub);
11592 if (self->dir_fd != DEFAULT_DIR_FD) {
11593#ifdef HAVE_FSTATAT
11594 result = fstatat(self->dir_fd, path, &st,
11595 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11596#else
11597 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11598 return NULL;
11599#endif /* HAVE_FSTATAT */
11600 }
11601 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011602#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011603 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011604 if (follow_symlinks)
11605 result = STAT(path, &st);
11606 else
11607 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011608 }
11609 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011610
11611 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011612 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011613
11614 return _pystat_fromstructstat(&st);
11615}
11616
11617static PyObject *
11618DirEntry_get_lstat(DirEntry *self)
11619{
11620 if (!self->lstat) {
11621#ifdef MS_WINDOWS
11622 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11623#else /* POSIX */
11624 self->lstat = DirEntry_fetch_stat(self, 0);
11625#endif
11626 }
11627 Py_XINCREF(self->lstat);
11628 return self->lstat;
11629}
11630
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011631/*[clinic input]
11632os.DirEntry.stat
11633 *
11634 follow_symlinks: bool = True
11635
11636Return stat_result object for the entry; cached per entry.
11637[clinic start generated code]*/
11638
Victor Stinner6036e442015-03-08 01:58:04 +010011639static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011640os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11641/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011642{
11643 if (!follow_symlinks)
11644 return DirEntry_get_lstat(self);
11645
11646 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011647 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011648 if (result == -1)
11649 return NULL;
11650 else if (result)
11651 self->stat = DirEntry_fetch_stat(self, 1);
11652 else
11653 self->stat = DirEntry_get_lstat(self);
11654 }
11655
11656 Py_XINCREF(self->stat);
11657 return self->stat;
11658}
11659
Victor Stinner6036e442015-03-08 01:58:04 +010011660/* Set exception and return -1 on error, 0 for False, 1 for True */
11661static int
11662DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11663{
11664 PyObject *stat = NULL;
11665 PyObject *st_mode = NULL;
11666 long mode;
11667 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011668#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011669 int is_symlink;
11670 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011671#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011672#ifdef MS_WINDOWS
11673 unsigned long dir_bits;
11674#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011675 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011676
11677#ifdef MS_WINDOWS
11678 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11679 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011680#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011681 is_symlink = self->d_type == DT_LNK;
11682 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11683#endif
11684
Victor Stinner35a97c02015-03-08 02:59:09 +010011685#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011686 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011687#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011688 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011689 if (!stat) {
11690 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11691 /* If file doesn't exist (anymore), then return False
11692 (i.e., say it's not a file/directory) */
11693 PyErr_Clear();
11694 return 0;
11695 }
11696 goto error;
11697 }
11698 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11699 if (!st_mode)
11700 goto error;
11701
11702 mode = PyLong_AsLong(st_mode);
11703 if (mode == -1 && PyErr_Occurred())
11704 goto error;
11705 Py_CLEAR(st_mode);
11706 Py_CLEAR(stat);
11707 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011708#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011709 }
11710 else if (is_symlink) {
11711 assert(mode_bits != S_IFLNK);
11712 result = 0;
11713 }
11714 else {
11715 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11716#ifdef MS_WINDOWS
11717 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11718 if (mode_bits == S_IFDIR)
11719 result = dir_bits != 0;
11720 else
11721 result = dir_bits == 0;
11722#else /* POSIX */
11723 if (mode_bits == S_IFDIR)
11724 result = self->d_type == DT_DIR;
11725 else
11726 result = self->d_type == DT_REG;
11727#endif
11728 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011729#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011730
11731 return result;
11732
11733error:
11734 Py_XDECREF(st_mode);
11735 Py_XDECREF(stat);
11736 return -1;
11737}
11738
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011739/*[clinic input]
11740os.DirEntry.is_dir -> bool
11741 *
11742 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011743
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011744Return True if the entry is a directory; cached per entry.
11745[clinic start generated code]*/
11746
11747static int
11748os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11749/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11750{
11751 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011752}
11753
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011754/*[clinic input]
11755os.DirEntry.is_file -> bool
11756 *
11757 follow_symlinks: bool = True
11758
11759Return True if the entry is a file; cached per entry.
11760[clinic start generated code]*/
11761
11762static int
11763os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11764/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011765{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011766 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011767}
11768
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011769/*[clinic input]
11770os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011771
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011772Return inode of the entry; cached per entry.
11773[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011774
11775static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011776os_DirEntry_inode_impl(DirEntry *self)
11777/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011778{
11779#ifdef MS_WINDOWS
11780 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011781 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011782 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011783 STRUCT_STAT stat;
11784 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011785
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011786 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011787 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011788 path = PyUnicode_AsUnicode(unicode);
11789 result = LSTAT(path, &stat);
11790 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011791
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011792 if (result != 0)
11793 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011794
11795 self->win32_file_index = stat.st_ino;
11796 self->got_file_index = 1;
11797 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011798 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11799 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011800#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011801 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11802 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011803#endif
11804}
11805
11806static PyObject *
11807DirEntry_repr(DirEntry *self)
11808{
11809 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11810}
11811
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011812/*[clinic input]
11813os.DirEntry.__fspath__
11814
11815Returns the path for the entry.
11816[clinic start generated code]*/
11817
Brett Cannon96881cd2016-06-10 14:37:21 -070011818static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011819os_DirEntry___fspath___impl(DirEntry *self)
11820/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011821{
11822 Py_INCREF(self->path);
11823 return self->path;
11824}
11825
Victor Stinner6036e442015-03-08 01:58:04 +010011826static PyMemberDef DirEntry_members[] = {
11827 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11828 "the entry's base filename, relative to scandir() \"path\" argument"},
11829 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11830 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11831 {NULL}
11832};
11833
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011834#include "clinic/posixmodule.c.h"
11835
Victor Stinner6036e442015-03-08 01:58:04 +010011836static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011837 OS_DIRENTRY_IS_DIR_METHODDEF
11838 OS_DIRENTRY_IS_FILE_METHODDEF
11839 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11840 OS_DIRENTRY_STAT_METHODDEF
11841 OS_DIRENTRY_INODE_METHODDEF
11842 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011843 {NULL}
11844};
11845
Benjamin Peterson5646de42015-04-12 17:56:34 -040011846static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011847 PyVarObject_HEAD_INIT(NULL, 0)
11848 MODNAME ".DirEntry", /* tp_name */
11849 sizeof(DirEntry), /* tp_basicsize */
11850 0, /* tp_itemsize */
11851 /* methods */
11852 (destructor)DirEntry_dealloc, /* tp_dealloc */
11853 0, /* tp_print */
11854 0, /* tp_getattr */
11855 0, /* tp_setattr */
11856 0, /* tp_compare */
11857 (reprfunc)DirEntry_repr, /* tp_repr */
11858 0, /* tp_as_number */
11859 0, /* tp_as_sequence */
11860 0, /* tp_as_mapping */
11861 0, /* tp_hash */
11862 0, /* tp_call */
11863 0, /* tp_str */
11864 0, /* tp_getattro */
11865 0, /* tp_setattro */
11866 0, /* tp_as_buffer */
11867 Py_TPFLAGS_DEFAULT, /* tp_flags */
11868 0, /* tp_doc */
11869 0, /* tp_traverse */
11870 0, /* tp_clear */
11871 0, /* tp_richcompare */
11872 0, /* tp_weaklistoffset */
11873 0, /* tp_iter */
11874 0, /* tp_iternext */
11875 DirEntry_methods, /* tp_methods */
11876 DirEntry_members, /* tp_members */
11877};
11878
11879#ifdef MS_WINDOWS
11880
11881static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011882join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011883{
11884 Py_ssize_t path_len;
11885 Py_ssize_t size;
11886 wchar_t *result;
11887 wchar_t ch;
11888
11889 if (!path_wide) { /* Default arg: "." */
11890 path_wide = L".";
11891 path_len = 1;
11892 }
11893 else {
11894 path_len = wcslen(path_wide);
11895 }
11896
11897 /* The +1's are for the path separator and the NUL */
11898 size = path_len + 1 + wcslen(filename) + 1;
11899 result = PyMem_New(wchar_t, size);
11900 if (!result) {
11901 PyErr_NoMemory();
11902 return NULL;
11903 }
11904 wcscpy(result, path_wide);
11905 if (path_len > 0) {
11906 ch = result[path_len - 1];
11907 if (ch != SEP && ch != ALTSEP && ch != L':')
11908 result[path_len++] = SEP;
11909 wcscpy(result + path_len, filename);
11910 }
11911 return result;
11912}
11913
11914static PyObject *
11915DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11916{
11917 DirEntry *entry;
11918 BY_HANDLE_FILE_INFORMATION file_info;
11919 ULONG reparse_tag;
11920 wchar_t *joined_path;
11921
11922 entry = PyObject_New(DirEntry, &DirEntryType);
11923 if (!entry)
11924 return NULL;
11925 entry->name = NULL;
11926 entry->path = NULL;
11927 entry->stat = NULL;
11928 entry->lstat = NULL;
11929 entry->got_file_index = 0;
11930
11931 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11932 if (!entry->name)
11933 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011934 if (path->narrow) {
11935 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11936 if (!entry->name)
11937 goto error;
11938 }
Victor Stinner6036e442015-03-08 01:58:04 +010011939
11940 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11941 if (!joined_path)
11942 goto error;
11943
11944 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11945 PyMem_Free(joined_path);
11946 if (!entry->path)
11947 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011948 if (path->narrow) {
11949 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11950 if (!entry->path)
11951 goto error;
11952 }
Victor Stinner6036e442015-03-08 01:58:04 +010011953
Steve Dowercc16be82016-09-08 10:35:16 -070011954 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011955 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11956
11957 return (PyObject *)entry;
11958
11959error:
11960 Py_DECREF(entry);
11961 return NULL;
11962}
11963
11964#else /* POSIX */
11965
11966static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011967join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011968{
11969 Py_ssize_t path_len;
11970 Py_ssize_t size;
11971 char *result;
11972
11973 if (!path_narrow) { /* Default arg: "." */
11974 path_narrow = ".";
11975 path_len = 1;
11976 }
11977 else {
11978 path_len = strlen(path_narrow);
11979 }
11980
11981 if (filename_len == -1)
11982 filename_len = strlen(filename);
11983
11984 /* The +1's are for the path separator and the NUL */
11985 size = path_len + 1 + filename_len + 1;
11986 result = PyMem_New(char, size);
11987 if (!result) {
11988 PyErr_NoMemory();
11989 return NULL;
11990 }
11991 strcpy(result, path_narrow);
11992 if (path_len > 0 && result[path_len - 1] != '/')
11993 result[path_len++] = '/';
11994 strcpy(result + path_len, filename);
11995 return result;
11996}
11997
11998static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011999DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012000 ino_t d_ino
12001#ifdef HAVE_DIRENT_D_TYPE
12002 , unsigned char d_type
12003#endif
12004 )
Victor Stinner6036e442015-03-08 01:58:04 +010012005{
12006 DirEntry *entry;
12007 char *joined_path;
12008
12009 entry = PyObject_New(DirEntry, &DirEntryType);
12010 if (!entry)
12011 return NULL;
12012 entry->name = NULL;
12013 entry->path = NULL;
12014 entry->stat = NULL;
12015 entry->lstat = NULL;
12016
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012017 if (path->fd != -1) {
12018 entry->dir_fd = path->fd;
12019 joined_path = NULL;
12020 }
12021 else {
12022 entry->dir_fd = DEFAULT_DIR_FD;
12023 joined_path = join_path_filename(path->narrow, name, name_len);
12024 if (!joined_path)
12025 goto error;
12026 }
Victor Stinner6036e442015-03-08 01:58:04 +010012027
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012028 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012029 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012030 if (joined_path)
12031 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012032 }
12033 else {
12034 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012035 if (joined_path)
12036 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012037 }
12038 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012039 if (!entry->name)
12040 goto error;
12041
12042 if (path->fd != -1) {
12043 entry->path = entry->name;
12044 Py_INCREF(entry->path);
12045 }
12046 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012047 goto error;
12048
Victor Stinner35a97c02015-03-08 02:59:09 +010012049#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012050 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012051#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012052 entry->d_ino = d_ino;
12053
12054 return (PyObject *)entry;
12055
12056error:
12057 Py_XDECREF(entry);
12058 return NULL;
12059}
12060
12061#endif
12062
12063
12064typedef struct {
12065 PyObject_HEAD
12066 path_t path;
12067#ifdef MS_WINDOWS
12068 HANDLE handle;
12069 WIN32_FIND_DATAW file_data;
12070 int first_time;
12071#else /* POSIX */
12072 DIR *dirp;
12073#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012074#ifdef HAVE_FDOPENDIR
12075 int fd;
12076#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012077} ScandirIterator;
12078
12079#ifdef MS_WINDOWS
12080
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012081static int
12082ScandirIterator_is_closed(ScandirIterator *iterator)
12083{
12084 return iterator->handle == INVALID_HANDLE_VALUE;
12085}
12086
Victor Stinner6036e442015-03-08 01:58:04 +010012087static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012088ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012089{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012090 HANDLE handle = iterator->handle;
12091
12092 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012093 return;
12094
Victor Stinner6036e442015-03-08 01:58:04 +010012095 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012096 Py_BEGIN_ALLOW_THREADS
12097 FindClose(handle);
12098 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012099}
12100
12101static PyObject *
12102ScandirIterator_iternext(ScandirIterator *iterator)
12103{
12104 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12105 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012106 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012107
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012108 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012109 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012110 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012111
12112 while (1) {
12113 if (!iterator->first_time) {
12114 Py_BEGIN_ALLOW_THREADS
12115 success = FindNextFileW(iterator->handle, file_data);
12116 Py_END_ALLOW_THREADS
12117 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012118 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012119 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012120 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012121 break;
12122 }
12123 }
12124 iterator->first_time = 0;
12125
12126 /* Skip over . and .. */
12127 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012128 wcscmp(file_data->cFileName, L"..") != 0) {
12129 entry = DirEntry_from_find_data(&iterator->path, file_data);
12130 if (!entry)
12131 break;
12132 return entry;
12133 }
Victor Stinner6036e442015-03-08 01:58:04 +010012134
12135 /* Loop till we get a non-dot directory or finish iterating */
12136 }
12137
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012138 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012139 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012140 return NULL;
12141}
12142
12143#else /* POSIX */
12144
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012145static int
12146ScandirIterator_is_closed(ScandirIterator *iterator)
12147{
12148 return !iterator->dirp;
12149}
12150
Victor Stinner6036e442015-03-08 01:58:04 +010012151static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012152ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012153{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012154 DIR *dirp = iterator->dirp;
12155
12156 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012157 return;
12158
Victor Stinner6036e442015-03-08 01:58:04 +010012159 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012160 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012161#ifdef HAVE_FDOPENDIR
12162 if (iterator->path.fd != -1)
12163 rewinddir(dirp);
12164#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012165 closedir(dirp);
12166 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012167 return;
12168}
12169
12170static PyObject *
12171ScandirIterator_iternext(ScandirIterator *iterator)
12172{
12173 struct dirent *direntp;
12174 Py_ssize_t name_len;
12175 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012176 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012177
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012178 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012179 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012180 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012181
12182 while (1) {
12183 errno = 0;
12184 Py_BEGIN_ALLOW_THREADS
12185 direntp = readdir(iterator->dirp);
12186 Py_END_ALLOW_THREADS
12187
12188 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012189 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012190 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012191 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012192 break;
12193 }
12194
12195 /* Skip over . and .. */
12196 name_len = NAMLEN(direntp);
12197 is_dot = direntp->d_name[0] == '.' &&
12198 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12199 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012200 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012201 name_len, direntp->d_ino
12202#ifdef HAVE_DIRENT_D_TYPE
12203 , direntp->d_type
12204#endif
12205 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012206 if (!entry)
12207 break;
12208 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012209 }
12210
12211 /* Loop till we get a non-dot directory or finish iterating */
12212 }
12213
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012214 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012215 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012216 return NULL;
12217}
12218
12219#endif
12220
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012221static PyObject *
12222ScandirIterator_close(ScandirIterator *self, PyObject *args)
12223{
12224 ScandirIterator_closedir(self);
12225 Py_RETURN_NONE;
12226}
12227
12228static PyObject *
12229ScandirIterator_enter(PyObject *self, PyObject *args)
12230{
12231 Py_INCREF(self);
12232 return self;
12233}
12234
12235static PyObject *
12236ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12237{
12238 ScandirIterator_closedir(self);
12239 Py_RETURN_NONE;
12240}
12241
Victor Stinner6036e442015-03-08 01:58:04 +010012242static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012243ScandirIterator_finalize(ScandirIterator *iterator)
12244{
12245 PyObject *error_type, *error_value, *error_traceback;
12246
12247 /* Save the current exception, if any. */
12248 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12249
12250 if (!ScandirIterator_is_closed(iterator)) {
12251 ScandirIterator_closedir(iterator);
12252
12253 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12254 "unclosed scandir iterator %R", iterator)) {
12255 /* Spurious errors can appear at shutdown */
12256 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12257 PyErr_WriteUnraisable((PyObject *) iterator);
12258 }
12259 }
12260 }
12261
Victor Stinner7bfa4092016-03-23 00:43:54 +010012262 path_cleanup(&iterator->path);
12263
12264 /* Restore the saved exception. */
12265 PyErr_Restore(error_type, error_value, error_traceback);
12266}
12267
12268static void
Victor Stinner6036e442015-03-08 01:58:04 +010012269ScandirIterator_dealloc(ScandirIterator *iterator)
12270{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012271 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12272 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012273
Victor Stinner6036e442015-03-08 01:58:04 +010012274 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12275}
12276
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012277static PyMethodDef ScandirIterator_methods[] = {
12278 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12279 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12280 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12281 {NULL}
12282};
12283
Benjamin Peterson5646de42015-04-12 17:56:34 -040012284static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012285 PyVarObject_HEAD_INIT(NULL, 0)
12286 MODNAME ".ScandirIterator", /* tp_name */
12287 sizeof(ScandirIterator), /* tp_basicsize */
12288 0, /* tp_itemsize */
12289 /* methods */
12290 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12291 0, /* tp_print */
12292 0, /* tp_getattr */
12293 0, /* tp_setattr */
12294 0, /* tp_compare */
12295 0, /* tp_repr */
12296 0, /* tp_as_number */
12297 0, /* tp_as_sequence */
12298 0, /* tp_as_mapping */
12299 0, /* tp_hash */
12300 0, /* tp_call */
12301 0, /* tp_str */
12302 0, /* tp_getattro */
12303 0, /* tp_setattro */
12304 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012305 Py_TPFLAGS_DEFAULT
12306 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012307 0, /* tp_doc */
12308 0, /* tp_traverse */
12309 0, /* tp_clear */
12310 0, /* tp_richcompare */
12311 0, /* tp_weaklistoffset */
12312 PyObject_SelfIter, /* tp_iter */
12313 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012314 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012315 0, /* tp_members */
12316 0, /* tp_getset */
12317 0, /* tp_base */
12318 0, /* tp_dict */
12319 0, /* tp_descr_get */
12320 0, /* tp_descr_set */
12321 0, /* tp_dictoffset */
12322 0, /* tp_init */
12323 0, /* tp_alloc */
12324 0, /* tp_new */
12325 0, /* tp_free */
12326 0, /* tp_is_gc */
12327 0, /* tp_bases */
12328 0, /* tp_mro */
12329 0, /* tp_cache */
12330 0, /* tp_subclasses */
12331 0, /* tp_weaklist */
12332 0, /* tp_del */
12333 0, /* tp_version_tag */
12334 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012335};
12336
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012337/*[clinic input]
12338os.scandir
12339
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012340 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012341
12342Return an iterator of DirEntry objects for given path.
12343
12344path can be specified as either str, bytes or path-like object. If path
12345is bytes, the names of yielded DirEntry objects will also be bytes; in
12346all other circumstances they will be str.
12347
12348If path is None, uses the path='.'.
12349[clinic start generated code]*/
12350
Victor Stinner6036e442015-03-08 01:58:04 +010012351static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012352os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012353/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012354{
12355 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012356#ifdef MS_WINDOWS
12357 wchar_t *path_strW;
12358#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012359 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012360#ifdef HAVE_FDOPENDIR
12361 int fd = -1;
12362#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012363#endif
12364
12365 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12366 if (!iterator)
12367 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012368
12369#ifdef MS_WINDOWS
12370 iterator->handle = INVALID_HANDLE_VALUE;
12371#else
12372 iterator->dirp = NULL;
12373#endif
12374
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012375 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012376 /* Move the ownership to iterator->path */
12377 path->object = NULL;
12378 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012379
12380#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012381 iterator->first_time = 1;
12382
12383 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12384 if (!path_strW)
12385 goto error;
12386
12387 Py_BEGIN_ALLOW_THREADS
12388 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12389 Py_END_ALLOW_THREADS
12390
12391 PyMem_Free(path_strW);
12392
12393 if (iterator->handle == INVALID_HANDLE_VALUE) {
12394 path_error(&iterator->path);
12395 goto error;
12396 }
12397#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012398 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012399#ifdef HAVE_FDOPENDIR
12400 if (path->fd != -1) {
12401 /* closedir() closes the FD, so we duplicate it */
12402 fd = _Py_dup(path->fd);
12403 if (fd == -1)
12404 goto error;
12405
12406 Py_BEGIN_ALLOW_THREADS
12407 iterator->dirp = fdopendir(fd);
12408 Py_END_ALLOW_THREADS
12409 }
12410 else
12411#endif
12412 {
12413 if (iterator->path.narrow)
12414 path_str = iterator->path.narrow;
12415 else
12416 path_str = ".";
12417
12418 Py_BEGIN_ALLOW_THREADS
12419 iterator->dirp = opendir(path_str);
12420 Py_END_ALLOW_THREADS
12421 }
Victor Stinner6036e442015-03-08 01:58:04 +010012422
12423 if (!iterator->dirp) {
12424 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012425#ifdef HAVE_FDOPENDIR
12426 if (fd != -1) {
12427 Py_BEGIN_ALLOW_THREADS
12428 close(fd);
12429 Py_END_ALLOW_THREADS
12430 }
12431#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012432 goto error;
12433 }
12434#endif
12435
12436 return (PyObject *)iterator;
12437
12438error:
12439 Py_DECREF(iterator);
12440 return NULL;
12441}
12442
Ethan Furman410ef8e2016-06-04 12:06:26 -070012443/*
12444 Return the file system path representation of the object.
12445
12446 If the object is str or bytes, then allow it to pass through with
12447 an incremented refcount. If the object defines __fspath__(), then
12448 return the result of that method. All other types raise a TypeError.
12449*/
12450PyObject *
12451PyOS_FSPath(PyObject *path)
12452{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012453 /* For error message reasons, this function is manually inlined in
12454 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012455 _Py_IDENTIFIER(__fspath__);
12456 PyObject *func = NULL;
12457 PyObject *path_repr = NULL;
12458
12459 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12460 Py_INCREF(path);
12461 return path;
12462 }
12463
12464 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12465 if (NULL == func) {
12466 return PyErr_Format(PyExc_TypeError,
12467 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012468 "not %.200s",
12469 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012470 }
12471
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012472 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012473 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012474 if (NULL == path_repr) {
12475 return NULL;
12476 }
12477
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012478 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12479 PyErr_Format(PyExc_TypeError,
12480 "expected %.200s.__fspath__() to return str or bytes, "
12481 "not %.200s", Py_TYPE(path)->tp_name,
12482 Py_TYPE(path_repr)->tp_name);
12483 Py_DECREF(path_repr);
12484 return NULL;
12485 }
12486
Ethan Furman410ef8e2016-06-04 12:06:26 -070012487 return path_repr;
12488}
12489
12490/*[clinic input]
12491os.fspath
12492
12493 path: object
12494
12495Return the file system path representation of the object.
12496
Brett Cannonb4f43e92016-06-09 14:32:08 -070012497If the object is str or bytes, then allow it to pass through as-is. If the
12498object defines __fspath__(), then return the result of that method. All other
12499types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012500[clinic start generated code]*/
12501
12502static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012503os_fspath_impl(PyObject *module, PyObject *path)
12504/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012505{
12506 return PyOS_FSPath(path);
12507}
Victor Stinner6036e442015-03-08 01:58:04 +010012508
Victor Stinner9b1f4742016-09-06 16:18:52 -070012509#ifdef HAVE_GETRANDOM_SYSCALL
12510/*[clinic input]
12511os.getrandom
12512
12513 size: Py_ssize_t
12514 flags: int=0
12515
12516Obtain a series of random bytes.
12517[clinic start generated code]*/
12518
12519static PyObject *
12520os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12521/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12522{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012523 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012524 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012525
12526 if (size < 0) {
12527 errno = EINVAL;
12528 return posix_error();
12529 }
12530
Victor Stinnerec2319c2016-09-20 23:00:59 +020012531 bytes = PyBytes_FromStringAndSize(NULL, size);
12532 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012533 PyErr_NoMemory();
12534 return NULL;
12535 }
12536
12537 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012538 n = syscall(SYS_getrandom,
12539 PyBytes_AS_STRING(bytes),
12540 PyBytes_GET_SIZE(bytes),
12541 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012542 if (n < 0 && errno == EINTR) {
12543 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012544 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012545 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012546
12547 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012548 continue;
12549 }
12550 break;
12551 }
12552
12553 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012554 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012555 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012556 }
12557
Victor Stinnerec2319c2016-09-20 23:00:59 +020012558 if (n != size) {
12559 _PyBytes_Resize(&bytes, n);
12560 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012561
12562 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012563
12564error:
12565 Py_DECREF(bytes);
12566 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012567}
12568#endif /* HAVE_GETRANDOM_SYSCALL */
12569
Larry Hastings31826802013-10-19 00:09:25 -070012570
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012571static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012572
12573 OS_STAT_METHODDEF
12574 OS_ACCESS_METHODDEF
12575 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012576 OS_CHDIR_METHODDEF
12577 OS_CHFLAGS_METHODDEF
12578 OS_CHMOD_METHODDEF
12579 OS_FCHMOD_METHODDEF
12580 OS_LCHMOD_METHODDEF
12581 OS_CHOWN_METHODDEF
12582 OS_FCHOWN_METHODDEF
12583 OS_LCHOWN_METHODDEF
12584 OS_LCHFLAGS_METHODDEF
12585 OS_CHROOT_METHODDEF
12586 OS_CTERMID_METHODDEF
12587 OS_GETCWD_METHODDEF
12588 OS_GETCWDB_METHODDEF
12589 OS_LINK_METHODDEF
12590 OS_LISTDIR_METHODDEF
12591 OS_LSTAT_METHODDEF
12592 OS_MKDIR_METHODDEF
12593 OS_NICE_METHODDEF
12594 OS_GETPRIORITY_METHODDEF
12595 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012596#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012597 {"readlink", (PyCFunction)posix_readlink,
12598 METH_VARARGS | METH_KEYWORDS,
12599 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012600#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012601#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012602 {"readlink", (PyCFunction)win_readlink,
12603 METH_VARARGS | METH_KEYWORDS,
12604 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012605#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012606 OS_RENAME_METHODDEF
12607 OS_REPLACE_METHODDEF
12608 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012609 OS_SYMLINK_METHODDEF
12610 OS_SYSTEM_METHODDEF
12611 OS_UMASK_METHODDEF
12612 OS_UNAME_METHODDEF
12613 OS_UNLINK_METHODDEF
12614 OS_REMOVE_METHODDEF
12615 OS_UTIME_METHODDEF
12616 OS_TIMES_METHODDEF
12617 OS__EXIT_METHODDEF
12618 OS_EXECV_METHODDEF
12619 OS_EXECVE_METHODDEF
12620 OS_SPAWNV_METHODDEF
12621 OS_SPAWNVE_METHODDEF
12622 OS_FORK1_METHODDEF
12623 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012624 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012625 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12626 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12627 OS_SCHED_GETPARAM_METHODDEF
12628 OS_SCHED_GETSCHEDULER_METHODDEF
12629 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12630 OS_SCHED_SETPARAM_METHODDEF
12631 OS_SCHED_SETSCHEDULER_METHODDEF
12632 OS_SCHED_YIELD_METHODDEF
12633 OS_SCHED_SETAFFINITY_METHODDEF
12634 OS_SCHED_GETAFFINITY_METHODDEF
12635 OS_OPENPTY_METHODDEF
12636 OS_FORKPTY_METHODDEF
12637 OS_GETEGID_METHODDEF
12638 OS_GETEUID_METHODDEF
12639 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012640#ifdef HAVE_GETGROUPLIST
12641 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12642#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012643 OS_GETGROUPS_METHODDEF
12644 OS_GETPID_METHODDEF
12645 OS_GETPGRP_METHODDEF
12646 OS_GETPPID_METHODDEF
12647 OS_GETUID_METHODDEF
12648 OS_GETLOGIN_METHODDEF
12649 OS_KILL_METHODDEF
12650 OS_KILLPG_METHODDEF
12651 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012652#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012653 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012654#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012655 OS_SETUID_METHODDEF
12656 OS_SETEUID_METHODDEF
12657 OS_SETREUID_METHODDEF
12658 OS_SETGID_METHODDEF
12659 OS_SETEGID_METHODDEF
12660 OS_SETREGID_METHODDEF
12661 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012662#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012663 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012664#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012665 OS_GETPGID_METHODDEF
12666 OS_SETPGRP_METHODDEF
12667 OS_WAIT_METHODDEF
12668 OS_WAIT3_METHODDEF
12669 OS_WAIT4_METHODDEF
12670 OS_WAITID_METHODDEF
12671 OS_WAITPID_METHODDEF
12672 OS_GETSID_METHODDEF
12673 OS_SETSID_METHODDEF
12674 OS_SETPGID_METHODDEF
12675 OS_TCGETPGRP_METHODDEF
12676 OS_TCSETPGRP_METHODDEF
12677 OS_OPEN_METHODDEF
12678 OS_CLOSE_METHODDEF
12679 OS_CLOSERANGE_METHODDEF
12680 OS_DEVICE_ENCODING_METHODDEF
12681 OS_DUP_METHODDEF
12682 OS_DUP2_METHODDEF
12683 OS_LOCKF_METHODDEF
12684 OS_LSEEK_METHODDEF
12685 OS_READ_METHODDEF
12686 OS_READV_METHODDEF
12687 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012688 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012689 OS_WRITE_METHODDEF
12690 OS_WRITEV_METHODDEF
12691 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012692 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012693#ifdef HAVE_SENDFILE
12694 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12695 posix_sendfile__doc__},
12696#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012697 OS_FSTAT_METHODDEF
12698 OS_ISATTY_METHODDEF
12699 OS_PIPE_METHODDEF
12700 OS_PIPE2_METHODDEF
12701 OS_MKFIFO_METHODDEF
12702 OS_MKNOD_METHODDEF
12703 OS_MAJOR_METHODDEF
12704 OS_MINOR_METHODDEF
12705 OS_MAKEDEV_METHODDEF
12706 OS_FTRUNCATE_METHODDEF
12707 OS_TRUNCATE_METHODDEF
12708 OS_POSIX_FALLOCATE_METHODDEF
12709 OS_POSIX_FADVISE_METHODDEF
12710 OS_PUTENV_METHODDEF
12711 OS_UNSETENV_METHODDEF
12712 OS_STRERROR_METHODDEF
12713 OS_FCHDIR_METHODDEF
12714 OS_FSYNC_METHODDEF
12715 OS_SYNC_METHODDEF
12716 OS_FDATASYNC_METHODDEF
12717 OS_WCOREDUMP_METHODDEF
12718 OS_WIFCONTINUED_METHODDEF
12719 OS_WIFSTOPPED_METHODDEF
12720 OS_WIFSIGNALED_METHODDEF
12721 OS_WIFEXITED_METHODDEF
12722 OS_WEXITSTATUS_METHODDEF
12723 OS_WTERMSIG_METHODDEF
12724 OS_WSTOPSIG_METHODDEF
12725 OS_FSTATVFS_METHODDEF
12726 OS_STATVFS_METHODDEF
12727 OS_CONFSTR_METHODDEF
12728 OS_SYSCONF_METHODDEF
12729 OS_FPATHCONF_METHODDEF
12730 OS_PATHCONF_METHODDEF
12731 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012732 OS__GETFULLPATHNAME_METHODDEF
12733 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012734 OS__GETDISKUSAGE_METHODDEF
12735 OS__GETFINALPATHNAME_METHODDEF
12736 OS__GETVOLUMEPATHNAME_METHODDEF
12737 OS_GETLOADAVG_METHODDEF
12738 OS_URANDOM_METHODDEF
12739 OS_SETRESUID_METHODDEF
12740 OS_SETRESGID_METHODDEF
12741 OS_GETRESUID_METHODDEF
12742 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012743
Larry Hastings2f936352014-08-05 14:04:04 +100012744 OS_GETXATTR_METHODDEF
12745 OS_SETXATTR_METHODDEF
12746 OS_REMOVEXATTR_METHODDEF
12747 OS_LISTXATTR_METHODDEF
12748
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012749#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12750 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12751#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012752 OS_CPU_COUNT_METHODDEF
12753 OS_GET_INHERITABLE_METHODDEF
12754 OS_SET_INHERITABLE_METHODDEF
12755 OS_GET_HANDLE_INHERITABLE_METHODDEF
12756 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012757#ifndef MS_WINDOWS
12758 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12759 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12760#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012761 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012762 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012763 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012764 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012765};
12766
12767
Brian Curtin52173d42010-12-02 18:29:18 +000012768#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012769static int
Brian Curtin52173d42010-12-02 18:29:18 +000012770enable_symlink()
12771{
12772 HANDLE tok;
12773 TOKEN_PRIVILEGES tok_priv;
12774 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012775
12776 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012777 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012778
12779 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012780 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012781
12782 tok_priv.PrivilegeCount = 1;
12783 tok_priv.Privileges[0].Luid = luid;
12784 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12785
12786 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12787 sizeof(TOKEN_PRIVILEGES),
12788 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012789 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012790
Brian Curtin3b4499c2010-12-28 14:31:47 +000012791 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12792 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012793}
12794#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12795
Barry Warsaw4a342091996-12-19 23:50:02 +000012796static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012798{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012799#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012801#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012802#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012804#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012805#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012806 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012807#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012808#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012809 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012810#endif
Fred Drakec9680921999-12-13 16:37:25 +000012811#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012812 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012813#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012814#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012815 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012816#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012817#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012818 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012819#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012820#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012821 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012822#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012823#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012824 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012825#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012826#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012827 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012828#endif
12829#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012830 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012831#endif
12832#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012833 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012834#endif
12835#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012836 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012837#endif
12838#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012839 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012840#endif
12841#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012843#endif
12844#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012846#endif
12847#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012849#endif
12850#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012852#endif
12853#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012855#endif
12856#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012858#endif
12859#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012861#endif
12862#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012863 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012864#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012865#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012867#endif
12868#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012870#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012871#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012873#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012874#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012876#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012877#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012878#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012880#endif
12881#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012883#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012884#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012885#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012886 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012887#endif
12888#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012889 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012890#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012891#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012892 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012893#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012894#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012895 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012896#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012897#ifdef O_TMPFILE
12898 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12899#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012900#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012901 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012902#endif
12903#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012904 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012905#endif
12906#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012907 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012908#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012909#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012910 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012911#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012912#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012914#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012915
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012916
Jesus Cea94363612012-06-22 18:32:07 +020012917#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012918 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012919#endif
12920#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012922#endif
12923
Tim Peters5aa91602002-01-30 05:46:57 +000012924/* MS Windows */
12925#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012926 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012928#endif
12929#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012930 /* Optimize for short life (keep in memory). */
12931 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012932 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012933#endif
12934#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012935 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012937#endif
12938#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012939 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012941#endif
12942#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012943 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012944 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012945#endif
12946
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012947/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012948#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012949 /* Send a SIGIO signal whenever input or output
12950 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012951 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012952#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012953#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012954 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012955 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012956#endif
12957#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012958 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012959 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012960#endif
12961#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012962 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012963 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012964#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012965#ifdef O_NOLINKS
12966 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012967 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012968#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012969#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012970 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012971 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012972#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012973
Victor Stinner8c62be82010-05-06 00:08:46 +000012974 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012975#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012976 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012977#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012978#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012980#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012981#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012982 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012983#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012984#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012985 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012986#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012987#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012988 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012989#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012990#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012991 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012992#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012993#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012994 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012995#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012996#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012997 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012998#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012999#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013000 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013001#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013002#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013003 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013004#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013005#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013007#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013008#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013009 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013010#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013011#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013012 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013013#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013014#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013016#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013017#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013019#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013020#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013022#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013023#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013024 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013025#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013026
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013027 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013028#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013029 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013030#endif /* ST_RDONLY */
13031#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013032 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013033#endif /* ST_NOSUID */
13034
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013035 /* GNU extensions */
13036#ifdef ST_NODEV
13037 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13038#endif /* ST_NODEV */
13039#ifdef ST_NOEXEC
13040 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13041#endif /* ST_NOEXEC */
13042#ifdef ST_SYNCHRONOUS
13043 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13044#endif /* ST_SYNCHRONOUS */
13045#ifdef ST_MANDLOCK
13046 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13047#endif /* ST_MANDLOCK */
13048#ifdef ST_WRITE
13049 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13050#endif /* ST_WRITE */
13051#ifdef ST_APPEND
13052 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13053#endif /* ST_APPEND */
13054#ifdef ST_NOATIME
13055 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13056#endif /* ST_NOATIME */
13057#ifdef ST_NODIRATIME
13058 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13059#endif /* ST_NODIRATIME */
13060#ifdef ST_RELATIME
13061 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13062#endif /* ST_RELATIME */
13063
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013064 /* FreeBSD sendfile() constants */
13065#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013066 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013067#endif
13068#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013069 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013070#endif
13071#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013072 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013073#endif
13074
Ross Lagerwall7807c352011-03-17 20:20:30 +020013075 /* constants for posix_fadvise */
13076#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013077 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013078#endif
13079#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013080 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013081#endif
13082#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013083 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013084#endif
13085#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013086 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013087#endif
13088#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013089 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013090#endif
13091#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013092 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013093#endif
13094
13095 /* constants for waitid */
13096#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013097 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13098 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13099 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013100#endif
13101#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013102 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013103#endif
13104#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013105 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013106#endif
13107#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013108 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013109#endif
13110#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013111 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013112#endif
13113#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013114 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013115#endif
13116#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013117 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013118#endif
13119#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013120 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013121#endif
13122
13123 /* constants for lockf */
13124#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013125 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013126#endif
13127#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013128 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013129#endif
13130#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013131 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013132#endif
13133#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013134 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013135#endif
13136
Pablo Galindo4defba32018-01-27 16:16:37 +000013137#ifdef RWF_DSYNC
13138 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13139#endif
13140#ifdef RWF_HIPRI
13141 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13142#endif
13143#ifdef RWF_SYNC
13144 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13145#endif
13146#ifdef RWF_NOWAIT
13147 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13148#endif
13149
Guido van Rossum246bc171999-02-01 23:54:31 +000013150#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013151 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13152 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13153 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13154 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13155 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013156#endif
13157
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013158#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013159#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013160 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013161#endif
13162#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013163 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013164#endif
13165#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013166 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013167#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013168#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013169 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013170#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013171#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013172 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013173#endif
13174#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013175 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013176#endif
13177#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013178 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013179#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013180#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013181 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013182#endif
13183#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013184 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013185#endif
13186#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013187 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013188#endif
13189#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013190 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013191#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013192#endif
13193
Benjamin Peterson9428d532011-09-14 11:45:52 -040013194#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013195 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13196 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13197 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013198#endif
13199
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013200#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013201 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013202#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013203#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013204 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013205#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013206#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013207 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013208#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013209#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013210 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013211#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013212#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013213 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013214#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013215#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013216 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013217#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013218#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013219 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013220#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013221#if HAVE_DECL_RTLD_MEMBER
13222 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13223#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013224
Victor Stinner9b1f4742016-09-06 16:18:52 -070013225#ifdef HAVE_GETRANDOM_SYSCALL
13226 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13227 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13228#endif
13229
Victor Stinner8c62be82010-05-06 00:08:46 +000013230 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013231}
13232
13233
Martin v. Löwis1a214512008-06-11 05:26:20 +000013234static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013235 PyModuleDef_HEAD_INIT,
13236 MODNAME,
13237 posix__doc__,
13238 -1,
13239 posix_methods,
13240 NULL,
13241 NULL,
13242 NULL,
13243 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013244};
13245
13246
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013247static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013248
13249#ifdef HAVE_FACCESSAT
13250 "HAVE_FACCESSAT",
13251#endif
13252
13253#ifdef HAVE_FCHDIR
13254 "HAVE_FCHDIR",
13255#endif
13256
13257#ifdef HAVE_FCHMOD
13258 "HAVE_FCHMOD",
13259#endif
13260
13261#ifdef HAVE_FCHMODAT
13262 "HAVE_FCHMODAT",
13263#endif
13264
13265#ifdef HAVE_FCHOWN
13266 "HAVE_FCHOWN",
13267#endif
13268
Larry Hastings00964ed2013-08-12 13:49:30 -040013269#ifdef HAVE_FCHOWNAT
13270 "HAVE_FCHOWNAT",
13271#endif
13272
Larry Hastings9cf065c2012-06-22 16:30:09 -070013273#ifdef HAVE_FEXECVE
13274 "HAVE_FEXECVE",
13275#endif
13276
13277#ifdef HAVE_FDOPENDIR
13278 "HAVE_FDOPENDIR",
13279#endif
13280
Georg Brandl306336b2012-06-24 12:55:33 +020013281#ifdef HAVE_FPATHCONF
13282 "HAVE_FPATHCONF",
13283#endif
13284
Larry Hastings9cf065c2012-06-22 16:30:09 -070013285#ifdef HAVE_FSTATAT
13286 "HAVE_FSTATAT",
13287#endif
13288
13289#ifdef HAVE_FSTATVFS
13290 "HAVE_FSTATVFS",
13291#endif
13292
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013293#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013294 "HAVE_FTRUNCATE",
13295#endif
13296
Larry Hastings9cf065c2012-06-22 16:30:09 -070013297#ifdef HAVE_FUTIMENS
13298 "HAVE_FUTIMENS",
13299#endif
13300
13301#ifdef HAVE_FUTIMES
13302 "HAVE_FUTIMES",
13303#endif
13304
13305#ifdef HAVE_FUTIMESAT
13306 "HAVE_FUTIMESAT",
13307#endif
13308
13309#ifdef HAVE_LINKAT
13310 "HAVE_LINKAT",
13311#endif
13312
13313#ifdef HAVE_LCHFLAGS
13314 "HAVE_LCHFLAGS",
13315#endif
13316
13317#ifdef HAVE_LCHMOD
13318 "HAVE_LCHMOD",
13319#endif
13320
13321#ifdef HAVE_LCHOWN
13322 "HAVE_LCHOWN",
13323#endif
13324
13325#ifdef HAVE_LSTAT
13326 "HAVE_LSTAT",
13327#endif
13328
13329#ifdef HAVE_LUTIMES
13330 "HAVE_LUTIMES",
13331#endif
13332
13333#ifdef HAVE_MKDIRAT
13334 "HAVE_MKDIRAT",
13335#endif
13336
13337#ifdef HAVE_MKFIFOAT
13338 "HAVE_MKFIFOAT",
13339#endif
13340
13341#ifdef HAVE_MKNODAT
13342 "HAVE_MKNODAT",
13343#endif
13344
13345#ifdef HAVE_OPENAT
13346 "HAVE_OPENAT",
13347#endif
13348
13349#ifdef HAVE_READLINKAT
13350 "HAVE_READLINKAT",
13351#endif
13352
13353#ifdef HAVE_RENAMEAT
13354 "HAVE_RENAMEAT",
13355#endif
13356
13357#ifdef HAVE_SYMLINKAT
13358 "HAVE_SYMLINKAT",
13359#endif
13360
13361#ifdef HAVE_UNLINKAT
13362 "HAVE_UNLINKAT",
13363#endif
13364
13365#ifdef HAVE_UTIMENSAT
13366 "HAVE_UTIMENSAT",
13367#endif
13368
13369#ifdef MS_WINDOWS
13370 "MS_WINDOWS",
13371#endif
13372
13373 NULL
13374};
13375
13376
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013377PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013378INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013379{
Victor Stinner8c62be82010-05-06 00:08:46 +000013380 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013381 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013382 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013383
Brian Curtin52173d42010-12-02 18:29:18 +000013384#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013385 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013386#endif
13387
Victor Stinner8c62be82010-05-06 00:08:46 +000013388 m = PyModule_Create(&posixmodule);
13389 if (m == NULL)
13390 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013391
Victor Stinner8c62be82010-05-06 00:08:46 +000013392 /* Initialize environ dictionary */
13393 v = convertenviron();
13394 Py_XINCREF(v);
13395 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13396 return NULL;
13397 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013398
Victor Stinner8c62be82010-05-06 00:08:46 +000013399 if (all_ins(m))
13400 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013401
Victor Stinner8c62be82010-05-06 00:08:46 +000013402 if (setup_confname_tables(m))
13403 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013404
Victor Stinner8c62be82010-05-06 00:08:46 +000013405 Py_INCREF(PyExc_OSError);
13406 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013407
Guido van Rossumb3d39562000-01-31 18:41:26 +000013408#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013409 if (posix_putenv_garbage == NULL)
13410 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013411#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013412
Victor Stinner8c62be82010-05-06 00:08:46 +000013413 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013414#if defined(HAVE_WAITID) && !defined(__APPLE__)
13415 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013416 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13417 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013418#endif
13419
Christian Heimes25827622013-10-12 01:27:08 +020013420 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013421 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13422 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13423 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013424 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13425 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013426 structseq_new = StatResultType.tp_new;
13427 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013428
Christian Heimes25827622013-10-12 01:27:08 +020013429 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013430 if (PyStructSequence_InitType2(&StatVFSResultType,
13431 &statvfs_result_desc) < 0)
13432 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013433#ifdef NEED_TICKS_PER_SECOND
13434# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013435 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013436# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013437 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013438# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013439 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013440# endif
13441#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013442
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013443#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013444 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013445 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13446 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013447 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013448#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013449
13450 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013451 if (PyStructSequence_InitType2(&TerminalSizeType,
13452 &TerminalSize_desc) < 0)
13453 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013454
13455 /* initialize scandir types */
13456 if (PyType_Ready(&ScandirIteratorType) < 0)
13457 return NULL;
13458 if (PyType_Ready(&DirEntryType) < 0)
13459 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013460 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013461#if defined(HAVE_WAITID) && !defined(__APPLE__)
13462 Py_INCREF((PyObject*) &WaitidResultType);
13463 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13464#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013465 Py_INCREF((PyObject*) &StatResultType);
13466 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13467 Py_INCREF((PyObject*) &StatVFSResultType);
13468 PyModule_AddObject(m, "statvfs_result",
13469 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013470
13471#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013472 Py_INCREF(&SchedParamType);
13473 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013474#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013475
Larry Hastings605a62d2012-06-24 04:33:36 -070013476 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013477 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13478 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013479 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13480
13481 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013482 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13483 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013484 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13485
Thomas Wouters477c8d52006-05-27 19:21:47 +000013486#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013487 /*
13488 * Step 2 of weak-linking support on Mac OS X.
13489 *
13490 * The code below removes functions that are not available on the
13491 * currently active platform.
13492 *
13493 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013494 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013495 * OSX 10.4.
13496 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013497#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013498 if (fstatvfs == NULL) {
13499 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13500 return NULL;
13501 }
13502 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013503#endif /* HAVE_FSTATVFS */
13504
13505#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013506 if (statvfs == NULL) {
13507 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13508 return NULL;
13509 }
13510 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013511#endif /* HAVE_STATVFS */
13512
13513# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013514 if (lchown == NULL) {
13515 if (PyObject_DelAttrString(m, "lchown") == -1) {
13516 return NULL;
13517 }
13518 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013519#endif /* HAVE_LCHOWN */
13520
13521
13522#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013523
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013524 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013525 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13526
Larry Hastings6fe20b32012-04-19 15:07:49 -070013527 billion = PyLong_FromLong(1000000000);
13528 if (!billion)
13529 return NULL;
13530
Larry Hastings9cf065c2012-06-22 16:30:09 -070013531 /* suppress "function not used" warnings */
13532 {
13533 int ignored;
13534 fd_specified("", -1);
13535 follow_symlinks_specified("", 1);
13536 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13537 dir_fd_converter(Py_None, &ignored);
13538 dir_fd_unavailable(Py_None, &ignored);
13539 }
13540
13541 /*
13542 * provide list of locally available functions
13543 * so os.py can populate support_* lists
13544 */
13545 list = PyList_New(0);
13546 if (!list)
13547 return NULL;
13548 for (trace = have_functions; *trace; trace++) {
13549 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13550 if (!unicode)
13551 return NULL;
13552 if (PyList_Append(list, unicode))
13553 return NULL;
13554 Py_DECREF(unicode);
13555 }
13556 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013557
13558 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013559 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013560
13561 initialized = 1;
13562
Victor Stinner8c62be82010-05-06 00:08:46 +000013563 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013564}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013565
13566#ifdef __cplusplus
13567}
13568#endif