blob: f76bd57fe41beeb7d1362bbe0a9de00fc8801891 [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 IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100305#ifndef IO_REPARSE_TAG_MOUNT_POINT
306#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
307#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000309#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000311#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000312#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000313#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
314#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000315static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000316#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318
Tim Petersbc2e10e2002-03-03 23:17:02 +0000319#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320#if defined(PATH_MAX) && PATH_MAX > 1024
321#define MAXPATHLEN PATH_MAX
322#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#endif /* MAXPATHLEN */
326
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000327#ifdef UNION_WAIT
328/* Emulate some macros on systems that have a union instead of macros */
329
330#ifndef WIFEXITED
331#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
332#endif
333
334#ifndef WEXITSTATUS
335#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
336#endif
337
338#ifndef WTERMSIG
339#define WTERMSIG(u_wait) ((u_wait).w_termsig)
340#endif
341
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000342#define WAIT_TYPE union wait
343#define WAIT_STATUS_INT(s) (s.w_status)
344
345#else /* !UNION_WAIT */
346#define WAIT_TYPE int
347#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000348#endif /* UNION_WAIT */
349
Greg Wardb48bc172000-03-01 21:51:56 +0000350/* Don't use the "_r" form if we don't need it (also, won't have a
351 prototype for it, at least on Solaris -- maybe others as well?). */
Antoine Pitroua6a4dc82017-09-07 18:56:24 +0200352#if defined(HAVE_CTERMID_R)
Greg Wardb48bc172000-03-01 21:51:56 +0000353#define USE_CTERMID_R
354#endif
355
Fred Drake699f3522000-06-29 21:12:41 +0000356/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000357#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000358#undef FSTAT
359#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200360#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000361# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700362# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200363# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800364# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000365#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700367# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000368# define FSTAT fstat
369# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000370#endif
371
Tim Peters11b23062003-04-23 02:39:17 +0000372#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000373#include <sys/mkdev.h>
374#else
375#if defined(MAJOR_IN_SYSMACROS)
376#include <sys/sysmacros.h>
377#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000378#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
379#include <sys/mkdev.h>
380#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#endif
Fred Drake699f3522000-06-29 21:12:41 +0000382
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200383#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100384#define INITFUNC PyInit_nt
385#define MODNAME "nt"
386#else
387#define INITFUNC PyInit_posix
388#define MODNAME "posix"
389#endif
390
jcea6c51d512018-01-28 14:00:08 +0100391#if defined(__sun)
392/* Something to implement in autoconf, not present in autoconf 2.69 */
393#define HAVE_STRUCT_STAT_ST_FSTYPE 1
394#endif
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200395
Gregory P. Smithefcf08d2018-12-30 22:14:33 -0800396#ifdef _Py_MEMORY_SANITIZER
397# include <sanitizer/msan_interface.h>
398#endif
399
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200400#ifdef HAVE_FORK
401static void
402run_at_forkers(PyObject *lst, int reverse)
403{
404 Py_ssize_t i;
405 PyObject *cpy;
406
407 if (lst != NULL) {
408 assert(PyList_CheckExact(lst));
409
410 /* Use a list copy in case register_at_fork() is called from
411 * one of the callbacks.
412 */
413 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
414 if (cpy == NULL)
415 PyErr_WriteUnraisable(lst);
416 else {
417 if (reverse)
418 PyList_Reverse(cpy);
419 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
420 PyObject *func, *res;
421 func = PyList_GET_ITEM(cpy, i);
422 res = PyObject_CallObject(func, NULL);
423 if (res == NULL)
424 PyErr_WriteUnraisable(func);
425 else
426 Py_DECREF(res);
427 }
428 Py_DECREF(cpy);
429 }
430 }
431}
432
433void
434PyOS_BeforeFork(void)
435{
436 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
437
438 _PyImport_AcquireLock();
439}
440
441void
442PyOS_AfterFork_Parent(void)
443{
444 if (_PyImport_ReleaseLock() <= 0)
445 Py_FatalError("failed releasing import lock after fork");
446
447 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
448}
449
450void
451PyOS_AfterFork_Child(void)
452{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200453 _PyGILState_Reinit();
454 PyEval_ReInitThreads();
455 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200456 _PySignal_AfterFork();
457
458 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
459}
460
461static int
462register_at_forker(PyObject **lst, PyObject *func)
463{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700464 if (func == NULL) /* nothing to register? do nothing. */
465 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200466 if (*lst == NULL) {
467 *lst = PyList_New(0);
468 if (*lst == NULL)
469 return -1;
470 }
471 return PyList_Append(*lst, func);
472}
473#endif
474
475/* Legacy wrapper */
476void
477PyOS_AfterFork(void)
478{
479#ifdef HAVE_FORK
480 PyOS_AfterFork_Child();
481#endif
482}
483
484
Victor Stinner6036e442015-03-08 01:58:04 +0100485#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200486/* defined in fileutils.c */
487PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
488PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
489 ULONG, struct _Py_stat_struct *);
490#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700491
492#ifdef MS_WINDOWS
493static int
494win32_warn_bytes_api()
495{
496 return PyErr_WarnEx(PyExc_DeprecationWarning,
497 "The Windows bytes API has been deprecated, "
498 "use Unicode filenames instead",
499 1);
500}
501#endif
502
503
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200504#ifndef MS_WINDOWS
505PyObject *
506_PyLong_FromUid(uid_t uid)
507{
508 if (uid == (uid_t)-1)
509 return PyLong_FromLong(-1);
510 return PyLong_FromUnsignedLong(uid);
511}
512
513PyObject *
514_PyLong_FromGid(gid_t gid)
515{
516 if (gid == (gid_t)-1)
517 return PyLong_FromLong(-1);
518 return PyLong_FromUnsignedLong(gid);
519}
520
521int
522_Py_Uid_Converter(PyObject *obj, void *p)
523{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 uid_t uid;
525 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200527 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 unsigned long uresult;
529
530 index = PyNumber_Index(obj);
531 if (index == NULL) {
532 PyErr_Format(PyExc_TypeError,
533 "uid should be integer, not %.200s",
534 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200535 return 0;
536 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537
538 /*
539 * Handling uid_t is complicated for two reasons:
540 * * Although uid_t is (always?) unsigned, it still
541 * accepts -1.
542 * * We don't know its size in advance--it may be
543 * bigger than an int, or it may be smaller than
544 * a long.
545 *
546 * So a bit of defensive programming is in order.
547 * Start with interpreting the value passed
548 * in as a signed long and see if it works.
549 */
550
551 result = PyLong_AsLongAndOverflow(index, &overflow);
552
553 if (!overflow) {
554 uid = (uid_t)result;
555
556 if (result == -1) {
557 if (PyErr_Occurred())
558 goto fail;
559 /* It's a legitimate -1, we're done. */
560 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200561 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700562
563 /* Any other negative number is disallowed. */
564 if (result < 0)
565 goto underflow;
566
567 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569 (long)uid != result)
570 goto underflow;
571 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200572 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700573
574 if (overflow < 0)
575 goto underflow;
576
577 /*
578 * Okay, the value overflowed a signed long. If it
579 * fits in an *unsigned* long, it may still be okay,
580 * as uid_t may be unsigned long on this platform.
581 */
582 uresult = PyLong_AsUnsignedLong(index);
583 if (PyErr_Occurred()) {
584 if (PyErr_ExceptionMatches(PyExc_OverflowError))
585 goto overflow;
586 goto fail;
587 }
588
589 uid = (uid_t)uresult;
590
591 /*
592 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
593 * but this value would get interpreted as (uid_t)-1 by chown
594 * and its siblings. That's not what the user meant! So we
595 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100596 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700597 */
598 if (uid == (uid_t)-1)
599 goto overflow;
600
601 /* Ensure the value wasn't truncated. */
602 if (sizeof(uid_t) < sizeof(long) &&
603 (unsigned long)uid != uresult)
604 goto overflow;
605 /* fallthrough */
606
607success:
608 Py_DECREF(index);
609 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200610 return 1;
611
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700612underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200613 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700614 "uid is less than minimum");
615 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700617overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700619 "uid is greater than maximum");
620 /* fallthrough */
621
622fail:
623 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 return 0;
625}
626
627int
628_Py_Gid_Converter(PyObject *obj, void *p)
629{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700630 gid_t gid;
631 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200633 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700634 unsigned long uresult;
635
636 index = PyNumber_Index(obj);
637 if (index == NULL) {
638 PyErr_Format(PyExc_TypeError,
639 "gid should be integer, not %.200s",
640 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200641 return 0;
642 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700643
644 /*
645 * Handling gid_t is complicated for two reasons:
646 * * Although gid_t is (always?) unsigned, it still
647 * accepts -1.
648 * * We don't know its size in advance--it may be
649 * bigger than an int, or it may be smaller than
650 * a long.
651 *
652 * So a bit of defensive programming is in order.
653 * Start with interpreting the value passed
654 * in as a signed long and see if it works.
655 */
656
657 result = PyLong_AsLongAndOverflow(index, &overflow);
658
659 if (!overflow) {
660 gid = (gid_t)result;
661
662 if (result == -1) {
663 if (PyErr_Occurred())
664 goto fail;
665 /* It's a legitimate -1, we're done. */
666 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200667 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700668
669 /* Any other negative number is disallowed. */
670 if (result < 0) {
671 goto underflow;
672 }
673
674 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200675 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700676 (long)gid != result)
677 goto underflow;
678 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680
681 if (overflow < 0)
682 goto underflow;
683
684 /*
685 * Okay, the value overflowed a signed long. If it
686 * fits in an *unsigned* long, it may still be okay,
687 * as gid_t may be unsigned long on this platform.
688 */
689 uresult = PyLong_AsUnsignedLong(index);
690 if (PyErr_Occurred()) {
691 if (PyErr_ExceptionMatches(PyExc_OverflowError))
692 goto overflow;
693 goto fail;
694 }
695
696 gid = (gid_t)uresult;
697
698 /*
699 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
700 * but this value would get interpreted as (gid_t)-1 by chown
701 * and its siblings. That's not what the user meant! So we
702 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100703 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700704 */
705 if (gid == (gid_t)-1)
706 goto overflow;
707
708 /* Ensure the value wasn't truncated. */
709 if (sizeof(gid_t) < sizeof(long) &&
710 (unsigned long)gid != uresult)
711 goto overflow;
712 /* fallthrough */
713
714success:
715 Py_DECREF(index);
716 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200717 return 1;
718
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700719underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200720 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700721 "gid is less than minimum");
722 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200723
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700724overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200725 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700726 "gid is greater than maximum");
727 /* fallthrough */
728
729fail:
730 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200731 return 0;
732}
733#endif /* MS_WINDOWS */
734
735
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700736#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800737
738
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200739#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
740static int
741_Py_Dev_Converter(PyObject *obj, void *p)
742{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200743 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200744 if (PyErr_Occurred())
745 return 0;
746 return 1;
747}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800748#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200749
750
Larry Hastings9cf065c2012-06-22 16:30:09 -0700751#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400752/*
753 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
754 * without the int cast, the value gets interpreted as uint (4291925331),
755 * which doesn't play nicely with all the initializer lines in this file that
756 * look like this:
757 * int dir_fd = DEFAULT_DIR_FD;
758 */
759#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760#else
761#define DEFAULT_DIR_FD (-100)
762#endif
763
764static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300765_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200766{
767 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700768 long long_value;
769
770 PyObject *index = PyNumber_Index(o);
771 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700772 return 0;
773 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700774
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300775 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700776 long_value = PyLong_AsLongAndOverflow(index, &overflow);
777 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300778 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200779 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700781 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700782 return 0;
783 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200784 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700785 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700786 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700787 return 0;
788 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700789
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 *p = (int)long_value;
791 return 1;
792}
793
794static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200795dir_fd_converter(PyObject *o, void *p)
796{
797 if (o == Py_None) {
798 *(int *)p = DEFAULT_DIR_FD;
799 return 1;
800 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300801 else if (PyIndex_Check(o)) {
802 return _fd_converter(o, (int *)p);
803 }
804 else {
805 PyErr_Format(PyExc_TypeError,
806 "argument should be integer or None, not %.200s",
807 Py_TYPE(o)->tp_name);
808 return 0;
809 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700810}
811
812
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813/*
814 * A PyArg_ParseTuple "converter" function
815 * that handles filesystem paths in the manner
816 * preferred by the os module.
817 *
818 * path_converter accepts (Unicode) strings and their
819 * subclasses, and bytes and their subclasses. What
820 * it does with the argument depends on the platform:
821 *
822 * * On Windows, if we get a (Unicode) string we
823 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700824 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700825 *
826 * * On all other platforms, strings are encoded
827 * to bytes using PyUnicode_FSConverter, then we
828 * extract the char * from the bytes object and
829 * return that.
830 *
831 * path_converter also optionally accepts signed
832 * integers (representing open file descriptors) instead
833 * of path strings.
834 *
835 * Input fields:
836 * path.nullable
837 * If nonzero, the path is permitted to be None.
838 * path.allow_fd
839 * If nonzero, the path is permitted to be a file handle
840 * (a signed int) instead of a string.
841 * path.function_name
842 * If non-NULL, path_converter will use that as the name
843 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700844 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700845 * path.argument_name
846 * If non-NULL, path_converter will use that as the name
847 * of the parameter in error messages.
848 * (If path.argument_name is NULL it uses "path".)
849 *
850 * Output fields:
851 * path.wide
852 * Points to the path if it was expressed as Unicode
853 * and was not encoded. (Only used on Windows.)
854 * path.narrow
855 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700856 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000857 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700858 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859 * path.fd
860 * Contains a file descriptor if path.accept_fd was true
861 * and the caller provided a signed integer instead of any
862 * sort of string.
863 *
864 * WARNING: if your "path" parameter is optional, and is
865 * unspecified, path_converter will never get called.
866 * So if you set allow_fd, you *MUST* initialize path.fd = -1
867 * yourself!
868 * path.length
869 * The length of the path in characters, if specified as
870 * a string.
871 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800872 * The original object passed in (if get a PathLike object,
873 * the result of PyOS_FSPath() is treated as the original object).
874 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 * path.cleanup
876 * For internal use only. May point to a temporary object.
877 * (Pay no attention to the man behind the curtain.)
878 *
879 * At most one of path.wide or path.narrow will be non-NULL.
880 * If path was None and path.nullable was set,
881 * or if path was an integer and path.allow_fd was set,
882 * both path.wide and path.narrow will be NULL
883 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200884 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700885 * path_converter takes care to not write to the path_t
886 * unless it's successful. However it must reset the
887 * "cleanup" field each time it's called.
888 *
889 * Use as follows:
890 * path_t path;
891 * memset(&path, 0, sizeof(path));
892 * PyArg_ParseTuple(args, "O&", path_converter, &path);
893 * // ... use values from path ...
894 * path_cleanup(&path);
895 *
896 * (Note that if PyArg_Parse fails you don't need to call
897 * path_cleanup(). However it is safe to do so.)
898 */
899typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100900 const char *function_name;
901 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700902 int nullable;
903 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300904 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700905#ifdef MS_WINDOWS
906 BOOL narrow;
907#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300908 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700909#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700910 int fd;
911 Py_ssize_t length;
912 PyObject *object;
913 PyObject *cleanup;
914} path_t;
915
Steve Dowercc16be82016-09-08 10:35:16 -0700916#ifdef MS_WINDOWS
917#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
918 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
919#else
Larry Hastings2f936352014-08-05 14:04:04 +1000920#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
921 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700922#endif
Larry Hastings31826802013-10-19 00:09:25 -0700923
Larry Hastings9cf065c2012-06-22 16:30:09 -0700924static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800925path_cleanup(path_t *path)
926{
927 Py_CLEAR(path->object);
928 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929}
930
931static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300932path_converter(PyObject *o, void *p)
933{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800935 PyObject *bytes = NULL;
936 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700937 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300938 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700939#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800940 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700941 const wchar_t *wide;
942#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943
944#define FORMAT_EXCEPTION(exc, fmt) \
945 PyErr_Format(exc, "%s%s" fmt, \
946 path->function_name ? path->function_name : "", \
947 path->function_name ? ": " : "", \
948 path->argument_name ? path->argument_name : "path")
949
950 /* Py_CLEANUP_SUPPORTED support */
951 if (o == NULL) {
952 path_cleanup(path);
953 return 1;
954 }
955
Brett Cannon3f9183b2016-08-26 14:44:48 -0700956 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800957 path->object = path->cleanup = NULL;
958 /* path->object owns a reference to the original object */
959 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300961 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700963#ifdef MS_WINDOWS
964 path->narrow = FALSE;
965#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700967#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800969 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700970 }
971
Brett Cannon3f9183b2016-08-26 14:44:48 -0700972 /* Only call this here so that we don't treat the return value of
973 os.fspath() as an fd or buffer. */
974 is_index = path->allow_fd && PyIndex_Check(o);
975 is_buffer = PyObject_CheckBuffer(o);
976 is_bytes = PyBytes_Check(o);
977 is_unicode = PyUnicode_Check(o);
978
979 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
980 /* Inline PyOS_FSPath() for better error messages. */
981 _Py_IDENTIFIER(__fspath__);
982 PyObject *func = NULL;
983
984 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
985 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800986 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800988 /* still owns a reference to the original object */
989 Py_DECREF(o);
990 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700991 Py_DECREF(func);
992 if (NULL == o) {
993 goto error_exit;
994 }
995 else if (PyUnicode_Check(o)) {
996 is_unicode = 1;
997 }
998 else if (PyBytes_Check(o)) {
999 is_bytes = 1;
1000 }
1001 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001002 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001003 }
1004 }
1005
1006 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001008 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001009 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011 }
Victor Stinner59799a82013-11-13 14:17:30 +01001012 if (length > 32767) {
1013 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001016 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001017 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001019 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001020
1021 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001022 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001023 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001024 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001026 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001027 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001028 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001029#endif
1030 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001031 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001032 bytes = o;
1033 Py_INCREF(bytes);
1034 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001035 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001036 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001037 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001038 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1039 "%s%s%s should be %s, not %.200s",
1040 path->function_name ? path->function_name : "",
1041 path->function_name ? ": " : "",
1042 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1044 "integer or None" :
1045 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1046 path->nullable ? "string, bytes, os.PathLike or None" :
1047 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001050 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001051 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001053 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001054 }
1055 }
Steve Dowercc16be82016-09-08 10:35:16 -07001056 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001057 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001058 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001059 }
1060 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001061#ifdef MS_WINDOWS
1062 path->narrow = FALSE;
1063#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001064 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001065#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001066 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001067 }
1068 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001069 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001070 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1071 path->function_name ? path->function_name : "",
1072 path->function_name ? ": " : "",
1073 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001074 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1075 "integer or None" :
1076 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1077 path->nullable ? "string, bytes, os.PathLike or None" :
1078 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001079 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001080 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 }
1082
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001085 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001086 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001087 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001088 }
1089
Steve Dowercc16be82016-09-08 10:35:16 -07001090#ifdef MS_WINDOWS
1091 wo = PyUnicode_DecodeFSDefaultAndSize(
1092 narrow,
1093 length
1094 );
1095 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001096 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001097 }
1098
Xiang Zhang04316c42017-01-08 23:26:57 +08001099 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001100 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001102 }
1103 if (length > 32767) {
1104 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 if (wcslen(wide) != length) {
1108 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001110 }
1111 path->wide = wide;
1112 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001113 path->cleanup = wo;
1114 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001115#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001116 path->wide = NULL;
1117 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001118 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001119 /* Still a reference owned by path->object, don't have to
1120 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001122 }
1123 else {
1124 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001125 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001126#endif
1127 path->fd = -1;
1128
1129 success_exit:
1130 path->length = length;
1131 path->object = o;
1132 return Py_CLEANUP_SUPPORTED;
1133
1134 error_exit:
1135 Py_XDECREF(o);
1136 Py_XDECREF(bytes);
1137#ifdef MS_WINDOWS
1138 Py_XDECREF(wo);
1139#endif
1140 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141}
1142
1143static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001144argument_unavailable_error(const char *function_name, const char *argument_name)
1145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 PyErr_Format(PyExc_NotImplementedError,
1147 "%s%s%s unavailable on this platform",
1148 (function_name != NULL) ? function_name : "",
1149 (function_name != NULL) ? ": ": "",
1150 argument_name);
1151}
1152
1153static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001154dir_fd_unavailable(PyObject *o, void *p)
1155{
1156 int dir_fd;
1157 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001158 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001159 if (dir_fd != DEFAULT_DIR_FD) {
1160 argument_unavailable_error(NULL, "dir_fd");
1161 return 0;
1162 }
1163 *(int *)p = dir_fd;
1164 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165}
1166
1167static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001168fd_specified(const char *function_name, int fd)
1169{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 if (fd == -1)
1171 return 0;
1172
1173 argument_unavailable_error(function_name, "fd");
1174 return 1;
1175}
1176
1177static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001178follow_symlinks_specified(const char *function_name, int follow_symlinks)
1179{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001180 if (follow_symlinks)
1181 return 0;
1182
1183 argument_unavailable_error(function_name, "follow_symlinks");
1184 return 1;
1185}
1186
1187static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001188path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1189{
Steve Dowercc16be82016-09-08 10:35:16 -07001190 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1191#ifndef MS_WINDOWS
1192 && !path->narrow
1193#endif
1194 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001195 PyErr_Format(PyExc_ValueError,
1196 "%s: can't specify dir_fd without matching path",
1197 function_name);
1198 return 1;
1199 }
1200 return 0;
1201}
1202
1203static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001204dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1205{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1207 PyErr_Format(PyExc_ValueError,
1208 "%s: can't specify both dir_fd and fd",
1209 function_name);
1210 return 1;
1211 }
1212 return 0;
1213}
1214
1215static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001216fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1217 int follow_symlinks)
1218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 if ((fd > 0) && (!follow_symlinks)) {
1220 PyErr_Format(PyExc_ValueError,
1221 "%s: cannot use fd and follow_symlinks together",
1222 function_name);
1223 return 1;
1224 }
1225 return 0;
1226}
1227
1228static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001229dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1230 int follow_symlinks)
1231{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001232 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1233 PyErr_Format(PyExc_ValueError,
1234 "%s: cannot use dir_fd and follow_symlinks together",
1235 function_name);
1236 return 1;
1237 }
1238 return 0;
1239}
1240
Larry Hastings2f936352014-08-05 14:04:04 +10001241#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001242 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001243#else
Larry Hastings2f936352014-08-05 14:04:04 +10001244 typedef off_t Py_off_t;
1245#endif
1246
1247static int
1248Py_off_t_converter(PyObject *arg, void *addr)
1249{
1250#ifdef HAVE_LARGEFILE_SUPPORT
1251 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1252#else
1253 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001254#endif
1255 if (PyErr_Occurred())
1256 return 0;
1257 return 1;
1258}
Larry Hastings2f936352014-08-05 14:04:04 +10001259
1260static PyObject *
1261PyLong_FromPy_off_t(Py_off_t offset)
1262{
1263#ifdef HAVE_LARGEFILE_SUPPORT
1264 return PyLong_FromLongLong(offset);
1265#else
1266 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001267#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001268}
1269
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001270#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001271
1272static int
Brian Curtind25aef52011-06-13 15:16:04 -05001273win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274{
Martin Panter70214ad2016-08-04 02:38:59 +00001275 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1276 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001277 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278
1279 if (0 == DeviceIoControl(
1280 reparse_point_handle,
1281 FSCTL_GET_REPARSE_POINT,
1282 NULL, 0, /* in buffer */
1283 target_buffer, sizeof(target_buffer),
1284 &n_bytes_returned,
1285 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001286 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001287
1288 if (reparse_tag)
1289 *reparse_tag = rdb->ReparseTag;
1290
Brian Curtind25aef52011-06-13 15:16:04 -05001291 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001292}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001293
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001294#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001296/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001297#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001298/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001299** environ directly, we must obtain it with _NSGetEnviron(). See also
1300** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001301*/
1302#include <crt_externs.h>
1303static char **environ;
1304#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001306#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307
Barry Warsaw53699e91996-12-10 23:23:01 +00001308static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001309convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310{
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001313 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001314#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001315 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001316#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001317
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 d = PyDict_New();
1319 if (d == NULL)
1320 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001321#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 if (environ == NULL)
1323 environ = *_NSGetEnviron();
1324#endif
1325#ifdef MS_WINDOWS
1326 /* _wenviron must be initialized in this way if the program is started
1327 through main() instead of wmain(). */
1328 _wgetenv(L"");
1329 if (_wenviron == NULL)
1330 return d;
1331 /* This part ignores errors */
1332 for (e = _wenviron; *e != NULL; e++) {
1333 PyObject *k;
1334 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001335 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001336 if (p == NULL)
1337 continue;
1338 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1339 if (k == NULL) {
1340 PyErr_Clear();
1341 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001342 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1344 if (v == NULL) {
1345 PyErr_Clear();
1346 Py_DECREF(k);
1347 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001348 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 if (PyDict_GetItem(d, k) == NULL) {
1350 if (PyDict_SetItem(d, k, v) != 0)
1351 PyErr_Clear();
1352 }
1353 Py_DECREF(k);
1354 Py_DECREF(v);
1355 }
1356#else
1357 if (environ == NULL)
1358 return d;
1359 /* This part ignores errors */
1360 for (e = environ; *e != NULL; e++) {
1361 PyObject *k;
1362 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001363 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 if (p == NULL)
1365 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001366 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001367 if (k == NULL) {
1368 PyErr_Clear();
1369 continue;
1370 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001371 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 if (v == NULL) {
1373 PyErr_Clear();
1374 Py_DECREF(k);
1375 continue;
1376 }
1377 if (PyDict_GetItem(d, k) == NULL) {
1378 if (PyDict_SetItem(d, k, v) != 0)
1379 PyErr_Clear();
1380 }
1381 Py_DECREF(k);
1382 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001383 }
1384#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001386}
1387
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001388/* Set a POSIX-specific error from errno, and return NULL */
1389
Barry Warsawd58d7641998-07-23 16:14:40 +00001390static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001391posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001392{
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001394}
Mark Hammondef8b6542001-05-13 08:04:26 +00001395
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001396#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001397static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001398win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001399{
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 /* XXX We should pass the function name along in the future.
1401 (winreg.c also wants to pass the function name.)
1402 This would however require an additional param to the
1403 Windows error object, which is non-trivial.
1404 */
1405 errno = GetLastError();
1406 if (filename)
1407 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1408 else
1409 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001410}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001411
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001412static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001413win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001414{
1415 /* XXX - see win32_error for comments on 'function' */
1416 errno = GetLastError();
1417 if (filename)
1418 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001419 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001420 errno,
1421 filename);
1422 else
1423 return PyErr_SetFromWindowsErr(errno);
1424}
1425
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001426#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427
Larry Hastings9cf065c2012-06-22 16:30:09 -07001428static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001429posix_path_object_error(PyObject *path)
1430{
1431 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1432}
1433
1434static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001435path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436{
1437#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001438 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1439 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001440#else
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001441 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001442#endif
1443}
1444
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001445static PyObject *
1446path_object_error2(PyObject *path, PyObject *path2)
1447{
1448#ifdef MS_WINDOWS
1449 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1450 PyExc_OSError, 0, path, path2);
1451#else
1452 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1453#endif
1454}
1455
1456static PyObject *
1457path_error(path_t *path)
1458{
1459 return path_object_error(path->object);
1460}
Larry Hastings31826802013-10-19 00:09:25 -07001461
Larry Hastingsb0827312014-02-09 22:05:19 -08001462static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001463posix_path_error(path_t *path)
1464{
1465 return posix_path_object_error(path->object);
1466}
1467
1468static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001469path_error2(path_t *path, path_t *path2)
1470{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001471 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001472}
1473
1474
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001475/* POSIX generic methods */
1476
Larry Hastings2f936352014-08-05 14:04:04 +10001477static int
1478fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001479{
Victor Stinner8c62be82010-05-06 00:08:46 +00001480 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001481 int *pointer = (int *)p;
1482 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001483 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001484 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001485 *pointer = fd;
1486 return 1;
1487}
1488
1489static PyObject *
1490posix_fildes_fd(int fd, int (*func)(int))
1491{
1492 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001493 int async_err = 0;
1494
1495 do {
1496 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001497 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001498 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001499 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001500 Py_END_ALLOW_THREADS
1501 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1502 if (res != 0)
1503 return (!async_err) ? posix_error() : NULL;
1504 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001505}
Guido van Rossum21142a01999-01-08 21:05:37 +00001506
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001507
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001508#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001509/* This is a reimplementation of the C library's chdir function,
1510 but one that produces Win32 errors instead of DOS error codes.
1511 chdir is essentially a wrapper around SetCurrentDirectory; however,
1512 it also needs to set "magic" environment variables indicating
1513 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001514static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515win32_wchdir(LPCWSTR path)
1516{
Victor Stinnered537822015-12-13 21:40:26 +01001517 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 int result;
1519 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001520
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 if(!SetCurrentDirectoryW(path))
1522 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001523 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 if (!result)
1525 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001526 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001527 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001528 if (!new_path) {
1529 SetLastError(ERROR_OUTOFMEMORY);
1530 return FALSE;
1531 }
1532 result = GetCurrentDirectoryW(result, new_path);
1533 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001534 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001535 return FALSE;
1536 }
1537 }
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001538 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1539 wcsncmp(new_path, L"//", 2) == 0);
1540 if (!is_unc_like_path) {
1541 env[1] = new_path[0];
1542 result = SetEnvironmentVariableW(env, new_path);
1543 }
Victor Stinnered537822015-12-13 21:40:26 +01001544 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001545 PyMem_RawFree(new_path);
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001546 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547}
1548#endif
1549
Martin v. Löwis14694662006-02-03 12:54:16 +00001550#ifdef MS_WINDOWS
1551/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1552 - time stamps are restricted to second resolution
1553 - file modification times suffer from forth-and-back conversions between
1554 UTC and local time
1555 Therefore, we implement our own stat, based on the Win32 API directly.
1556*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001557#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001558#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001559
Victor Stinner6036e442015-03-08 01:58:04 +01001560static void
Steve Dowercc16be82016-09-08 10:35:16 -07001561find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1562 BY_HANDLE_FILE_INFORMATION *info,
1563 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001564{
1565 memset(info, 0, sizeof(*info));
1566 info->dwFileAttributes = pFileData->dwFileAttributes;
1567 info->ftCreationTime = pFileData->ftCreationTime;
1568 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1569 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1570 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1571 info->nFileSizeLow = pFileData->nFileSizeLow;
1572/* info->nNumberOfLinks = 1; */
1573 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1574 *reparse_tag = pFileData->dwReserved0;
1575 else
1576 *reparse_tag = 0;
1577}
1578
Guido van Rossumd8faa362007-04-27 19:54:29 +00001579static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001580attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001581{
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 HANDLE hFindFile;
1583 WIN32_FIND_DATAW FileData;
1584 hFindFile = FindFirstFileW(pszFile, &FileData);
1585 if (hFindFile == INVALID_HANDLE_VALUE)
1586 return FALSE;
1587 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001588 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001589 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001590}
1591
Brian Curtind25aef52011-06-13 15:16:04 -05001592static BOOL
1593get_target_path(HANDLE hdl, wchar_t **target_path)
1594{
1595 int buf_size, result_length;
1596 wchar_t *buf;
1597
1598 /* We have a good handle to the target, use it to determine
1599 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001600 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1601 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001602 if(!buf_size)
1603 return FALSE;
1604
Victor Stinnerc36674a2016-03-16 14:30:16 +01001605 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001606 if (!buf) {
1607 SetLastError(ERROR_OUTOFMEMORY);
1608 return FALSE;
1609 }
1610
Steve Dower2ea51c92015-03-20 21:49:12 -07001611 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001612 buf, buf_size, VOLUME_NAME_DOS);
1613
1614 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001615 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001616 return FALSE;
1617 }
1618
Brian Curtind25aef52011-06-13 15:16:04 -05001619 buf[result_length] = 0;
1620
1621 *target_path = buf;
1622 return TRUE;
1623}
1624
1625static int
Steve Dowercc16be82016-09-08 10:35:16 -07001626win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001627 BOOL traverse)
1628{
Victor Stinner26de69d2011-06-17 15:15:38 +02001629 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001630 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001631 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001632 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001633 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001634 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001635
Steve Dowercc16be82016-09-08 10:35:16 -07001636 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001637 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001638 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 0, /* share mode */
1640 NULL, /* security attributes */
1641 OPEN_EXISTING,
1642 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001643 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1644 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001645 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1647 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001648 NULL);
1649
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001650 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001651 /* Either the target doesn't exist, or we don't have access to
1652 get a handle to it. If the former, we need to return an error.
1653 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001654 DWORD lastError = GetLastError();
1655 if (lastError != ERROR_ACCESS_DENIED &&
1656 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001657 return -1;
1658 /* Could not get attributes on open file. Fall back to
1659 reading the directory. */
1660 if (!attributes_from_dir(path, &info, &reparse_tag))
1661 /* Very strange. This should not fail now */
1662 return -1;
1663 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1664 if (traverse) {
1665 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001666 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001667 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001668 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 } else {
1671 if (!GetFileInformationByHandle(hFile, &info)) {
1672 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001673 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674 }
1675 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Miss Islington (bot)63a69ef2019-02-02 13:29:07 -08001676 if (!win32_get_reparse_tag(hFile, &reparse_tag)) {
1677 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001678 return -1;
Miss Islington (bot)63a69ef2019-02-02 13:29:07 -08001679 }
Brian Curtind25aef52011-06-13 15:16:04 -05001680 /* Close the outer open file handle now that we're about to
1681 reopen it with different flags. */
1682 if (!CloseHandle(hFile))
1683 return -1;
1684
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001686 /* In order to call GetFinalPathNameByHandle we need to open
1687 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001688 hFile2 = CreateFileW(
1689 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1690 NULL, OPEN_EXISTING,
1691 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1692 NULL);
1693 if (hFile2 == INVALID_HANDLE_VALUE)
1694 return -1;
1695
Miss Islington (bot)63a69ef2019-02-02 13:29:07 -08001696 if (!get_target_path(hFile2, &target_path)) {
1697 CloseHandle(hFile2);
Brian Curtind25aef52011-06-13 15:16:04 -05001698 return -1;
Miss Islington (bot)63a69ef2019-02-02 13:29:07 -08001699 }
1700
1701 if (!CloseHandle(hFile2)) {
1702 return -1;
1703 }
Brian Curtind25aef52011-06-13 15:16:04 -05001704
Steve Dowercc16be82016-09-08 10:35:16 -07001705 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001706 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001707 return code;
1708 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001709 } else
1710 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001711 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001712 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001713
1714 /* Set S_IEXEC if it is an .exe, .bat, ... */
1715 dot = wcsrchr(path, '.');
1716 if (dot) {
1717 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1718 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1719 result->st_mode |= 0111;
1720 }
1721 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001722}
1723
1724static int
Steve Dowercc16be82016-09-08 10:35:16 -07001725win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001726{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001727 /* Protocol violation: we explicitly clear errno, instead of
1728 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001729 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001730 errno = 0;
1731 return code;
1732}
Brian Curtind25aef52011-06-13 15:16:04 -05001733/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001734
1735 In Posix, stat automatically traverses symlinks and returns the stat
1736 structure for the target. In Windows, the equivalent GetFileAttributes by
1737 default does not traverse symlinks and instead returns attributes for
1738 the symlink.
1739
1740 Therefore, win32_lstat will get the attributes traditionally, and
1741 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001742 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001743
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001744static int
Steve Dowercc16be82016-09-08 10:35:16 -07001745win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001746{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001747 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001748}
1749
Victor Stinner8c62be82010-05-06 00:08:46 +00001750static int
Steve Dowercc16be82016-09-08 10:35:16 -07001751win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001752{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001753 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001754}
1755
Martin v. Löwis14694662006-02-03 12:54:16 +00001756#endif /* MS_WINDOWS */
1757
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001758PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001759"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001760This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001761 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1763\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001764Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1765or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001766\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001768
1769static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_mode", "protection bits"},
1771 {"st_ino", "inode"},
1772 {"st_dev", "device"},
1773 {"st_nlink", "number of hard links"},
1774 {"st_uid", "user ID of owner"},
1775 {"st_gid", "group ID of owner"},
1776 {"st_size", "total size, in bytes"},
1777 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1778 {NULL, "integer time of last access"},
1779 {NULL, "integer time of last modification"},
1780 {NULL, "integer time of last change"},
1781 {"st_atime", "time of last access"},
1782 {"st_mtime", "time of last modification"},
1783 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001784 {"st_atime_ns", "time of last access in nanoseconds"},
1785 {"st_mtime_ns", "time of last modification in nanoseconds"},
1786 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001787#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001790#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001792#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001793#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001795#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001796#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001798#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001799#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001800 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001801#endif
1802#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001804#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001805#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1806 {"st_file_attributes", "Windows file attribute bits"},
1807#endif
jcea6c51d512018-01-28 14:00:08 +01001808#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1809 {"st_fstype", "Type of filesystem"},
1810#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812};
1813
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001814#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001815#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001816#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001817#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001818#endif
1819
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001820#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001821#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1822#else
1823#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1824#endif
1825
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001826#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001827#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1828#else
1829#define ST_RDEV_IDX ST_BLOCKS_IDX
1830#endif
1831
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001832#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1833#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1834#else
1835#define ST_FLAGS_IDX ST_RDEV_IDX
1836#endif
1837
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001838#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001839#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001840#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001841#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001842#endif
1843
1844#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1845#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1846#else
1847#define ST_BIRTHTIME_IDX ST_GEN_IDX
1848#endif
1849
Zachary Ware63f277b2014-06-19 09:46:37 -05001850#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1851#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1852#else
1853#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1854#endif
1855
jcea6c51d512018-01-28 14:00:08 +01001856#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1857#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1858#else
1859#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1860#endif
1861
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001862static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 "stat_result", /* name */
1864 stat_result__doc__, /* doc */
1865 stat_result_fields,
1866 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001867};
1868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001870"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1871This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001872 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001873or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001874\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001876
1877static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001878 {"f_bsize", },
1879 {"f_frsize", },
1880 {"f_blocks", },
1881 {"f_bfree", },
1882 {"f_bavail", },
1883 {"f_files", },
1884 {"f_ffree", },
1885 {"f_favail", },
1886 {"f_flag", },
1887 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001888 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001890};
1891
1892static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001893 "statvfs_result", /* name */
1894 statvfs_result__doc__, /* doc */
1895 statvfs_result_fields,
1896 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001897};
1898
Ross Lagerwall7807c352011-03-17 20:20:30 +02001899#if defined(HAVE_WAITID) && !defined(__APPLE__)
1900PyDoc_STRVAR(waitid_result__doc__,
1901"waitid_result: Result from waitid.\n\n\
1902This object may be accessed either as a tuple of\n\
1903 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1904or via the attributes si_pid, si_uid, and so on.\n\
1905\n\
1906See os.waitid for more information.");
1907
1908static PyStructSequence_Field waitid_result_fields[] = {
1909 {"si_pid", },
1910 {"si_uid", },
1911 {"si_signo", },
1912 {"si_status", },
1913 {"si_code", },
1914 {0}
1915};
1916
1917static PyStructSequence_Desc waitid_result_desc = {
1918 "waitid_result", /* name */
1919 waitid_result__doc__, /* doc */
1920 waitid_result_fields,
1921 5
1922};
1923static PyTypeObject WaitidResultType;
1924#endif
1925
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001926static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927static PyTypeObject StatResultType;
1928static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001929#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001930static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001931#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001932static newfunc structseq_new;
1933
1934static PyObject *
1935statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1936{
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 PyStructSequence *result;
1938 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001939
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 result = (PyStructSequence*)structseq_new(type, args, kwds);
1941 if (!result)
1942 return NULL;
1943 /* If we have been initialized from a tuple,
1944 st_?time might be set to None. Initialize it
1945 from the int slots. */
1946 for (i = 7; i <= 9; i++) {
1947 if (result->ob_item[i+3] == Py_None) {
1948 Py_DECREF(Py_None);
1949 Py_INCREF(result->ob_item[i]);
1950 result->ob_item[i+3] = result->ob_item[i];
1951 }
1952 }
1953 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001954}
1955
1956
Larry Hastings6fe20b32012-04-19 15:07:49 -07001957static PyObject *billion = NULL;
1958
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001959static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001960fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001961{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001962 PyObject *s = _PyLong_FromTime_t(sec);
1963 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1964 PyObject *s_in_ns = NULL;
1965 PyObject *ns_total = NULL;
1966 PyObject *float_s = NULL;
1967
1968 if (!(s && ns_fractional))
1969 goto exit;
1970
1971 s_in_ns = PyNumber_Multiply(s, billion);
1972 if (!s_in_ns)
1973 goto exit;
1974
1975 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1976 if (!ns_total)
1977 goto exit;
1978
Victor Stinner01b5aab2017-10-24 02:02:00 -07001979 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1980 if (!float_s) {
1981 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001982 }
1983
1984 PyStructSequence_SET_ITEM(v, index, s);
1985 PyStructSequence_SET_ITEM(v, index+3, float_s);
1986 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1987 s = NULL;
1988 float_s = NULL;
1989 ns_total = NULL;
1990exit:
1991 Py_XDECREF(s);
1992 Py_XDECREF(ns_fractional);
1993 Py_XDECREF(s_in_ns);
1994 Py_XDECREF(ns_total);
1995 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001996}
1997
Tim Peters5aa91602002-01-30 05:46:57 +00001998/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001999 (used by posix_stat() and posix_fstat()) */
2000static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002001_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002002{
Victor Stinner8c62be82010-05-06 00:08:46 +00002003 unsigned long ansec, mnsec, cnsec;
2004 PyObject *v = PyStructSequence_New(&StatResultType);
2005 if (v == NULL)
2006 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002007
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002009 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002010 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002011#ifdef MS_WINDOWS
2012 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002013#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002014 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002015#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002017#if defined(MS_WINDOWS)
2018 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2019 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2020#else
2021 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2022 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2023#endif
xdegaye50e86032017-05-22 11:15:08 +02002024 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2025 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002026
Martin v. Löwis14694662006-02-03 12:54:16 +00002027#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002028 ansec = st->st_atim.tv_nsec;
2029 mnsec = st->st_mtim.tv_nsec;
2030 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002031#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 ansec = st->st_atimespec.tv_nsec;
2033 mnsec = st->st_mtimespec.tv_nsec;
2034 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002035#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 ansec = st->st_atime_nsec;
2037 mnsec = st->st_mtime_nsec;
2038 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002039#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002041#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002042 fill_time(v, 7, st->st_atime, ansec);
2043 fill_time(v, 8, st->st_mtime, mnsec);
2044 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002045
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002046#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2048 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002049#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002050#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2052 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002053#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002054#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002055 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2056 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002057#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002058#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002059 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2060 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002061#endif
2062#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002064 PyObject *val;
2065 unsigned long bsec,bnsec;
2066 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002067#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002068 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002069#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002070 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002071#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002072 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002073 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2074 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002077#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002078 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2079 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002080#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002081#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2082 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2083 PyLong_FromUnsignedLong(st->st_file_attributes));
2084#endif
jcea6c51d512018-01-28 14:00:08 +01002085#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2086 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2087 PyUnicode_FromString(st->st_fstype));
2088#endif
Fred Drake699f3522000-06-29 21:12:41 +00002089
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 if (PyErr_Occurred()) {
2091 Py_DECREF(v);
2092 return NULL;
2093 }
Fred Drake699f3522000-06-29 21:12:41 +00002094
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002096}
2097
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002098/* POSIX methods */
2099
Guido van Rossum94f6f721999-01-06 18:42:14 +00002100
2101static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002102posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002103 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002104{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002105 STRUCT_STAT st;
2106 int result;
2107
2108#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2109 if (follow_symlinks_specified(function_name, follow_symlinks))
2110 return NULL;
2111#endif
2112
2113 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2114 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2115 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2116 return NULL;
2117
2118 Py_BEGIN_ALLOW_THREADS
2119 if (path->fd != -1)
2120 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002121#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002122 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002123 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002124 else
Steve Dowercc16be82016-09-08 10:35:16 -07002125 result = win32_lstat(path->wide, &st);
2126#else
2127 else
2128#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002129 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2130 result = LSTAT(path->narrow, &st);
2131 else
Steve Dowercc16be82016-09-08 10:35:16 -07002132#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002133#ifdef HAVE_FSTATAT
2134 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2135 result = fstatat(dir_fd, path->narrow, &st,
2136 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2137 else
Steve Dowercc16be82016-09-08 10:35:16 -07002138#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002139 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002140#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002141 Py_END_ALLOW_THREADS
2142
Victor Stinner292c8352012-10-30 02:17:38 +01002143 if (result != 0) {
2144 return path_error(path);
2145 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002146
2147 return _pystat_fromstructstat(&st);
2148}
2149
Larry Hastings2f936352014-08-05 14:04:04 +10002150/*[python input]
2151
2152for s in """
2153
2154FACCESSAT
2155FCHMODAT
2156FCHOWNAT
2157FSTATAT
2158LINKAT
2159MKDIRAT
2160MKFIFOAT
2161MKNODAT
2162OPENAT
2163READLINKAT
2164SYMLINKAT
2165UNLINKAT
2166
2167""".strip().split():
2168 s = s.strip()
2169 print("""
2170#ifdef HAVE_{s}
2171 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002172#else
Larry Hastings2f936352014-08-05 14:04:04 +10002173 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002174#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002175""".rstrip().format(s=s))
2176
2177for s in """
2178
2179FCHDIR
2180FCHMOD
2181FCHOWN
2182FDOPENDIR
2183FEXECVE
2184FPATHCONF
2185FSTATVFS
2186FTRUNCATE
2187
2188""".strip().split():
2189 s = s.strip()
2190 print("""
2191#ifdef HAVE_{s}
2192 #define PATH_HAVE_{s} 1
2193#else
2194 #define PATH_HAVE_{s} 0
2195#endif
2196
2197""".rstrip().format(s=s))
2198[python start generated code]*/
2199
2200#ifdef HAVE_FACCESSAT
2201 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_FCHMODAT
2207 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2208#else
2209 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2210#endif
2211
2212#ifdef HAVE_FCHOWNAT
2213 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_FSTATAT
2219 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_LINKAT
2225 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_MKDIRAT
2231 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_MKFIFOAT
2237 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_MKNODAT
2243 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_OPENAT
2249 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_READLINKAT
2255 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_SYMLINKAT
2261 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_UNLINKAT
2267 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2268#else
2269 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2270#endif
2271
2272#ifdef HAVE_FCHDIR
2273 #define PATH_HAVE_FCHDIR 1
2274#else
2275 #define PATH_HAVE_FCHDIR 0
2276#endif
2277
2278#ifdef HAVE_FCHMOD
2279 #define PATH_HAVE_FCHMOD 1
2280#else
2281 #define PATH_HAVE_FCHMOD 0
2282#endif
2283
2284#ifdef HAVE_FCHOWN
2285 #define PATH_HAVE_FCHOWN 1
2286#else
2287 #define PATH_HAVE_FCHOWN 0
2288#endif
2289
2290#ifdef HAVE_FDOPENDIR
2291 #define PATH_HAVE_FDOPENDIR 1
2292#else
2293 #define PATH_HAVE_FDOPENDIR 0
2294#endif
2295
2296#ifdef HAVE_FEXECVE
2297 #define PATH_HAVE_FEXECVE 1
2298#else
2299 #define PATH_HAVE_FEXECVE 0
2300#endif
2301
2302#ifdef HAVE_FPATHCONF
2303 #define PATH_HAVE_FPATHCONF 1
2304#else
2305 #define PATH_HAVE_FPATHCONF 0
2306#endif
2307
2308#ifdef HAVE_FSTATVFS
2309 #define PATH_HAVE_FSTATVFS 1
2310#else
2311 #define PATH_HAVE_FSTATVFS 0
2312#endif
2313
2314#ifdef HAVE_FTRUNCATE
2315 #define PATH_HAVE_FTRUNCATE 1
2316#else
2317 #define PATH_HAVE_FTRUNCATE 0
2318#endif
2319/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002320
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002321#ifdef MS_WINDOWS
2322 #undef PATH_HAVE_FTRUNCATE
2323 #define PATH_HAVE_FTRUNCATE 1
2324#endif
Larry Hastings31826802013-10-19 00:09:25 -07002325
Larry Hastings61272b72014-01-07 12:41:53 -08002326/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002327
2328class path_t_converter(CConverter):
2329
2330 type = "path_t"
2331 impl_by_reference = True
2332 parse_by_reference = True
2333
2334 converter = 'path_converter'
2335
2336 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002337 # right now path_t doesn't support default values.
2338 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002339 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002340 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002341
Larry Hastings2f936352014-08-05 14:04:04 +10002342 if self.c_default not in (None, 'Py_None'):
2343 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002344
2345 self.nullable = nullable
2346 self.allow_fd = allow_fd
2347
Larry Hastings7726ac92014-01-31 22:03:12 -08002348 def pre_render(self):
2349 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002350 if isinstance(value, str):
2351 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002352 return str(int(bool(value)))
2353
2354 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002355 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002356 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002357 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002358 strify(self.nullable),
2359 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002360 )
2361
2362 def cleanup(self):
2363 return "path_cleanup(&" + self.name + ");\n"
2364
2365
2366class dir_fd_converter(CConverter):
2367 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002368
Larry Hastings2f936352014-08-05 14:04:04 +10002369 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002370 if self.default in (unspecified, None):
2371 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002372 if isinstance(requires, str):
2373 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2374 else:
2375 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002376
Larry Hastings2f936352014-08-05 14:04:04 +10002377class fildes_converter(CConverter):
2378 type = 'int'
2379 converter = 'fildes_converter'
2380
2381class uid_t_converter(CConverter):
2382 type = "uid_t"
2383 converter = '_Py_Uid_Converter'
2384
2385class gid_t_converter(CConverter):
2386 type = "gid_t"
2387 converter = '_Py_Gid_Converter'
2388
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002389class dev_t_converter(CConverter):
2390 type = 'dev_t'
2391 converter = '_Py_Dev_Converter'
2392
2393class dev_t_return_converter(unsigned_long_return_converter):
2394 type = 'dev_t'
2395 conversion_fn = '_PyLong_FromDev'
2396 unsigned_cast = '(dev_t)'
2397
Larry Hastings2f936352014-08-05 14:04:04 +10002398class FSConverter_converter(CConverter):
2399 type = 'PyObject *'
2400 converter = 'PyUnicode_FSConverter'
2401 def converter_init(self):
2402 if self.default is not unspecified:
2403 fail("FSConverter_converter does not support default values")
2404 self.c_default = 'NULL'
2405
2406 def cleanup(self):
2407 return "Py_XDECREF(" + self.name + ");\n"
2408
2409class pid_t_converter(CConverter):
2410 type = 'pid_t'
2411 format_unit = '" _Py_PARSE_PID "'
2412
2413class idtype_t_converter(int_converter):
2414 type = 'idtype_t'
2415
2416class id_t_converter(CConverter):
2417 type = 'id_t'
2418 format_unit = '" _Py_PARSE_PID "'
2419
Benjamin Petersonca470632016-09-06 13:47:26 -07002420class intptr_t_converter(CConverter):
2421 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002422 format_unit = '" _Py_PARSE_INTPTR "'
2423
2424class Py_off_t_converter(CConverter):
2425 type = 'Py_off_t'
2426 converter = 'Py_off_t_converter'
2427
2428class Py_off_t_return_converter(long_return_converter):
2429 type = 'Py_off_t'
2430 conversion_fn = 'PyLong_FromPy_off_t'
2431
2432class path_confname_converter(CConverter):
2433 type="int"
2434 converter="conv_path_confname"
2435
2436class confstr_confname_converter(path_confname_converter):
2437 converter='conv_confstr_confname'
2438
2439class sysconf_confname_converter(path_confname_converter):
2440 converter="conv_sysconf_confname"
2441
2442class sched_param_converter(CConverter):
2443 type = 'struct sched_param'
2444 converter = 'convert_sched_param'
2445 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002446
Larry Hastings61272b72014-01-07 12:41:53 -08002447[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002448/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002449
Larry Hastings61272b72014-01-07 12:41:53 -08002450/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002451
Larry Hastings2a727912014-01-16 11:32:01 -08002452os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002453
2454 path : path_t(allow_fd=True)
BNMetrics08026b12018-11-02 17:56:25 +00002455 Path to be examined; can be string, bytes, a path-like object or
Xiang Zhang4459e002017-01-22 13:04:17 +08002456 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002457
2458 *
2459
Larry Hastings2f936352014-08-05 14:04:04 +10002460 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002461 If not None, it should be a file descriptor open to a directory,
2462 and path should be a relative string; path will then be relative to
2463 that directory.
2464
2465 follow_symlinks: bool = True
2466 If False, and the last element of the path is a symbolic link,
2467 stat will examine the symbolic link itself instead of the file
2468 the link points to.
2469
2470Perform a stat system call on the given path.
2471
2472dir_fd and follow_symlinks may not be implemented
2473 on your platform. If they are unavailable, using them will raise a
2474 NotImplementedError.
2475
2476It's an error to use dir_fd or follow_symlinks when specifying path as
2477 an open file descriptor.
2478
Larry Hastings61272b72014-01-07 12:41:53 -08002479[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002480
Larry Hastings31826802013-10-19 00:09:25 -07002481static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002482os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002483/*[clinic end generated code: output=7d4976e6f18a59c5 input=01d362ebcc06996b]*/
Larry Hastings31826802013-10-19 00:09:25 -07002484{
2485 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2486}
2487
Larry Hastings2f936352014-08-05 14:04:04 +10002488
2489/*[clinic input]
2490os.lstat
2491
2492 path : path_t
2493
2494 *
2495
2496 dir_fd : dir_fd(requires='fstatat') = None
2497
2498Perform a stat system call on the given path, without following symbolic links.
2499
2500Like stat(), but do not follow symbolic links.
2501Equivalent to stat(path, follow_symlinks=False).
2502[clinic start generated code]*/
2503
Larry Hastings2f936352014-08-05 14:04:04 +10002504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002505os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2506/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002507{
2508 int follow_symlinks = 0;
2509 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2510}
Larry Hastings31826802013-10-19 00:09:25 -07002511
Larry Hastings2f936352014-08-05 14:04:04 +10002512
Larry Hastings61272b72014-01-07 12:41:53 -08002513/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002514os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002515
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002516 path: path_t
BNMetrics08026b12018-11-02 17:56:25 +00002517 Path to be tested; can be string, bytes, or a path-like object.
Larry Hastings31826802013-10-19 00:09:25 -07002518
2519 mode: int
2520 Operating-system mode bitfield. Can be F_OK to test existence,
2521 or the inclusive-OR of R_OK, W_OK, and X_OK.
2522
2523 *
2524
Larry Hastings2f936352014-08-05 14:04:04 +10002525 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002526 If not None, it should be a file descriptor open to a directory,
2527 and path should be relative; path will then be relative to that
2528 directory.
2529
2530 effective_ids: bool = False
2531 If True, access will use the effective uid/gid instead of
2532 the real uid/gid.
2533
2534 follow_symlinks: bool = True
2535 If False, and the last element of the path is a symbolic link,
2536 access will examine the symbolic link itself instead of the file
2537 the link points to.
2538
2539Use the real uid/gid to test for access to a path.
2540
2541{parameters}
2542dir_fd, effective_ids, and follow_symlinks may not be implemented
2543 on your platform. If they are unavailable, using them will raise a
2544 NotImplementedError.
2545
2546Note that most operations will use the effective uid/gid, therefore this
2547 routine can be used in a suid/sgid environment to test if the invoking user
2548 has the specified access to the path.
2549
Larry Hastings61272b72014-01-07 12:41:53 -08002550[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002551
Larry Hastings2f936352014-08-05 14:04:04 +10002552static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002553os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002554 int effective_ids, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002555/*[clinic end generated code: output=cf84158bc90b1a77 input=3ffe4e650ee3bf20]*/
Larry Hastings31826802013-10-19 00:09:25 -07002556{
Larry Hastings2f936352014-08-05 14:04:04 +10002557 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002558
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002559#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002560 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002561#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002563#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002564
Larry Hastings9cf065c2012-06-22 16:30:09 -07002565#ifndef HAVE_FACCESSAT
2566 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002567 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002568
2569 if (effective_ids) {
2570 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002571 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 }
2573#endif
2574
2575#ifdef MS_WINDOWS
2576 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002577 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002578 Py_END_ALLOW_THREADS
2579
2580 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002581 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582 * * we didn't get a -1, and
2583 * * write access wasn't requested,
2584 * * or the file isn't read-only,
2585 * * or it's a directory.
2586 * (Directories cannot be read-only on Windows.)
2587 */
Larry Hastings2f936352014-08-05 14:04:04 +10002588 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002589 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002590 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002591 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002592#else
2593
2594 Py_BEGIN_ALLOW_THREADS
2595#ifdef HAVE_FACCESSAT
2596 if ((dir_fd != DEFAULT_DIR_FD) ||
2597 effective_ids ||
2598 !follow_symlinks) {
2599 int flags = 0;
2600 if (!follow_symlinks)
2601 flags |= AT_SYMLINK_NOFOLLOW;
2602 if (effective_ids)
2603 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002604 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605 }
2606 else
2607#endif
Larry Hastings31826802013-10-19 00:09:25 -07002608 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002609 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002610 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002611#endif
2612
Larry Hastings9cf065c2012-06-22 16:30:09 -07002613 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002614}
2615
Guido van Rossumd371ff11999-01-25 16:12:23 +00002616#ifndef F_OK
2617#define F_OK 0
2618#endif
2619#ifndef R_OK
2620#define R_OK 4
2621#endif
2622#ifndef W_OK
2623#define W_OK 2
2624#endif
2625#ifndef X_OK
2626#define X_OK 1
2627#endif
2628
Larry Hastings31826802013-10-19 00:09:25 -07002629
Guido van Rossumd371ff11999-01-25 16:12:23 +00002630#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002631/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002632os.ttyname -> DecodeFSDefault
2633
2634 fd: int
2635 Integer file descriptor handle.
2636
2637 /
2638
2639Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002640[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002641
Larry Hastings31826802013-10-19 00:09:25 -07002642static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002643os_ttyname_impl(PyObject *module, int fd)
2644/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002645{
2646 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002647
Larry Hastings31826802013-10-19 00:09:25 -07002648 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002649 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002650 posix_error();
2651 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002652}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002653#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002654
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002655#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002656/*[clinic input]
2657os.ctermid
2658
2659Return the name of the controlling terminal for this process.
2660[clinic start generated code]*/
2661
Larry Hastings2f936352014-08-05 14:04:04 +10002662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002663os_ctermid_impl(PyObject *module)
2664/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665{
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 char *ret;
2667 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002668
Greg Wardb48bc172000-03-01 21:51:56 +00002669#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002670 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002674 if (ret == NULL)
2675 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002676 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002677}
Larry Hastings2f936352014-08-05 14:04:04 +10002678#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002679
Larry Hastings2f936352014-08-05 14:04:04 +10002680
2681/*[clinic input]
2682os.chdir
2683
2684 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2685
2686Change the current working directory to the specified path.
2687
2688path may always be specified as a string.
2689On some platforms, path may also be specified as an open file descriptor.
2690 If this functionality is unavailable, using it raises an exception.
2691[clinic start generated code]*/
2692
Larry Hastings2f936352014-08-05 14:04:04 +10002693static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002694os_chdir_impl(PyObject *module, path_t *path)
2695/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002696{
2697 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002698
2699 Py_BEGIN_ALLOW_THREADS
2700#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002701 /* on unix, success = 0, on windows, success = !0 */
2702 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002703#else
2704#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002705 if (path->fd != -1)
2706 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002707 else
2708#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002709 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002710#endif
2711 Py_END_ALLOW_THREADS
2712
2713 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002714 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002715 }
2716
Larry Hastings2f936352014-08-05 14:04:04 +10002717 Py_RETURN_NONE;
2718}
2719
2720
2721#ifdef HAVE_FCHDIR
2722/*[clinic input]
2723os.fchdir
2724
2725 fd: fildes
2726
2727Change to the directory of the given file descriptor.
2728
2729fd must be opened on a directory, not a file.
2730Equivalent to os.chdir(fd).
2731
2732[clinic start generated code]*/
2733
Fred Drake4d1e64b2002-04-15 19:40:07 +00002734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002735os_fchdir_impl(PyObject *module, int fd)
2736/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002737{
Larry Hastings2f936352014-08-05 14:04:04 +10002738 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002739}
2740#endif /* HAVE_FCHDIR */
2741
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002742
Larry Hastings2f936352014-08-05 14:04:04 +10002743/*[clinic input]
2744os.chmod
2745
2746 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
BNMetrics08026b12018-11-02 17:56:25 +00002747 Path to be modified. May always be specified as a str, bytes, or a path-like object.
Larry Hastings2f936352014-08-05 14:04:04 +10002748 On some platforms, path may also be specified as an open file descriptor.
2749 If this functionality is unavailable, using it raises an exception.
2750
2751 mode: int
2752 Operating-system mode bitfield.
2753
2754 *
2755
2756 dir_fd : dir_fd(requires='fchmodat') = None
2757 If not None, it should be a file descriptor open to a directory,
2758 and path should be relative; path will then be relative to that
2759 directory.
2760
2761 follow_symlinks: bool = True
2762 If False, and the last element of the path is a symbolic link,
2763 chmod will modify the symbolic link itself instead of the file
2764 the link points to.
2765
2766Change the access permissions of a file.
2767
2768It is an error to use dir_fd or follow_symlinks when specifying path as
2769 an open file descriptor.
2770dir_fd and follow_symlinks may not be implemented on your platform.
2771 If they are unavailable, using them will raise a NotImplementedError.
2772
2773[clinic start generated code]*/
2774
Larry Hastings2f936352014-08-05 14:04:04 +10002775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002776os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002777 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00002778/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002779{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002782#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002783 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002785
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786#ifdef HAVE_FCHMODAT
2787 int fchmodat_nofollow_unsupported = 0;
2788#endif
2789
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2791 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002792 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793#endif
2794
2795#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002797 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002798 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799 result = 0;
2800 else {
2801 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002802 attr &= ~FILE_ATTRIBUTE_READONLY;
2803 else
2804 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002805 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002806 }
2807 Py_END_ALLOW_THREADS
2808
2809 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002810 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 }
2812#else /* MS_WINDOWS */
2813 Py_BEGIN_ALLOW_THREADS
2814#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002815 if (path->fd != -1)
2816 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 else
2818#endif
2819#ifdef HAVE_LCHMOD
2820 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002821 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822 else
2823#endif
2824#ifdef HAVE_FCHMODAT
2825 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2826 /*
2827 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2828 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002829 * and then says it isn't implemented yet.
2830 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 *
2832 * Once it is supported, os.chmod will automatically
2833 * support dir_fd and follow_symlinks=False. (Hopefully.)
2834 * Until then, we need to be careful what exception we raise.
2835 */
Larry Hastings2f936352014-08-05 14:04:04 +10002836 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2838 /*
2839 * But wait! We can't throw the exception without allowing threads,
2840 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2841 */
2842 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002843 result &&
2844 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2845 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 }
2847 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002848#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002849 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850 Py_END_ALLOW_THREADS
2851
2852 if (result) {
2853#ifdef HAVE_FCHMODAT
2854 if (fchmodat_nofollow_unsupported) {
2855 if (dir_fd != DEFAULT_DIR_FD)
2856 dir_fd_and_follow_symlinks_invalid("chmod",
2857 dir_fd, follow_symlinks);
2858 else
2859 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002860 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861 }
2862 else
2863#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002864 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865 }
2866#endif
2867
Larry Hastings2f936352014-08-05 14:04:04 +10002868 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002869}
2870
Larry Hastings9cf065c2012-06-22 16:30:09 -07002871
Christian Heimes4e30a842007-11-30 22:12:06 +00002872#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002873/*[clinic input]
2874os.fchmod
2875
2876 fd: int
2877 mode: int
2878
2879Change the access permissions of the file given by file descriptor fd.
2880
2881Equivalent to os.chmod(fd, mode).
2882[clinic start generated code]*/
2883
Larry Hastings2f936352014-08-05 14:04:04 +10002884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002885os_fchmod_impl(PyObject *module, int fd, int mode)
2886/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002887{
2888 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002889 int async_err = 0;
2890
2891 do {
2892 Py_BEGIN_ALLOW_THREADS
2893 res = fchmod(fd, mode);
2894 Py_END_ALLOW_THREADS
2895 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2896 if (res != 0)
2897 return (!async_err) ? posix_error() : NULL;
2898
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002900}
2901#endif /* HAVE_FCHMOD */
2902
Larry Hastings2f936352014-08-05 14:04:04 +10002903
Christian Heimes4e30a842007-11-30 22:12:06 +00002904#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002905/*[clinic input]
2906os.lchmod
2907
2908 path: path_t
2909 mode: int
2910
2911Change the access permissions of a file, without following symbolic links.
2912
2913If path is a symlink, this affects the link itself rather than the target.
2914Equivalent to chmod(path, mode, follow_symlinks=False)."
2915[clinic start generated code]*/
2916
Larry Hastings2f936352014-08-05 14:04:04 +10002917static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002918os_lchmod_impl(PyObject *module, path_t *path, int mode)
2919/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002920{
Victor Stinner8c62be82010-05-06 00:08:46 +00002921 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002923 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002924 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002925 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002926 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002927 return NULL;
2928 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002929 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002930}
2931#endif /* HAVE_LCHMOD */
2932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002933
Thomas Wouterscf297e42007-02-23 15:07:44 +00002934#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002935/*[clinic input]
2936os.chflags
2937
2938 path: path_t
2939 flags: unsigned_long(bitwise=True)
2940 follow_symlinks: bool=True
2941
2942Set file flags.
2943
2944If follow_symlinks is False, and the last element of the path is a symbolic
2945 link, chflags will change flags on the symbolic link itself instead of the
2946 file the link points to.
2947follow_symlinks may not be implemented on your platform. If it is
2948unavailable, using it will raise a NotImplementedError.
2949
2950[clinic start generated code]*/
2951
Larry Hastings2f936352014-08-05 14:04:04 +10002952static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002953os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002954 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002955/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002956{
2957 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958
2959#ifndef HAVE_LCHFLAGS
2960 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002961 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962#endif
2963
Victor Stinner8c62be82010-05-06 00:08:46 +00002964 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002965#ifdef HAVE_LCHFLAGS
2966 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002967 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002968 else
2969#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002970 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972
Larry Hastings2f936352014-08-05 14:04:04 +10002973 if (result)
2974 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975
Larry Hastings2f936352014-08-05 14:04:04 +10002976 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002977}
2978#endif /* HAVE_CHFLAGS */
2979
Larry Hastings2f936352014-08-05 14:04:04 +10002980
Thomas Wouterscf297e42007-02-23 15:07:44 +00002981#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002982/*[clinic input]
2983os.lchflags
2984
2985 path: path_t
2986 flags: unsigned_long(bitwise=True)
2987
2988Set file flags.
2989
2990This function will not follow symbolic links.
2991Equivalent to chflags(path, flags, follow_symlinks=False).
2992[clinic start generated code]*/
2993
Larry Hastings2f936352014-08-05 14:04:04 +10002994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002995os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2996/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002997{
Victor Stinner8c62be82010-05-06 00:08:46 +00002998 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002999 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003000 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003001 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003002 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003003 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003004 }
Victor Stinner292c8352012-10-30 02:17:38 +01003005 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003006}
3007#endif /* HAVE_LCHFLAGS */
3008
Larry Hastings2f936352014-08-05 14:04:04 +10003009
Martin v. Löwis244edc82001-10-04 22:44:26 +00003010#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003011/*[clinic input]
3012os.chroot
3013 path: path_t
3014
3015Change root directory to path.
3016
3017[clinic start generated code]*/
3018
Larry Hastings2f936352014-08-05 14:04:04 +10003019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003020os_chroot_impl(PyObject *module, path_t *path)
3021/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003022{
3023 int res;
3024 Py_BEGIN_ALLOW_THREADS
3025 res = chroot(path->narrow);
3026 Py_END_ALLOW_THREADS
3027 if (res < 0)
3028 return path_error(path);
3029 Py_RETURN_NONE;
3030}
3031#endif /* HAVE_CHROOT */
3032
Martin v. Löwis244edc82001-10-04 22:44:26 +00003033
Guido van Rossum21142a01999-01-08 21:05:37 +00003034#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003035/*[clinic input]
3036os.fsync
3037
3038 fd: fildes
3039
3040Force write of fd to disk.
3041[clinic start generated code]*/
3042
Larry Hastings2f936352014-08-05 14:04:04 +10003043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003044os_fsync_impl(PyObject *module, int fd)
3045/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003046{
3047 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003048}
3049#endif /* HAVE_FSYNC */
3050
Larry Hastings2f936352014-08-05 14:04:04 +10003051
Ross Lagerwall7807c352011-03-17 20:20:30 +02003052#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003053/*[clinic input]
3054os.sync
3055
3056Force write of everything to disk.
3057[clinic start generated code]*/
3058
Larry Hastings2f936352014-08-05 14:04:04 +10003059static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003060os_sync_impl(PyObject *module)
3061/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003062{
3063 Py_BEGIN_ALLOW_THREADS
3064 sync();
3065 Py_END_ALLOW_THREADS
3066 Py_RETURN_NONE;
3067}
Larry Hastings2f936352014-08-05 14:04:04 +10003068#endif /* HAVE_SYNC */
3069
Ross Lagerwall7807c352011-03-17 20:20:30 +02003070
Guido van Rossum21142a01999-01-08 21:05:37 +00003071#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003072#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003073extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3074#endif
3075
Larry Hastings2f936352014-08-05 14:04:04 +10003076/*[clinic input]
3077os.fdatasync
3078
3079 fd: fildes
3080
3081Force write of fd to disk without forcing update of metadata.
3082[clinic start generated code]*/
3083
Larry Hastings2f936352014-08-05 14:04:04 +10003084static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003085os_fdatasync_impl(PyObject *module, int fd)
3086/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003087{
3088 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003089}
3090#endif /* HAVE_FDATASYNC */
3091
3092
Fredrik Lundh10723342000-07-10 16:38:09 +00003093#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003094/*[clinic input]
3095os.chown
3096
3097 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
BNMetrics08026b12018-11-02 17:56:25 +00003098 Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int.
Larry Hastings2f936352014-08-05 14:04:04 +10003099
3100 uid: uid_t
3101
3102 gid: gid_t
3103
3104 *
3105
3106 dir_fd : dir_fd(requires='fchownat') = None
3107 If not None, it should be a file descriptor open to a directory,
3108 and path should be relative; path will then be relative to that
3109 directory.
3110
3111 follow_symlinks: bool = True
3112 If False, and the last element of the path is a symbolic link,
3113 stat will examine the symbolic link itself instead of the file
3114 the link points to.
3115
3116Change the owner and group id of path to the numeric uid and gid.\
3117
3118path may always be specified as a string.
3119On some platforms, path may also be specified as an open file descriptor.
3120 If this functionality is unavailable, using it raises an exception.
3121If dir_fd is not None, it should be a file descriptor open to a directory,
3122 and path should be relative; path will then be relative to that directory.
3123If follow_symlinks is False, and the last element of the path is a symbolic
3124 link, chown will modify the symbolic link itself instead of the file the
3125 link points to.
3126It is an error to use dir_fd or follow_symlinks when specifying path as
3127 an open file descriptor.
3128dir_fd and follow_symlinks may not be implemented on your platform.
3129 If they are unavailable, using them will raise a NotImplementedError.
3130
3131[clinic start generated code]*/
3132
Larry Hastings2f936352014-08-05 14:04:04 +10003133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003134os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003135 int dir_fd, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +00003136/*[clinic end generated code: output=4beadab0db5f70cd input=b08c5ec67996a97d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003137{
3138 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003139
3140#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3141 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003142 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003143#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003144 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3145 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3146 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003147
3148#ifdef __APPLE__
3149 /*
3150 * This is for Mac OS X 10.3, which doesn't have lchown.
3151 * (But we still have an lchown symbol because of weak-linking.)
3152 * It doesn't have fchownat either. So there's no possibility
3153 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003154 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003155 if ((!follow_symlinks) && (lchown == NULL)) {
3156 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003157 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003158 }
3159#endif
3160
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003163 if (path->fd != -1)
3164 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003165 else
3166#endif
3167#ifdef HAVE_LCHOWN
3168 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003169 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003170 else
3171#endif
3172#ifdef HAVE_FCHOWNAT
3173 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003174 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3176 else
3177#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003178 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003179 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003180
Larry Hastings2f936352014-08-05 14:04:04 +10003181 if (result)
3182 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003183
Larry Hastings2f936352014-08-05 14:04:04 +10003184 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003185}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003186#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003187
Larry Hastings2f936352014-08-05 14:04:04 +10003188
Christian Heimes4e30a842007-11-30 22:12:06 +00003189#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003190/*[clinic input]
3191os.fchown
3192
3193 fd: int
3194 uid: uid_t
3195 gid: gid_t
3196
3197Change the owner and group id of the file specified by file descriptor.
3198
3199Equivalent to os.chown(fd, uid, gid).
3200
3201[clinic start generated code]*/
3202
Larry Hastings2f936352014-08-05 14:04:04 +10003203static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003204os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3205/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003206{
Victor Stinner8c62be82010-05-06 00:08:46 +00003207 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003208 int async_err = 0;
3209
3210 do {
3211 Py_BEGIN_ALLOW_THREADS
3212 res = fchown(fd, uid, gid);
3213 Py_END_ALLOW_THREADS
3214 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3215 if (res != 0)
3216 return (!async_err) ? posix_error() : NULL;
3217
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003219}
3220#endif /* HAVE_FCHOWN */
3221
Larry Hastings2f936352014-08-05 14:04:04 +10003222
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003223#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003224/*[clinic input]
3225os.lchown
3226
3227 path : path_t
3228 uid: uid_t
3229 gid: gid_t
3230
3231Change the owner and group id of path to the numeric uid and gid.
3232
3233This function will not follow symbolic links.
3234Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3235[clinic start generated code]*/
3236
Larry Hastings2f936352014-08-05 14:04:04 +10003237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003238os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3239/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003240{
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003243 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003244 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003245 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003246 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003247 }
Larry Hastings2f936352014-08-05 14:04:04 +10003248 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003249}
3250#endif /* HAVE_LCHOWN */
3251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003252
Barry Warsaw53699e91996-12-10 23:23:01 +00003253static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003254posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003255{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003256 char *buf, *tmpbuf;
3257 char *cwd;
3258 const size_t chunk = 1024;
3259 size_t buflen = 0;
3260 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003261
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003262#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003264 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003265 wchar_t *wbuf2 = wbuf;
3266 PyObject *resobj;
3267 DWORD len;
3268 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003269 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003270 /* If the buffer is large enough, len does not include the
3271 terminating \0. If the buffer is too small, len includes
3272 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003273 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003274 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 if (wbuf2)
3276 len = GetCurrentDirectoryW(len, wbuf2);
3277 }
3278 Py_END_ALLOW_THREADS
3279 if (!wbuf2) {
3280 PyErr_NoMemory();
3281 return NULL;
3282 }
3283 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003284 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003285 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003286 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 }
3288 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003289 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003290 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 return resobj;
3292 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003293
3294 if (win32_warn_bytes_api())
3295 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003296#endif
3297
Victor Stinner4403d7d2015-04-25 00:16:10 +02003298 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003300 do {
3301 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003302#ifdef MS_WINDOWS
3303 if (buflen > INT_MAX) {
3304 PyErr_NoMemory();
3305 break;
3306 }
3307#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003308 tmpbuf = PyMem_RawRealloc(buf, buflen);
3309 if (tmpbuf == NULL)
3310 break;
3311
3312 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003313#ifdef MS_WINDOWS
3314 cwd = getcwd(buf, (int)buflen);
3315#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003316 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003317#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003318 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003319 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003320
3321 if (cwd == NULL) {
3322 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003324 }
3325
Victor Stinner8c62be82010-05-06 00:08:46 +00003326 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003327 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3328 else
3329 obj = PyUnicode_DecodeFSDefault(buf);
3330 PyMem_RawFree(buf);
3331
3332 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003333}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003334
Larry Hastings2f936352014-08-05 14:04:04 +10003335
3336/*[clinic input]
3337os.getcwd
3338
3339Return a unicode string representing the current working directory.
3340[clinic start generated code]*/
3341
Larry Hastings2f936352014-08-05 14:04:04 +10003342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003343os_getcwd_impl(PyObject *module)
3344/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003345{
3346 return posix_getcwd(0);
3347}
3348
Larry Hastings2f936352014-08-05 14:04:04 +10003349
3350/*[clinic input]
3351os.getcwdb
3352
3353Return a bytes string representing the current working directory.
3354[clinic start generated code]*/
3355
Larry Hastings2f936352014-08-05 14:04:04 +10003356static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003357os_getcwdb_impl(PyObject *module)
3358/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003359{
3360 return posix_getcwd(1);
3361}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003362
Larry Hastings2f936352014-08-05 14:04:04 +10003363
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3365#define HAVE_LINK 1
3366#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003367
Guido van Rossumb6775db1994-08-01 11:34:53 +00003368#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003369/*[clinic input]
3370
3371os.link
3372
3373 src : path_t
3374 dst : path_t
3375 *
3376 src_dir_fd : dir_fd = None
3377 dst_dir_fd : dir_fd = None
3378 follow_symlinks: bool = True
3379
3380Create a hard link to a file.
3381
3382If either src_dir_fd or dst_dir_fd is not None, it should be a file
3383 descriptor open to a directory, and the respective path string (src or dst)
3384 should be relative; the path will then be relative to that directory.
3385If follow_symlinks is False, and the last element of src is a symbolic
3386 link, link will create a link to the symbolic link itself instead of the
3387 file the link points to.
3388src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3389 platform. If they are unavailable, using them will raise a
3390 NotImplementedError.
3391[clinic start generated code]*/
3392
Larry Hastings2f936352014-08-05 14:04:04 +10003393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003394os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003395 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003396/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003397{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003399 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400#else
3401 int result;
3402#endif
3403
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404#ifndef HAVE_LINKAT
3405 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3406 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003407 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 }
3409#endif
3410
Steve Dowercc16be82016-09-08 10:35:16 -07003411#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003412 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413 PyErr_SetString(PyExc_NotImplementedError,
3414 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003415 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 }
Steve Dowercc16be82016-09-08 10:35:16 -07003417#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003418
Brian Curtin1b9df392010-11-24 20:24:31 +00003419#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003421 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003423
Larry Hastings2f936352014-08-05 14:04:04 +10003424 if (!result)
3425 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426#else
3427 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003428#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3430 (dst_dir_fd != DEFAULT_DIR_FD) ||
3431 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003432 result = linkat(src_dir_fd, src->narrow,
3433 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3435 else
Steve Dowercc16be82016-09-08 10:35:16 -07003436#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003437 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003439
Larry Hastings2f936352014-08-05 14:04:04 +10003440 if (result)
3441 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003442#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443
Larry Hastings2f936352014-08-05 14:04:04 +10003444 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003445}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446#endif
3447
Brian Curtin1b9df392010-11-24 20:24:31 +00003448
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003449#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003450static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003451_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003452{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 PyObject *v;
3454 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3455 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003456 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003458 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003459 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460
Steve Dowercc16be82016-09-08 10:35:16 -07003461 WIN32_FIND_DATAW wFileData;
3462 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003463
Steve Dowercc16be82016-09-08 10:35:16 -07003464 if (!path->wide) { /* Default arg: "." */
3465 po_wchars = L".";
3466 len = 1;
3467 } else {
3468 po_wchars = path->wide;
3469 len = wcslen(path->wide);
3470 }
3471 /* The +5 is so we can append "\\*.*\0" */
3472 wnamebuf = PyMem_New(wchar_t, len + 5);
3473 if (!wnamebuf) {
3474 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 }
Steve Dowercc16be82016-09-08 10:35:16 -07003477 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003479 wchar_t wch = wnamebuf[len-1];
3480 if (wch != SEP && wch != ALTSEP && wch != L':')
3481 wnamebuf[len++] = SEP;
3482 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003483 }
Steve Dowercc16be82016-09-08 10:35:16 -07003484 if ((list = PyList_New(0)) == NULL) {
3485 goto exit;
3486 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003487 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003488 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003489 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 if (hFindFile == INVALID_HANDLE_VALUE) {
3491 int error = GetLastError();
3492 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 goto exit;
3494 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003495 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 }
3498 do {
3499 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003500 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3501 wcscmp(wFileData.cFileName, L"..") != 0) {
3502 v = PyUnicode_FromWideChar(wFileData.cFileName,
3503 wcslen(wFileData.cFileName));
3504 if (path->narrow && v) {
3505 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3506 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 Py_DECREF(list);
3509 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 break;
3511 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 Py_DECREF(list);
3515 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 break;
3517 }
3518 Py_DECREF(v);
3519 }
3520 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003521 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 Py_END_ALLOW_THREADS
3523 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3524 it got to the end of the directory. */
3525 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003527 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 }
3530 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003531
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532exit:
3533 if (hFindFile != INVALID_HANDLE_VALUE) {
3534 if (FindClose(hFindFile) == FALSE) {
3535 if (list != NULL) {
3536 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003537 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 }
3539 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003541 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003542
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003544} /* end of _listdir_windows_no_opendir */
3545
3546#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3547
3548static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003549_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003550{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003551 PyObject *v;
3552 DIR *dirp = NULL;
3553 struct dirent *ep;
3554 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003555#ifdef HAVE_FDOPENDIR
3556 int fd = -1;
3557#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003558
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003561 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003563 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003564 if (fd == -1)
3565 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566
Larry Hastingsfdaea062012-06-25 04:42:23 -07003567 return_str = 1;
3568
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 Py_BEGIN_ALLOW_THREADS
3570 dirp = fdopendir(fd);
3571 Py_END_ALLOW_THREADS
3572 }
3573 else
3574#endif
3575 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003576 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003577 if (path->narrow) {
3578 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003579 /* only return bytes if they specified a bytes-like object */
3580 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003581 }
3582 else {
3583 name = ".";
3584 return_str = 1;
3585 }
3586
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 Py_BEGIN_ALLOW_THREADS
3588 dirp = opendir(name);
3589 Py_END_ALLOW_THREADS
3590 }
3591
3592 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003593 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003594#ifdef HAVE_FDOPENDIR
3595 if (fd != -1) {
3596 Py_BEGIN_ALLOW_THREADS
3597 close(fd);
3598 Py_END_ALLOW_THREADS
3599 }
3600#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 goto exit;
3602 }
3603 if ((list = PyList_New(0)) == NULL) {
3604 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 }
3606 for (;;) {
3607 errno = 0;
3608 Py_BEGIN_ALLOW_THREADS
3609 ep = readdir(dirp);
3610 Py_END_ALLOW_THREADS
3611 if (ep == NULL) {
3612 if (errno == 0) {
3613 break;
3614 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003616 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 }
3619 }
3620 if (ep->d_name[0] == '.' &&
3621 (NAMLEN(ep) == 1 ||
3622 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3623 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003624 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003625 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3626 else
3627 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 break;
3631 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 break;
3636 }
3637 Py_DECREF(v);
3638 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003639
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640exit:
3641 if (dirp != NULL) {
3642 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003643#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 if (fd > -1)
3645 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003646#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 closedir(dirp);
3648 Py_END_ALLOW_THREADS
3649 }
3650
Larry Hastings9cf065c2012-06-22 16:30:09 -07003651 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003652} /* end of _posix_listdir */
3653#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003654
Larry Hastings2f936352014-08-05 14:04:04 +10003655
3656/*[clinic input]
3657os.listdir
3658
3659 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3660
3661Return a list containing the names of the files in the directory.
3662
BNMetrics08026b12018-11-02 17:56:25 +00003663path can be specified as either str, bytes, or a path-like object. If path is bytes,
Larry Hastings2f936352014-08-05 14:04:04 +10003664 the filenames returned will also be bytes; in all other circumstances
3665 the filenames returned will be str.
3666If path is None, uses the path='.'.
3667On some platforms, path may also be specified as an open file descriptor;\
3668 the file descriptor must refer to a directory.
3669 If this functionality is unavailable, using it raises NotImplementedError.
3670
3671The list is in arbitrary order. It does not include the special
3672entries '.' and '..' even if they are present in the directory.
3673
3674
3675[clinic start generated code]*/
3676
Larry Hastings2f936352014-08-05 14:04:04 +10003677static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003678os_listdir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +00003679/*[clinic end generated code: output=293045673fcd1a75 input=e3f58030f538295d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003680{
3681#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3682 return _listdir_windows_no_opendir(path, NULL);
3683#else
3684 return _posix_listdir(path, NULL);
3685#endif
3686}
3687
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003688#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003689/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003690/*[clinic input]
3691os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003692
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003693 path: path_t
3694 /
3695
3696[clinic start generated code]*/
3697
3698static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003699os__getfullpathname_impl(PyObject *module, path_t *path)
3700/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003701{
Steve Dowercc16be82016-09-08 10:35:16 -07003702 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3703 wchar_t *wtemp;
3704 DWORD result;
3705 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003706
Steve Dowercc16be82016-09-08 10:35:16 -07003707 result = GetFullPathNameW(path->wide,
3708 Py_ARRAY_LENGTH(woutbuf),
3709 woutbuf, &wtemp);
3710 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3711 woutbufp = PyMem_New(wchar_t, result);
3712 if (!woutbufp)
3713 return PyErr_NoMemory();
3714 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 }
Steve Dowercc16be82016-09-08 10:35:16 -07003716 if (result) {
3717 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3718 if (path->narrow)
3719 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3720 } else
3721 v = win32_error_object("GetFullPathNameW", path->object);
3722 if (woutbufp != woutbuf)
3723 PyMem_Free(woutbufp);
3724 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003725}
Brian Curtind40e6f72010-07-08 21:39:08 +00003726
Brian Curtind25aef52011-06-13 15:16:04 -05003727
Larry Hastings2f936352014-08-05 14:04:04 +10003728/*[clinic input]
3729os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003730
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003731 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003732 /
3733
3734A helper function for samepath on windows.
3735[clinic start generated code]*/
3736
Larry Hastings2f936352014-08-05 14:04:04 +10003737static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003738os__getfinalpathname_impl(PyObject *module, path_t *path)
3739/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003740{
3741 HANDLE hFile;
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003742 wchar_t buf[MAXPATHLEN], *target_path = buf;
3743 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003745 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003746
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003747 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003748 hFile = CreateFileW(
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003749 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003750 0, /* desired access */
3751 0, /* share mode */
3752 NULL, /* security attributes */
3753 OPEN_EXISTING,
3754 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3755 FILE_FLAG_BACKUP_SEMANTICS,
3756 NULL);
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003757 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003758
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003759 if (hFile == INVALID_HANDLE_VALUE) {
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003760 return win32_error_object("CreateFileW", path->object);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003761 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003762
3763 /* We have a good handle to the target, use it to determine the
3764 target path name. */
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003765 while (1) {
3766 Py_BEGIN_ALLOW_THREADS
3767 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3768 buf_size, VOLUME_NAME_DOS);
3769 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003770
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003771 if (!result_length) {
3772 result = win32_error_object("GetFinalPathNameByHandleW",
3773 path->object);
3774 goto cleanup;
3775 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003776
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003777 if (result_length < buf_size) {
3778 break;
3779 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003780
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003781 wchar_t *tmp;
3782 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3783 result_length * sizeof(*tmp));
3784 if (!tmp) {
3785 result = PyErr_NoMemory();
3786 goto cleanup;
3787 }
3788
3789 buf_size = result_length;
3790 target_path = tmp;
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003791 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003792
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003793 result = PyUnicode_FromWideChar(target_path, result_length);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003794 if (path->narrow)
3795 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003796
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003797cleanup:
3798 if (target_path != buf) {
3799 PyMem_Free(target_path);
3800 }
3801 CloseHandle(hFile);
3802 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003803}
Brian Curtin62857742010-09-06 17:07:27 +00003804
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003805/*[clinic input]
3806os._isdir
3807
3808 path: path_t
3809 /
3810
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003811Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003812[clinic start generated code]*/
3813
Brian Curtin9c669cc2011-06-08 18:17:18 -05003814static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003815os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003816/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003817{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003818 DWORD attributes;
3819
Steve Dowerb22a6772016-07-17 20:49:38 -07003820 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003821 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003822 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003823
Brian Curtin9c669cc2011-06-08 18:17:18 -05003824 if (attributes == INVALID_FILE_ATTRIBUTES)
3825 Py_RETURN_FALSE;
3826
Brian Curtin9c669cc2011-06-08 18:17:18 -05003827 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3828 Py_RETURN_TRUE;
3829 else
3830 Py_RETURN_FALSE;
3831}
Tim Golden6b528062013-08-01 12:44:00 +01003832
Tim Golden6b528062013-08-01 12:44:00 +01003833
Larry Hastings2f936352014-08-05 14:04:04 +10003834/*[clinic input]
3835os._getvolumepathname
3836
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003837 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003838
3839A helper function for ismount on Win32.
3840[clinic start generated code]*/
3841
Larry Hastings2f936352014-08-05 14:04:04 +10003842static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003843os__getvolumepathname_impl(PyObject *module, path_t *path)
3844/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003845{
3846 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003847 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003848 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003849 BOOL ret;
3850
Tim Golden6b528062013-08-01 12:44:00 +01003851 /* Volume path should be shorter than entire path */
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003852 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003853
Victor Stinner850a18e2017-10-24 16:53:32 -07003854 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003855 PyErr_SetString(PyExc_OverflowError, "path too long");
3856 return NULL;
3857 }
3858
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003859 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003860 if (mountpath == NULL)
3861 return PyErr_NoMemory();
3862
3863 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003864 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003865 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003866 Py_END_ALLOW_THREADS
3867
3868 if (!ret) {
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003869 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003870 goto exit;
3871 }
3872 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003873 if (path->narrow)
3874 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003875
3876exit:
3877 PyMem_Free(mountpath);
3878 return result;
3879}
Tim Golden6b528062013-08-01 12:44:00 +01003880
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003881#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003882
Larry Hastings2f936352014-08-05 14:04:04 +10003883
3884/*[clinic input]
3885os.mkdir
3886
3887 path : path_t
3888
3889 mode: int = 0o777
3890
3891 *
3892
3893 dir_fd : dir_fd(requires='mkdirat') = None
3894
3895# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3896
3897Create a directory.
3898
3899If dir_fd is not None, it should be a file descriptor open to a directory,
3900 and path should be relative; path will then be relative to that directory.
3901dir_fd may not be implemented on your platform.
3902 If it is unavailable, using it will raise a NotImplementedError.
3903
3904The mode argument is ignored on Windows.
3905[clinic start generated code]*/
3906
Larry Hastings2f936352014-08-05 14:04:04 +10003907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003908os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3909/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003910{
3911 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003912
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003913#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003914 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003915 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003917
Larry Hastings2f936352014-08-05 14:04:04 +10003918 if (!result)
3919 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003920#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003921 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003922#if HAVE_MKDIRAT
3923 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003924 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003925 else
3926#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003927#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003928 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003929#else
Larry Hastings2f936352014-08-05 14:04:04 +10003930 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003931#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003932 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003933 if (result < 0)
3934 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003935#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003936 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003937}
3938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003939
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003940/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3941#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003942#include <sys/resource.h>
3943#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003944
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003945
3946#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003947/*[clinic input]
3948os.nice
3949
3950 increment: int
3951 /
3952
3953Add increment to the priority of process and return the new priority.
3954[clinic start generated code]*/
3955
Larry Hastings2f936352014-08-05 14:04:04 +10003956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003957os_nice_impl(PyObject *module, int increment)
3958/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003959{
3960 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003961
Victor Stinner8c62be82010-05-06 00:08:46 +00003962 /* There are two flavours of 'nice': one that returns the new
3963 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003964 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003966
Victor Stinner8c62be82010-05-06 00:08:46 +00003967 If we are of the nice family that returns the new priority, we
3968 need to clear errno before the call, and check if errno is filled
3969 before calling posix_error() on a returnvalue of -1, because the
3970 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003971
Victor Stinner8c62be82010-05-06 00:08:46 +00003972 errno = 0;
3973 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003974#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003975 if (value == 0)
3976 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003977#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003978 if (value == -1 && errno != 0)
3979 /* either nice() or getpriority() returned an error */
3980 return posix_error();
3981 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003982}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003983#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003984
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003985
3986#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003987/*[clinic input]
3988os.getpriority
3989
3990 which: int
3991 who: int
3992
3993Return program scheduling priority.
3994[clinic start generated code]*/
3995
Larry Hastings2f936352014-08-05 14:04:04 +10003996static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003997os_getpriority_impl(PyObject *module, int which, int who)
3998/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003999{
4000 int retval;
4001
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004002 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004003 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004004 if (errno != 0)
4005 return posix_error();
4006 return PyLong_FromLong((long)retval);
4007}
4008#endif /* HAVE_GETPRIORITY */
4009
4010
4011#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004012/*[clinic input]
4013os.setpriority
4014
4015 which: int
4016 who: int
4017 priority: int
4018
4019Set program scheduling priority.
4020[clinic start generated code]*/
4021
Larry Hastings2f936352014-08-05 14:04:04 +10004022static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004023os_setpriority_impl(PyObject *module, int which, int who, int priority)
4024/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004025{
4026 int retval;
4027
4028 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004029 if (retval == -1)
4030 return posix_error();
4031 Py_RETURN_NONE;
4032}
4033#endif /* HAVE_SETPRIORITY */
4034
4035
Barry Warsaw53699e91996-12-10 23:23:01 +00004036static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004037internal_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 +00004038{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004039 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004041
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004042#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004043 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004044 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004045#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004046 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004047#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004048
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4050 (dst_dir_fd != DEFAULT_DIR_FD);
4051#ifndef HAVE_RENAMEAT
4052 if (dir_fd_specified) {
4053 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004054 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055 }
4056#endif
4057
Larry Hastings9cf065c2012-06-22 16:30:09 -07004058#ifdef MS_WINDOWS
4059 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004060 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004061 Py_END_ALLOW_THREADS
4062
Larry Hastings2f936352014-08-05 14:04:04 +10004063 if (!result)
4064 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004065
4066#else
Steve Dowercc16be82016-09-08 10:35:16 -07004067 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4068 PyErr_Format(PyExc_ValueError,
4069 "%s: src and dst must be the same type", function_name);
4070 return NULL;
4071 }
4072
Larry Hastings9cf065c2012-06-22 16:30:09 -07004073 Py_BEGIN_ALLOW_THREADS
4074#ifdef HAVE_RENAMEAT
4075 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004076 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004077 else
4078#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004079 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004080 Py_END_ALLOW_THREADS
4081
Larry Hastings2f936352014-08-05 14:04:04 +10004082 if (result)
4083 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004084#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004085 Py_RETURN_NONE;
4086}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004087
Larry Hastings2f936352014-08-05 14:04:04 +10004088
4089/*[clinic input]
4090os.rename
4091
4092 src : path_t
4093 dst : path_t
4094 *
4095 src_dir_fd : dir_fd = None
4096 dst_dir_fd : dir_fd = None
4097
4098Rename a file or directory.
4099
4100If either src_dir_fd or dst_dir_fd is not None, it should be a file
4101 descriptor open to a directory, and the respective path string (src or dst)
4102 should be relative; the path will then be relative to that directory.
4103src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4104 If they are unavailable, using them will raise a NotImplementedError.
4105[clinic start generated code]*/
4106
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004107static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004108os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004109 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004110/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004111{
Larry Hastings2f936352014-08-05 14:04:04 +10004112 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004113}
4114
Larry Hastings2f936352014-08-05 14:04:04 +10004115
4116/*[clinic input]
4117os.replace = os.rename
4118
4119Rename a file or directory, overwriting the destination.
4120
4121If either src_dir_fd or dst_dir_fd is not None, it should be a file
4122 descriptor open to a directory, and the respective path string (src or dst)
4123 should be relative; the path will then be relative to that directory.
4124src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4125 If they are unavailable, using them will raise a NotImplementedError."
4126[clinic start generated code]*/
4127
Larry Hastings2f936352014-08-05 14:04:04 +10004128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004129os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4130 int dst_dir_fd)
4131/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004132{
4133 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4134}
4135
4136
4137/*[clinic input]
4138os.rmdir
4139
4140 path: path_t
4141 *
4142 dir_fd: dir_fd(requires='unlinkat') = None
4143
4144Remove a directory.
4145
4146If dir_fd is not None, it should be a file descriptor open to a directory,
4147 and path should be relative; path will then be relative to that directory.
4148dir_fd may not be implemented on your platform.
4149 If it is unavailable, using it will raise a NotImplementedError.
4150[clinic start generated code]*/
4151
Larry Hastings2f936352014-08-05 14:04:04 +10004152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004153os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4154/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004155{
4156 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004157
4158 Py_BEGIN_ALLOW_THREADS
4159#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004160 /* Windows, success=1, UNIX, success=0 */
4161 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004162#else
4163#ifdef HAVE_UNLINKAT
4164 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004165 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004166 else
4167#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004168 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004169#endif
4170 Py_END_ALLOW_THREADS
4171
Larry Hastings2f936352014-08-05 14:04:04 +10004172 if (result)
4173 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004174
Larry Hastings2f936352014-08-05 14:04:04 +10004175 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004176}
4177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004178
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004179#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004180#ifdef MS_WINDOWS
4181/*[clinic input]
4182os.system -> long
4183
4184 command: Py_UNICODE
4185
4186Execute the command in a subshell.
4187[clinic start generated code]*/
4188
Larry Hastings2f936352014-08-05 14:04:04 +10004189static long
Serhiy Storchaka45a7b762018-12-14 11:56:48 +02004190os_system_impl(PyObject *module, const Py_UNICODE *command)
4191/*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004192{
4193 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004195 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004196 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004197 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004198 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004199 return result;
4200}
4201#else /* MS_WINDOWS */
4202/*[clinic input]
4203os.system -> long
4204
4205 command: FSConverter
4206
4207Execute the command in a subshell.
4208[clinic start generated code]*/
4209
Larry Hastings2f936352014-08-05 14:04:04 +10004210static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004211os_system_impl(PyObject *module, PyObject *command)
4212/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004213{
4214 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004215 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004216 Py_BEGIN_ALLOW_THREADS
4217 result = system(bytes);
4218 Py_END_ALLOW_THREADS
4219 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004220}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004221#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004222#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004224
Larry Hastings2f936352014-08-05 14:04:04 +10004225/*[clinic input]
4226os.umask
4227
4228 mask: int
4229 /
4230
4231Set the current numeric umask and return the previous umask.
4232[clinic start generated code]*/
4233
Larry Hastings2f936352014-08-05 14:04:04 +10004234static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004235os_umask_impl(PyObject *module, int mask)
4236/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004237{
4238 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 if (i < 0)
4240 return posix_error();
4241 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004242}
4243
Brian Curtind40e6f72010-07-08 21:39:08 +00004244#ifdef MS_WINDOWS
4245
4246/* override the default DeleteFileW behavior so that directory
4247symlinks can be removed with this function, the same as with
4248Unix symlinks */
4249BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4250{
4251 WIN32_FILE_ATTRIBUTE_DATA info;
4252 WIN32_FIND_DATAW find_data;
4253 HANDLE find_data_handle;
4254 int is_directory = 0;
4255 int is_link = 0;
4256
4257 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4258 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004259
Brian Curtind40e6f72010-07-08 21:39:08 +00004260 /* Get WIN32_FIND_DATA structure for the path to determine if
4261 it is a symlink */
4262 if(is_directory &&
4263 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4264 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4265
4266 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004267 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4268 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4269 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4270 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004271 FindClose(find_data_handle);
4272 }
4273 }
4274 }
4275
4276 if (is_directory && is_link)
4277 return RemoveDirectoryW(lpFileName);
4278
4279 return DeleteFileW(lpFileName);
4280}
4281#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Larry Hastings2f936352014-08-05 14:04:04 +10004284/*[clinic input]
4285os.unlink
4286
4287 path: path_t
4288 *
4289 dir_fd: dir_fd(requires='unlinkat')=None
4290
4291Remove a file (same as remove()).
4292
4293If dir_fd is not None, it should be a file descriptor open to a directory,
4294 and path should be relative; path will then be relative to that directory.
4295dir_fd may not be implemented on your platform.
4296 If it is unavailable, using it will raise a NotImplementedError.
4297
4298[clinic start generated code]*/
4299
Larry Hastings2f936352014-08-05 14:04:04 +10004300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004301os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4302/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004303{
4304 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305
4306 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004307 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004308#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004309 /* Windows, success=1, UNIX, success=0 */
4310 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004311#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#ifdef HAVE_UNLINKAT
4313 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004314 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315 else
4316#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004317 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004319 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004320 Py_END_ALLOW_THREADS
4321
Larry Hastings2f936352014-08-05 14:04:04 +10004322 if (result)
4323 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004324
Larry Hastings2f936352014-08-05 14:04:04 +10004325 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004326}
4327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
Larry Hastings2f936352014-08-05 14:04:04 +10004329/*[clinic input]
4330os.remove = os.unlink
4331
4332Remove a file (same as unlink()).
4333
4334If dir_fd is not None, it should be a file descriptor open to a directory,
4335 and path should be relative; path will then be relative to that directory.
4336dir_fd may not be implemented on your platform.
4337 If it is unavailable, using it will raise a NotImplementedError.
4338[clinic start generated code]*/
4339
Larry Hastings2f936352014-08-05 14:04:04 +10004340static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004341os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4342/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004343{
4344 return os_unlink_impl(module, path, dir_fd);
4345}
4346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004347
Larry Hastings605a62d2012-06-24 04:33:36 -07004348static PyStructSequence_Field uname_result_fields[] = {
4349 {"sysname", "operating system name"},
4350 {"nodename", "name of machine on network (implementation-defined)"},
4351 {"release", "operating system release"},
4352 {"version", "operating system version"},
4353 {"machine", "hardware identifier"},
4354 {NULL}
4355};
4356
4357PyDoc_STRVAR(uname_result__doc__,
4358"uname_result: Result from os.uname().\n\n\
4359This object may be accessed either as a tuple of\n\
4360 (sysname, nodename, release, version, machine),\n\
4361or via the attributes sysname, nodename, release, version, and machine.\n\
4362\n\
4363See os.uname for more information.");
4364
4365static PyStructSequence_Desc uname_result_desc = {
4366 "uname_result", /* name */
4367 uname_result__doc__, /* doc */
4368 uname_result_fields,
4369 5
4370};
4371
4372static PyTypeObject UnameResultType;
4373
4374
4375#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004376/*[clinic input]
4377os.uname
4378
4379Return an object identifying the current operating system.
4380
4381The object behaves like a named tuple with the following fields:
4382 (sysname, nodename, release, version, machine)
4383
4384[clinic start generated code]*/
4385
Larry Hastings2f936352014-08-05 14:04:04 +10004386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004387os_uname_impl(PyObject *module)
4388/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004389{
Victor Stinner8c62be82010-05-06 00:08:46 +00004390 struct utsname u;
4391 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004392 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004393
Victor Stinner8c62be82010-05-06 00:08:46 +00004394 Py_BEGIN_ALLOW_THREADS
4395 res = uname(&u);
4396 Py_END_ALLOW_THREADS
4397 if (res < 0)
4398 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004399
4400 value = PyStructSequence_New(&UnameResultType);
4401 if (value == NULL)
4402 return NULL;
4403
4404#define SET(i, field) \
4405 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004406 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004407 if (!o) { \
4408 Py_DECREF(value); \
4409 return NULL; \
4410 } \
4411 PyStructSequence_SET_ITEM(value, i, o); \
4412 } \
4413
4414 SET(0, u.sysname);
4415 SET(1, u.nodename);
4416 SET(2, u.release);
4417 SET(3, u.version);
4418 SET(4, u.machine);
4419
4420#undef SET
4421
4422 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004423}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004424#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004425
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004426
Larry Hastings9cf065c2012-06-22 16:30:09 -07004427
4428typedef struct {
4429 int now;
4430 time_t atime_s;
4431 long atime_ns;
4432 time_t mtime_s;
4433 long mtime_ns;
4434} utime_t;
4435
4436/*
Victor Stinner484df002014-10-09 13:52:31 +02004437 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438 * they also intentionally leak the declaration of a pointer named "time"
4439 */
4440#define UTIME_TO_TIMESPEC \
4441 struct timespec ts[2]; \
4442 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004443 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 time = NULL; \
4445 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004446 ts[0].tv_sec = ut->atime_s; \
4447 ts[0].tv_nsec = ut->atime_ns; \
4448 ts[1].tv_sec = ut->mtime_s; \
4449 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450 time = ts; \
4451 } \
4452
4453#define UTIME_TO_TIMEVAL \
4454 struct timeval tv[2]; \
4455 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004456 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457 time = NULL; \
4458 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004459 tv[0].tv_sec = ut->atime_s; \
4460 tv[0].tv_usec = ut->atime_ns / 1000; \
4461 tv[1].tv_sec = ut->mtime_s; \
4462 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463 time = tv; \
4464 } \
4465
4466#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004467 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004469 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004470 time = NULL; \
4471 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004472 u.actime = ut->atime_s; \
4473 u.modtime = ut->mtime_s; \
4474 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475 }
4476
4477#define UTIME_TO_TIME_T \
4478 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004479 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004480 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004481 time = NULL; \
4482 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004483 timet[0] = ut->atime_s; \
4484 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004485 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486 } \
4487
4488
Victor Stinner528a9ab2015-09-03 21:30:26 +02004489#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004490
4491static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004492utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004493{
4494#ifdef HAVE_UTIMENSAT
4495 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4496 UTIME_TO_TIMESPEC;
4497 return utimensat(dir_fd, path, time, flags);
4498#elif defined(HAVE_FUTIMESAT)
4499 UTIME_TO_TIMEVAL;
4500 /*
4501 * follow_symlinks will never be false here;
4502 * we only allow !follow_symlinks and dir_fd together
4503 * if we have utimensat()
4504 */
4505 assert(follow_symlinks);
4506 return futimesat(dir_fd, path, time);
4507#endif
4508}
4509
Larry Hastings2f936352014-08-05 14:04:04 +10004510 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4511#else
4512 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513#endif
4514
Victor Stinner528a9ab2015-09-03 21:30:26 +02004515#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516
4517static int
Victor Stinner484df002014-10-09 13:52:31 +02004518utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519{
4520#ifdef HAVE_FUTIMENS
4521 UTIME_TO_TIMESPEC;
4522 return futimens(fd, time);
4523#else
4524 UTIME_TO_TIMEVAL;
4525 return futimes(fd, time);
4526#endif
4527}
4528
Larry Hastings2f936352014-08-05 14:04:04 +10004529 #define PATH_UTIME_HAVE_FD 1
4530#else
4531 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532#endif
4533
Victor Stinner5ebae872015-09-22 01:29:33 +02004534#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4535# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4536#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004537
Victor Stinner4552ced2015-09-21 22:37:15 +02004538#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539
4540static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004541utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542{
4543#ifdef HAVE_UTIMENSAT
4544 UTIME_TO_TIMESPEC;
4545 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4546#else
4547 UTIME_TO_TIMEVAL;
4548 return lutimes(path, time);
4549#endif
4550}
4551
4552#endif
4553
4554#ifndef MS_WINDOWS
4555
4556static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004557utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558{
4559#ifdef HAVE_UTIMENSAT
4560 UTIME_TO_TIMESPEC;
4561 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4562#elif defined(HAVE_UTIMES)
4563 UTIME_TO_TIMEVAL;
4564 return utimes(path, time);
4565#elif defined(HAVE_UTIME_H)
4566 UTIME_TO_UTIMBUF;
4567 return utime(path, time);
4568#else
4569 UTIME_TO_TIME_T;
4570 return utime(path, time);
4571#endif
4572}
4573
4574#endif
4575
Larry Hastings76ad59b2012-05-03 00:30:07 -07004576static int
4577split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4578{
4579 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004580 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004581 divmod = PyNumber_Divmod(py_long, billion);
4582 if (!divmod)
4583 goto exit;
Miss Islington (bot)329ea4e2018-09-12 12:46:30 -07004584 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4585 PyErr_Format(PyExc_TypeError,
4586 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4587 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4588 goto exit;
4589 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4591 if ((*s == -1) && PyErr_Occurred())
4592 goto exit;
4593 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004594 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004595 goto exit;
4596
4597 result = 1;
4598exit:
4599 Py_XDECREF(divmod);
4600 return result;
4601}
4602
Larry Hastings2f936352014-08-05 14:04:04 +10004603
4604/*[clinic input]
4605os.utime
4606
4607 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4608 times: object = NULL
4609 *
4610 ns: object = NULL
4611 dir_fd: dir_fd(requires='futimensat') = None
4612 follow_symlinks: bool=True
4613
Martin Panter0ff89092015-09-09 01:56:53 +00004614# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004615
4616Set the access and modified time of path.
4617
4618path may always be specified as a string.
4619On some platforms, path may also be specified as an open file descriptor.
4620 If this functionality is unavailable, using it raises an exception.
4621
4622If times is not None, it must be a tuple (atime, mtime);
4623 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004624If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004625 atime_ns and mtime_ns should be expressed as integer nanoseconds
4626 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004627If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004628Specifying tuples for both times and ns is an error.
4629
4630If dir_fd is not None, it should be a file descriptor open to a directory,
4631 and path should be relative; path will then be relative to that directory.
4632If follow_symlinks is False, and the last element of the path is a symbolic
4633 link, utime will modify the symbolic link itself instead of the file the
4634 link points to.
4635It is an error to use dir_fd or follow_symlinks when specifying path
4636 as an open file descriptor.
4637dir_fd and follow_symlinks may not be available on your platform.
4638 If they are unavailable, using them will raise a NotImplementedError.
4639
4640[clinic start generated code]*/
4641
Larry Hastings2f936352014-08-05 14:04:04 +10004642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004643os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4644 int dir_fd, int follow_symlinks)
4645/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004646{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647#ifdef MS_WINDOWS
4648 HANDLE hFile;
4649 FILETIME atime, mtime;
4650#else
4651 int result;
4652#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653
Larry Hastings2f936352014-08-05 14:04:04 +10004654 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004655
Christian Heimesb3c87242013-08-01 00:08:16 +02004656 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004657
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658 if (times && (times != Py_None) && ns) {
4659 PyErr_SetString(PyExc_ValueError,
4660 "utime: you may specify either 'times'"
4661 " or 'ns' but not both");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004662 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004663 }
4664
4665 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004666 time_t a_sec, m_sec;
4667 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 PyErr_SetString(PyExc_TypeError,
4670 "utime: 'times' must be either"
4671 " a tuple of two ints or None");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004672 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004673 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004675 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004676 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004677 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004678 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004679 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004680 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004681 utime.atime_s = a_sec;
4682 utime.atime_ns = a_nsec;
4683 utime.mtime_s = m_sec;
4684 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004685 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004687 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 PyErr_SetString(PyExc_TypeError,
4689 "utime: 'ns' must be a tuple of two ints");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004690 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004691 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004693 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004695 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004696 &utime.mtime_s, &utime.mtime_ns)) {
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004697 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004698 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699 }
4700 else {
4701 /* times and ns are both None/unspecified. use "now". */
4702 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004703 }
4704
Victor Stinner4552ced2015-09-21 22:37:15 +02004705#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 if (follow_symlinks_specified("utime", follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004707 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004709
Larry Hastings2f936352014-08-05 14:04:04 +10004710 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4711 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4712 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004713 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004714
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715#if !defined(HAVE_UTIMENSAT)
4716 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004717 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 "utime: cannot use dir_fd and follow_symlinks "
4719 "together on this platform");
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004720 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721 }
4722#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004723
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004724#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004726 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4727 NULL, OPEN_EXISTING,
4728 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 Py_END_ALLOW_THREADS
4730 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004731 path_error(path);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004732 return NULL;
Larry Hastingsb3336402012-05-04 02:31:57 -07004733 }
4734
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004736 GetSystemTimeAsFileTime(&mtime);
4737 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004739 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004740 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4741 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004742 }
4743 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4744 /* Avoid putting the file name into the error here,
4745 as that may confuse the user into believing that
4746 something is wrong with the file, when it also
4747 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004748 PyErr_SetFromWindowsErr(0);
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004749 CloseHandle(hFile);
4750 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004751 }
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004752 CloseHandle(hFile);
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004753#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004755
Victor Stinner4552ced2015-09-21 22:37:15 +02004756#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004758 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004760#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761
Victor Stinner528a9ab2015-09-03 21:30:26 +02004762#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004764 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 else
4766#endif
4767
Victor Stinner528a9ab2015-09-03 21:30:26 +02004768#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004769 if (path->fd != -1)
4770 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771 else
4772#endif
4773
Larry Hastings2f936352014-08-05 14:04:04 +10004774 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775
4776 Py_END_ALLOW_THREADS
4777
4778 if (result < 0) {
4779 /* see previous comment about not putting filename in error here */
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004780 posix_error();
4781 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004783
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004784#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785
Miss Islington (bot)265b4192018-12-01 04:52:04 -08004786 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004787}
4788
Guido van Rossum3b066191991-06-04 19:40:25 +00004789/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004790
Larry Hastings2f936352014-08-05 14:04:04 +10004791
4792/*[clinic input]
4793os._exit
4794
4795 status: int
4796
4797Exit to the system with specified status, without normal exit processing.
4798[clinic start generated code]*/
4799
Larry Hastings2f936352014-08-05 14:04:04 +10004800static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004801os__exit_impl(PyObject *module, int status)
4802/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004803{
4804 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004806}
4807
Steve Dowercc16be82016-09-08 10:35:16 -07004808#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4809#define EXECV_CHAR wchar_t
4810#else
4811#define EXECV_CHAR char
4812#endif
4813
Martin v. Löwis114619e2002-10-07 06:44:21 +00004814#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4815static void
Steve Dowercc16be82016-09-08 10:35:16 -07004816free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004817{
Victor Stinner8c62be82010-05-06 00:08:46 +00004818 Py_ssize_t i;
4819 for (i = 0; i < count; i++)
4820 PyMem_Free(array[i]);
4821 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004822}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004823
Berker Peksag81816462016-09-15 20:19:47 +03004824static int
4825fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004826{
Victor Stinner8c62be82010-05-06 00:08:46 +00004827 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004828 PyObject *ub;
4829 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004830#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004831 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004832 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004833 *out = PyUnicode_AsWideCharString(ub, &size);
4834 if (*out)
4835 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004836#else
Berker Peksag81816462016-09-15 20:19:47 +03004837 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004839 size = PyBytes_GET_SIZE(ub);
4840 *out = PyMem_Malloc(size + 1);
4841 if (*out) {
4842 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4843 result = 1;
4844 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004845 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004846#endif
Berker Peksag81816462016-09-15 20:19:47 +03004847 Py_DECREF(ub);
4848 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004849}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004850#endif
4851
Ross Lagerwall7807c352011-03-17 20:20:30 +02004852#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004853static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004854parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4855{
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 Py_ssize_t i, pos, envc;
4857 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004858 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004859 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004860
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 i = PyMapping_Size(env);
4862 if (i < 0)
4863 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004864 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 if (envlist == NULL) {
4866 PyErr_NoMemory();
4867 return NULL;
4868 }
4869 envc = 0;
4870 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004871 if (!keys)
4872 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004874 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 goto error;
4876 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4877 PyErr_Format(PyExc_TypeError,
4878 "env.keys() or env.values() is not a list");
4879 goto error;
4880 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004881
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 for (pos = 0; pos < i; pos++) {
4883 key = PyList_GetItem(keys, pos);
4884 val = PyList_GetItem(vals, pos);
4885 if (!key || !val)
4886 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004887
Berker Peksag81816462016-09-15 20:19:47 +03004888#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4889 if (!PyUnicode_FSDecoder(key, &key2))
4890 goto error;
4891 if (!PyUnicode_FSDecoder(val, &val2)) {
4892 Py_DECREF(key2);
4893 goto error;
4894 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004895 /* Search from index 1 because on Windows starting '=' is allowed for
4896 defining hidden environment variables. */
4897 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4898 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4899 {
4900 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004901 Py_DECREF(key2);
4902 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004903 goto error;
4904 }
Berker Peksag81816462016-09-15 20:19:47 +03004905 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4906#else
4907 if (!PyUnicode_FSConverter(key, &key2))
4908 goto error;
4909 if (!PyUnicode_FSConverter(val, &val2)) {
4910 Py_DECREF(key2);
4911 goto error;
4912 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004913 if (PyBytes_GET_SIZE(key2) == 0 ||
4914 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4915 {
4916 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004917 Py_DECREF(key2);
4918 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004919 goto error;
4920 }
Berker Peksag81816462016-09-15 20:19:47 +03004921 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4922 PyBytes_AS_STRING(val2));
4923#endif
4924 Py_DECREF(key2);
4925 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004926 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004928
4929 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4930 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004931 goto error;
4932 }
Berker Peksag81816462016-09-15 20:19:47 +03004933
Steve Dowercc16be82016-09-08 10:35:16 -07004934 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004935 }
4936 Py_DECREF(vals);
4937 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004938
Victor Stinner8c62be82010-05-06 00:08:46 +00004939 envlist[envc] = 0;
4940 *envc_ptr = envc;
4941 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004942
4943error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 Py_XDECREF(keys);
4945 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004946 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004948}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004949
Steve Dowercc16be82016-09-08 10:35:16 -07004950static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004951parse_arglist(PyObject* argv, Py_ssize_t *argc)
4952{
4953 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004954 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004955 if (argvlist == NULL) {
4956 PyErr_NoMemory();
4957 return NULL;
4958 }
4959 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004960 PyObject* item = PySequence_ITEM(argv, i);
4961 if (item == NULL)
4962 goto fail;
4963 if (!fsconvert_strdup(item, &argvlist[i])) {
4964 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004965 goto fail;
4966 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004967 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004968 }
4969 argvlist[*argc] = NULL;
4970 return argvlist;
4971fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004972 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004973 free_string_array(argvlist, *argc);
4974 return NULL;
4975}
Steve Dowercc16be82016-09-08 10:35:16 -07004976
Ross Lagerwall7807c352011-03-17 20:20:30 +02004977#endif
4978
Larry Hastings2f936352014-08-05 14:04:04 +10004979
Ross Lagerwall7807c352011-03-17 20:20:30 +02004980#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004981/*[clinic input]
4982os.execv
4983
Steve Dowercc16be82016-09-08 10:35:16 -07004984 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004985 Path of executable file.
4986 argv: object
4987 Tuple or list of strings.
4988 /
4989
4990Execute an executable path with arguments, replacing current process.
4991[clinic start generated code]*/
4992
Larry Hastings2f936352014-08-05 14:04:04 +10004993static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004994os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4995/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004996{
Steve Dowercc16be82016-09-08 10:35:16 -07004997 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004998 Py_ssize_t argc;
4999
5000 /* execv has two arguments: (path, argv), where
5001 argv is a list or tuple of strings. */
5002
Ross Lagerwall7807c352011-03-17 20:20:30 +02005003 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5004 PyErr_SetString(PyExc_TypeError,
5005 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005006 return NULL;
5007 }
5008 argc = PySequence_Size(argv);
5009 if (argc < 1) {
5010 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005011 return NULL;
5012 }
5013
5014 argvlist = parse_arglist(argv, &argc);
5015 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 return NULL;
5017 }
Steve Dowerbce26262016-11-19 19:17:26 -08005018 if (!argvlist[0][0]) {
5019 PyErr_SetString(PyExc_ValueError,
5020 "execv() arg 2 first element cannot be empty");
5021 free_string_array(argvlist, argc);
5022 return NULL;
5023 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005024
Steve Dowerbce26262016-11-19 19:17:26 -08005025 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005026#ifdef HAVE_WEXECV
5027 _wexecv(path->wide, argvlist);
5028#else
5029 execv(path->narrow, argvlist);
5030#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005031 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005032
5033 /* If we get here it's definitely an error */
5034
5035 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005036 return posix_error();
5037}
5038
Larry Hastings2f936352014-08-05 14:04:04 +10005039
5040/*[clinic input]
5041os.execve
5042
5043 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5044 Path of executable file.
5045 argv: object
5046 Tuple or list of strings.
5047 env: object
5048 Dictionary of strings mapping to strings.
5049
5050Execute an executable path with arguments, replacing current process.
5051[clinic start generated code]*/
5052
Larry Hastings2f936352014-08-05 14:04:04 +10005053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005054os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5055/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005056{
Steve Dowercc16be82016-09-08 10:35:16 -07005057 EXECV_CHAR **argvlist = NULL;
5058 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005060
Victor Stinner8c62be82010-05-06 00:08:46 +00005061 /* execve has three arguments: (path, argv, env), where
5062 argv is a list or tuple of strings and env is a dictionary
5063 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005064
Ross Lagerwall7807c352011-03-17 20:20:30 +02005065 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005067 "execve: argv must be a tuple or list");
5068 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005071 if (argc < 1) {
5072 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5073 return NULL;
5074 }
5075
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 if (!PyMapping_Check(env)) {
5077 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005078 "execve: environment must be a mapping object");
5079 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005081
Ross Lagerwall7807c352011-03-17 20:20:30 +02005082 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005084 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 }
Steve Dowerbce26262016-11-19 19:17:26 -08005086 if (!argvlist[0][0]) {
5087 PyErr_SetString(PyExc_ValueError,
5088 "execve: argv first element cannot be empty");
5089 goto fail;
5090 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005091
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 envlist = parse_envlist(env, &envc);
5093 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005094 goto fail;
5095
Steve Dowerbce26262016-11-19 19:17:26 -08005096 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005097#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005098 if (path->fd > -1)
5099 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005100 else
5101#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005102#ifdef HAVE_WEXECV
5103 _wexecve(path->wide, argvlist, envlist);
5104#else
Larry Hastings2f936352014-08-05 14:04:04 +10005105 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005106#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005107 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108
5109 /* If we get here it's definitely an error */
5110
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07005111 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005112
Steve Dowercc16be82016-09-08 10:35:16 -07005113 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005114 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005115 if (argvlist)
5116 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005117 return NULL;
5118}
Steve Dowercc16be82016-09-08 10:35:16 -07005119
Larry Hastings9cf065c2012-06-22 16:30:09 -07005120#endif /* HAVE_EXECV */
5121
Steve Dowercc16be82016-09-08 10:35:16 -07005122#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005123/*[clinic input]
5124os.spawnv
5125
5126 mode: int
5127 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005128 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005129 Path of executable file.
5130 argv: object
5131 Tuple or list of strings.
5132 /
5133
5134Execute the program specified by path in a new process.
5135[clinic start generated code]*/
5136
Larry Hastings2f936352014-08-05 14:04:04 +10005137static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005138os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5139/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005140{
Steve Dowercc16be82016-09-08 10:35:16 -07005141 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005142 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005144 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005146
Victor Stinner8c62be82010-05-06 00:08:46 +00005147 /* spawnv has three arguments: (mode, path, argv), where
5148 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005149
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 if (PyList_Check(argv)) {
5151 argc = PyList_Size(argv);
5152 getitem = PyList_GetItem;
5153 }
5154 else if (PyTuple_Check(argv)) {
5155 argc = PyTuple_Size(argv);
5156 getitem = PyTuple_GetItem;
5157 }
5158 else {
5159 PyErr_SetString(PyExc_TypeError,
5160 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 return NULL;
5162 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005163 if (argc == 0) {
5164 PyErr_SetString(PyExc_ValueError,
5165 "spawnv() arg 2 cannot be empty");
5166 return NULL;
5167 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005168
Steve Dowercc16be82016-09-08 10:35:16 -07005169 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 return PyErr_NoMemory();
5172 }
5173 for (i = 0; i < argc; i++) {
5174 if (!fsconvert_strdup((*getitem)(argv, i),
5175 &argvlist[i])) {
5176 free_string_array(argvlist, i);
5177 PyErr_SetString(
5178 PyExc_TypeError,
5179 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005180 return NULL;
5181 }
Steve Dower93ff8722016-11-19 19:03:54 -08005182 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005183 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005184 PyErr_SetString(
5185 PyExc_ValueError,
5186 "spawnv() arg 2 first element cannot be empty");
5187 return NULL;
5188 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 }
5190 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005191
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 if (mode == _OLD_P_OVERLAY)
5193 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005194
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005196 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005197#ifdef HAVE_WSPAWNV
5198 spawnval = _wspawnv(mode, path->wide, argvlist);
5199#else
5200 spawnval = _spawnv(mode, path->narrow, argvlist);
5201#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005202 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005206
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 if (spawnval == -1)
5208 return posix_error();
5209 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005210 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005211}
5212
Larry Hastings2f936352014-08-05 14:04:04 +10005213/*[clinic input]
5214os.spawnve
5215
5216 mode: int
5217 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005218 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005219 Path of executable file.
5220 argv: object
5221 Tuple or list of strings.
5222 env: object
5223 Dictionary of strings mapping to strings.
5224 /
5225
5226Execute the program specified by path in a new process.
5227[clinic start generated code]*/
5228
Larry Hastings2f936352014-08-05 14:04:04 +10005229static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005230os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005231 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005232/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005233{
Steve Dowercc16be82016-09-08 10:35:16 -07005234 EXECV_CHAR **argvlist;
5235 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005237 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005238 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005239 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005240 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005241
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 /* spawnve has four arguments: (mode, path, argv, env), where
5243 argv is a list or tuple of strings and env is a dictionary
5244 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005245
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 if (PyList_Check(argv)) {
5247 argc = PyList_Size(argv);
5248 getitem = PyList_GetItem;
5249 }
5250 else if (PyTuple_Check(argv)) {
5251 argc = PyTuple_Size(argv);
5252 getitem = PyTuple_GetItem;
5253 }
5254 else {
5255 PyErr_SetString(PyExc_TypeError,
5256 "spawnve() arg 2 must be a tuple or list");
5257 goto fail_0;
5258 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005259 if (argc == 0) {
5260 PyErr_SetString(PyExc_ValueError,
5261 "spawnve() arg 2 cannot be empty");
5262 goto fail_0;
5263 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005264 if (!PyMapping_Check(env)) {
5265 PyErr_SetString(PyExc_TypeError,
5266 "spawnve() arg 3 must be a mapping object");
5267 goto fail_0;
5268 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005269
Steve Dowercc16be82016-09-08 10:35:16 -07005270 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005271 if (argvlist == NULL) {
5272 PyErr_NoMemory();
5273 goto fail_0;
5274 }
5275 for (i = 0; i < argc; i++) {
5276 if (!fsconvert_strdup((*getitem)(argv, i),
5277 &argvlist[i]))
5278 {
5279 lastarg = i;
5280 goto fail_1;
5281 }
Steve Dowerbce26262016-11-19 19:17:26 -08005282 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005283 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005284 PyErr_SetString(
5285 PyExc_ValueError,
5286 "spawnv() arg 2 first element cannot be empty");
5287 goto fail_1;
5288 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 }
5290 lastarg = argc;
5291 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005292
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 envlist = parse_envlist(env, &envc);
5294 if (envlist == NULL)
5295 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005296
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 if (mode == _OLD_P_OVERLAY)
5298 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005299
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005301 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005302#ifdef HAVE_WSPAWNV
5303 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5304#else
5305 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5306#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005307 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005309
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 if (spawnval == -1)
5311 (void) posix_error();
5312 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005313 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005314
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 while (--envc >= 0)
5316 PyMem_DEL(envlist[envc]);
5317 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005318 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005319 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005320 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005321 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005322}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005323
Guido van Rossuma1065681999-01-25 23:20:23 +00005324#endif /* HAVE_SPAWNV */
5325
5326
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005327#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005328
5329/* Helper function to validate arguments.
5330 Returns 0 on success. non-zero on failure with a TypeError raised.
5331 If obj is non-NULL it must be callable. */
5332static int
5333check_null_or_callable(PyObject *obj, const char* obj_name)
5334{
5335 if (obj && !PyCallable_Check(obj)) {
5336 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5337 obj_name, Py_TYPE(obj)->tp_name);
5338 return -1;
5339 }
5340 return 0;
5341}
5342
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005343/*[clinic input]
5344os.register_at_fork
5345
Gregory P. Smith163468a2017-05-29 10:03:41 -07005346 *
5347 before: object=NULL
5348 A callable to be called in the parent before the fork() syscall.
5349 after_in_child: object=NULL
5350 A callable to be called in the child after fork().
5351 after_in_parent: object=NULL
5352 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005353
Gregory P. Smith163468a2017-05-29 10:03:41 -07005354Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005355
Gregory P. Smith163468a2017-05-29 10:03:41 -07005356'before' callbacks are called in reverse order.
5357'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005358
5359[clinic start generated code]*/
5360
5361static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005362os_register_at_fork_impl(PyObject *module, PyObject *before,
5363 PyObject *after_in_child, PyObject *after_in_parent)
5364/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005365{
5366 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005367
Gregory P. Smith163468a2017-05-29 10:03:41 -07005368 if (!before && !after_in_child && !after_in_parent) {
5369 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5370 return NULL;
5371 }
5372 if (check_null_or_callable(before, "before") ||
5373 check_null_or_callable(after_in_child, "after_in_child") ||
5374 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005375 return NULL;
5376 }
5377 interp = PyThreadState_Get()->interp;
5378
Gregory P. Smith163468a2017-05-29 10:03:41 -07005379 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005380 return NULL;
5381 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005382 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005383 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005384 }
5385 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5386 return NULL;
5387 }
5388 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005389}
5390#endif /* HAVE_FORK */
5391
5392
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005393#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005394/*[clinic input]
5395os.fork1
5396
5397Fork a child process with a single multiplexed (i.e., not bound) thread.
5398
5399Return 0 to child process and PID of child to parent process.
5400[clinic start generated code]*/
5401
Larry Hastings2f936352014-08-05 14:04:04 +10005402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005403os_fork1_impl(PyObject *module)
5404/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005405{
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005407
5408 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005409 pid = fork1();
5410 if (pid == 0) {
5411 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005412 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 } else {
5414 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005415 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 }
5417 if (pid == -1)
5418 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005420}
Larry Hastings2f936352014-08-05 14:04:04 +10005421#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005422
5423
Guido van Rossumad0ee831995-03-01 10:34:45 +00005424#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005425/*[clinic input]
5426os.fork
5427
5428Fork a child process.
5429
5430Return 0 to child process and PID of child to parent process.
5431[clinic start generated code]*/
5432
Larry Hastings2f936352014-08-05 14:04:04 +10005433static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005434os_fork_impl(PyObject *module)
5435/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005436{
Victor Stinner8c62be82010-05-06 00:08:46 +00005437 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005438
5439 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005440 pid = fork();
5441 if (pid == 0) {
5442 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005443 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 } else {
5445 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005446 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005447 }
5448 if (pid == -1)
5449 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005451}
Larry Hastings2f936352014-08-05 14:04:04 +10005452#endif /* HAVE_FORK */
5453
Guido van Rossum85e3b011991-06-03 12:42:10 +00005454
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005455#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005456#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005457/*[clinic input]
5458os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005459
Larry Hastings2f936352014-08-05 14:04:04 +10005460 policy: int
5461
5462Get the maximum scheduling priority for policy.
5463[clinic start generated code]*/
5464
Larry Hastings2f936352014-08-05 14:04:04 +10005465static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005466os_sched_get_priority_max_impl(PyObject *module, int policy)
5467/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005468{
5469 int max;
5470
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005471 max = sched_get_priority_max(policy);
5472 if (max < 0)
5473 return posix_error();
5474 return PyLong_FromLong(max);
5475}
5476
Larry Hastings2f936352014-08-05 14:04:04 +10005477
5478/*[clinic input]
5479os.sched_get_priority_min
5480
5481 policy: int
5482
5483Get the minimum scheduling priority for policy.
5484[clinic start generated code]*/
5485
Larry Hastings2f936352014-08-05 14:04:04 +10005486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005487os_sched_get_priority_min_impl(PyObject *module, int policy)
5488/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005489{
5490 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005491 if (min < 0)
5492 return posix_error();
5493 return PyLong_FromLong(min);
5494}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005495#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5496
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005497
Larry Hastings2f936352014-08-05 14:04:04 +10005498#ifdef HAVE_SCHED_SETSCHEDULER
5499/*[clinic input]
5500os.sched_getscheduler
5501 pid: pid_t
5502 /
5503
5504Get the scheduling policy for the process identifiedy by pid.
5505
5506Passing 0 for pid returns the scheduling policy for the calling process.
5507[clinic start generated code]*/
5508
Larry Hastings2f936352014-08-05 14:04:04 +10005509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005510os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5511/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005512{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005513 int policy;
5514
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005515 policy = sched_getscheduler(pid);
5516 if (policy < 0)
5517 return posix_error();
5518 return PyLong_FromLong(policy);
5519}
Larry Hastings2f936352014-08-05 14:04:04 +10005520#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005521
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005522
5523#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005524/*[clinic input]
5525class os.sched_param "PyObject *" "&SchedParamType"
5526
5527@classmethod
5528os.sched_param.__new__
5529
5530 sched_priority: object
5531 A scheduling parameter.
5532
5533Current has only one field: sched_priority");
5534[clinic start generated code]*/
5535
Larry Hastings2f936352014-08-05 14:04:04 +10005536static PyObject *
5537os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005538/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005539{
5540 PyObject *res;
5541
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005542 res = PyStructSequence_New(type);
5543 if (!res)
5544 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005545 Py_INCREF(sched_priority);
5546 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547 return res;
5548}
5549
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005550
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005551PyDoc_VAR(os_sched_param__doc__);
5552
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005553static PyStructSequence_Field sched_param_fields[] = {
5554 {"sched_priority", "the scheduling priority"},
5555 {0}
5556};
5557
5558static PyStructSequence_Desc sched_param_desc = {
5559 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005560 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005561 sched_param_fields,
5562 1
5563};
5564
5565static int
5566convert_sched_param(PyObject *param, struct sched_param *res)
5567{
5568 long priority;
5569
5570 if (Py_TYPE(param) != &SchedParamType) {
5571 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5572 return 0;
5573 }
5574 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5575 if (priority == -1 && PyErr_Occurred())
5576 return 0;
5577 if (priority > INT_MAX || priority < INT_MIN) {
5578 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5579 return 0;
5580 }
5581 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5582 return 1;
5583}
Larry Hastings2f936352014-08-05 14:04:04 +10005584#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005585
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005586
5587#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005588/*[clinic input]
5589os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005590
Larry Hastings2f936352014-08-05 14:04:04 +10005591 pid: pid_t
5592 policy: int
5593 param: sched_param
5594 /
5595
5596Set the scheduling policy for the process identified by pid.
5597
5598If pid is 0, the calling process is changed.
5599param is an instance of sched_param.
5600[clinic start generated code]*/
5601
Larry Hastings2f936352014-08-05 14:04:04 +10005602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005603os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005604 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005605/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005606{
Jesus Cea9c822272011-09-10 01:40:52 +02005607 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005608 ** sched_setscheduler() returns 0 in Linux, but the previous
5609 ** scheduling policy under Solaris/Illumos, and others.
5610 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005611 */
Larry Hastings2f936352014-08-05 14:04:04 +10005612 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005613 return posix_error();
5614 Py_RETURN_NONE;
5615}
Larry Hastings2f936352014-08-05 14:04:04 +10005616#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005617
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005618
5619#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005620/*[clinic input]
5621os.sched_getparam
5622 pid: pid_t
5623 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005624
Larry Hastings2f936352014-08-05 14:04:04 +10005625Returns scheduling parameters for the process identified by pid.
5626
5627If pid is 0, returns parameters for the calling process.
5628Return value is an instance of sched_param.
5629[clinic start generated code]*/
5630
Larry Hastings2f936352014-08-05 14:04:04 +10005631static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005632os_sched_getparam_impl(PyObject *module, pid_t pid)
5633/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005634{
5635 struct sched_param param;
5636 PyObject *result;
5637 PyObject *priority;
5638
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005639 if (sched_getparam(pid, &param))
5640 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005641 result = PyStructSequence_New(&SchedParamType);
5642 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005643 return NULL;
5644 priority = PyLong_FromLong(param.sched_priority);
5645 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005646 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005647 return NULL;
5648 }
Larry Hastings2f936352014-08-05 14:04:04 +10005649 PyStructSequence_SET_ITEM(result, 0, priority);
5650 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005651}
5652
Larry Hastings2f936352014-08-05 14:04:04 +10005653
5654/*[clinic input]
5655os.sched_setparam
5656 pid: pid_t
5657 param: sched_param
5658 /
5659
5660Set scheduling parameters for the process identified by pid.
5661
5662If pid is 0, sets parameters for the calling process.
5663param should be an instance of sched_param.
5664[clinic start generated code]*/
5665
Larry Hastings2f936352014-08-05 14:04:04 +10005666static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005667os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005668 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005669/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005670{
5671 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005672 return posix_error();
5673 Py_RETURN_NONE;
5674}
Larry Hastings2f936352014-08-05 14:04:04 +10005675#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005676
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005677
5678#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005679/*[clinic input]
5680os.sched_rr_get_interval -> double
5681 pid: pid_t
5682 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005683
Larry Hastings2f936352014-08-05 14:04:04 +10005684Return the round-robin quantum for the process identified by pid, in seconds.
5685
5686Value returned is a float.
5687[clinic start generated code]*/
5688
Larry Hastings2f936352014-08-05 14:04:04 +10005689static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005690os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5691/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005692{
5693 struct timespec interval;
5694 if (sched_rr_get_interval(pid, &interval)) {
5695 posix_error();
5696 return -1.0;
5697 }
Gregory P. Smithefcf08d2018-12-30 22:14:33 -08005698#ifdef _Py_MEMORY_SANITIZER
5699 __msan_unpoison(&interval, sizeof(interval));
5700#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005701 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5702}
5703#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005704
Larry Hastings2f936352014-08-05 14:04:04 +10005705
5706/*[clinic input]
5707os.sched_yield
5708
5709Voluntarily relinquish the CPU.
5710[clinic start generated code]*/
5711
Larry Hastings2f936352014-08-05 14:04:04 +10005712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005713os_sched_yield_impl(PyObject *module)
5714/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005715{
5716 if (sched_yield())
5717 return posix_error();
5718 Py_RETURN_NONE;
5719}
5720
Benjamin Peterson2740af82011-08-02 17:41:34 -05005721#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005722/* The minimum number of CPUs allocated in a cpu_set_t */
5723static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005724
Larry Hastings2f936352014-08-05 14:04:04 +10005725/*[clinic input]
5726os.sched_setaffinity
5727 pid: pid_t
5728 mask : object
5729 /
5730
5731Set the CPU affinity of the process identified by pid to mask.
5732
5733mask should be an iterable of integers identifying CPUs.
5734[clinic start generated code]*/
5735
Larry Hastings2f936352014-08-05 14:04:04 +10005736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005737os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5738/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005739{
Antoine Pitrou84869872012-08-04 16:16:35 +02005740 int ncpus;
5741 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005742 cpu_set_t *cpu_set = NULL;
5743 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005744
Larry Hastings2f936352014-08-05 14:04:04 +10005745 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005746 if (iterator == NULL)
5747 return NULL;
5748
5749 ncpus = NCPUS_START;
5750 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005751 cpu_set = CPU_ALLOC(ncpus);
5752 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005753 PyErr_NoMemory();
5754 goto error;
5755 }
Larry Hastings2f936352014-08-05 14:04:04 +10005756 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005757
5758 while ((item = PyIter_Next(iterator))) {
5759 long cpu;
5760 if (!PyLong_Check(item)) {
5761 PyErr_Format(PyExc_TypeError,
5762 "expected an iterator of ints, "
5763 "but iterator yielded %R",
5764 Py_TYPE(item));
5765 Py_DECREF(item);
5766 goto error;
5767 }
5768 cpu = PyLong_AsLong(item);
5769 Py_DECREF(item);
5770 if (cpu < 0) {
5771 if (!PyErr_Occurred())
5772 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5773 goto error;
5774 }
5775 if (cpu > INT_MAX - 1) {
5776 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5777 goto error;
5778 }
5779 if (cpu >= ncpus) {
5780 /* Grow CPU mask to fit the CPU number */
5781 int newncpus = ncpus;
5782 cpu_set_t *newmask;
5783 size_t newsetsize;
5784 while (newncpus <= cpu) {
5785 if (newncpus > INT_MAX / 2)
5786 newncpus = cpu + 1;
5787 else
5788 newncpus = newncpus * 2;
5789 }
5790 newmask = CPU_ALLOC(newncpus);
5791 if (newmask == NULL) {
5792 PyErr_NoMemory();
5793 goto error;
5794 }
5795 newsetsize = CPU_ALLOC_SIZE(newncpus);
5796 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005797 memcpy(newmask, cpu_set, setsize);
5798 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005800 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005801 ncpus = newncpus;
5802 }
Larry Hastings2f936352014-08-05 14:04:04 +10005803 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005804 }
5805 Py_CLEAR(iterator);
5806
Larry Hastings2f936352014-08-05 14:04:04 +10005807 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005808 posix_error();
5809 goto error;
5810 }
Larry Hastings2f936352014-08-05 14:04:04 +10005811 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005812 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005813
5814error:
Larry Hastings2f936352014-08-05 14:04:04 +10005815 if (cpu_set)
5816 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005817 Py_XDECREF(iterator);
5818 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005819}
5820
Larry Hastings2f936352014-08-05 14:04:04 +10005821
5822/*[clinic input]
5823os.sched_getaffinity
5824 pid: pid_t
5825 /
5826
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005827Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005828
5829The affinity is returned as a set of CPU identifiers.
5830[clinic start generated code]*/
5831
Larry Hastings2f936352014-08-05 14:04:04 +10005832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005833os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005834/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005835{
Antoine Pitrou84869872012-08-04 16:16:35 +02005836 int cpu, ncpus, count;
5837 size_t setsize;
5838 cpu_set_t *mask = NULL;
5839 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005840
Antoine Pitrou84869872012-08-04 16:16:35 +02005841 ncpus = NCPUS_START;
5842 while (1) {
5843 setsize = CPU_ALLOC_SIZE(ncpus);
5844 mask = CPU_ALLOC(ncpus);
5845 if (mask == NULL)
5846 return PyErr_NoMemory();
5847 if (sched_getaffinity(pid, setsize, mask) == 0)
5848 break;
5849 CPU_FREE(mask);
5850 if (errno != EINVAL)
5851 return posix_error();
5852 if (ncpus > INT_MAX / 2) {
5853 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5854 "a large enough CPU set");
5855 return NULL;
5856 }
5857 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005858 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005859
5860 res = PySet_New(NULL);
5861 if (res == NULL)
5862 goto error;
5863 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5864 if (CPU_ISSET_S(cpu, setsize, mask)) {
5865 PyObject *cpu_num = PyLong_FromLong(cpu);
5866 --count;
5867 if (cpu_num == NULL)
5868 goto error;
5869 if (PySet_Add(res, cpu_num)) {
5870 Py_DECREF(cpu_num);
5871 goto error;
5872 }
5873 Py_DECREF(cpu_num);
5874 }
5875 }
5876 CPU_FREE(mask);
5877 return res;
5878
5879error:
5880 if (mask)
5881 CPU_FREE(mask);
5882 Py_XDECREF(res);
5883 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005884}
5885
Benjamin Peterson2740af82011-08-02 17:41:34 -05005886#endif /* HAVE_SCHED_SETAFFINITY */
5887
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005888#endif /* HAVE_SCHED_H */
5889
Larry Hastings2f936352014-08-05 14:04:04 +10005890
Neal Norwitzb59798b2003-03-21 01:43:31 +00005891/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005892/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5893#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005894#define DEV_PTY_FILE "/dev/ptc"
5895#define HAVE_DEV_PTMX
5896#else
5897#define DEV_PTY_FILE "/dev/ptmx"
5898#endif
5899
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005900#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005901#ifdef HAVE_PTY_H
5902#include <pty.h>
5903#else
5904#ifdef HAVE_LIBUTIL_H
5905#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005906#else
5907#ifdef HAVE_UTIL_H
5908#include <util.h>
5909#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005910#endif /* HAVE_LIBUTIL_H */
5911#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005912#ifdef HAVE_STROPTS_H
5913#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005914#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005915#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005916
Larry Hastings2f936352014-08-05 14:04:04 +10005917
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005918#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005919/*[clinic input]
5920os.openpty
5921
5922Open a pseudo-terminal.
5923
5924Return a tuple of (master_fd, slave_fd) containing open file descriptors
5925for both the master and slave ends.
5926[clinic start generated code]*/
5927
Larry Hastings2f936352014-08-05 14:04:04 +10005928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005929os_openpty_impl(PyObject *module)
5930/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005931{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005932 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005935#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005936#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 PyOS_sighandler_t sig_saved;
Miss Islington (bot)d8234432018-12-30 18:39:00 -08005938#if defined(__sun) && defined(__SVR4)
Victor Stinner8c62be82010-05-06 00:08:46 +00005939 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005940#endif
5941#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005942
Thomas Wouters70c21a12000-07-14 14:28:33 +00005943#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005945 goto posix_error;
5946
5947 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5948 goto error;
5949 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5950 goto error;
5951
Neal Norwitzb59798b2003-03-21 01:43:31 +00005952#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5954 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005955 goto posix_error;
5956 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5957 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005958
Victor Stinnerdaf45552013-08-28 00:53:59 +02005959 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005961 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005962
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005963#else
Victor Stinner000de532013-11-25 23:19:58 +01005964 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005966 goto posix_error;
5967
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005969
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 /* change permission of slave */
5971 if (grantpt(master_fd) < 0) {
5972 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005973 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005975
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 /* unlock slave */
5977 if (unlockpt(master_fd) < 0) {
5978 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005979 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005981
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005983
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 slave_name = ptsname(master_fd); /* get name of slave */
5985 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005986 goto posix_error;
5987
5988 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005989 if (slave_fd == -1)
5990 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005991
5992 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5993 goto posix_error;
5994
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005995#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005996 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5997 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005998#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006000#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006001#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006002#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006003
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006005
Victor Stinnerdaf45552013-08-28 00:53:59 +02006006posix_error:
6007 posix_error();
6008error:
6009 if (master_fd != -1)
6010 close(master_fd);
6011 if (slave_fd != -1)
6012 close(slave_fd);
6013 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006015#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006016
Larry Hastings2f936352014-08-05 14:04:04 +10006017
Fred Drake8cef4cf2000-06-28 16:40:38 +00006018#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006019/*[clinic input]
6020os.forkpty
6021
6022Fork a new process with a new pseudo-terminal as controlling tty.
6023
6024Returns a tuple of (pid, master_fd).
6025Like fork(), return pid of 0 to the child process,
6026and pid of child to the parent process.
6027To both, return fd of newly opened pseudo-terminal.
6028[clinic start generated code]*/
6029
Larry Hastings2f936352014-08-05 14:04:04 +10006030static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006031os_forkpty_impl(PyObject *module)
6032/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006033{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006034 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006035 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006036
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006037 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 pid = forkpty(&master_fd, NULL, NULL, NULL);
6039 if (pid == 0) {
6040 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006041 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006042 } else {
6043 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006044 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006045 }
6046 if (pid == -1)
6047 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006048 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006049}
Larry Hastings2f936352014-08-05 14:04:04 +10006050#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006051
Ross Lagerwall7807c352011-03-17 20:20:30 +02006052
Guido van Rossumad0ee831995-03-01 10:34:45 +00006053#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006054/*[clinic input]
6055os.getegid
6056
6057Return the current process's effective group id.
6058[clinic start generated code]*/
6059
Larry Hastings2f936352014-08-05 14:04:04 +10006060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006061os_getegid_impl(PyObject *module)
6062/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006063{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006064 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006065}
Larry Hastings2f936352014-08-05 14:04:04 +10006066#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006068
Guido van Rossumad0ee831995-03-01 10:34:45 +00006069#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006070/*[clinic input]
6071os.geteuid
6072
6073Return the current process's effective user id.
6074[clinic start generated code]*/
6075
Larry Hastings2f936352014-08-05 14:04:04 +10006076static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006077os_geteuid_impl(PyObject *module)
6078/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006079{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006080 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006081}
Larry Hastings2f936352014-08-05 14:04:04 +10006082#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006084
Guido van Rossumad0ee831995-03-01 10:34:45 +00006085#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006086/*[clinic input]
6087os.getgid
6088
6089Return the current process's group id.
6090[clinic start generated code]*/
6091
Larry Hastings2f936352014-08-05 14:04:04 +10006092static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006093os_getgid_impl(PyObject *module)
6094/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006095{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006096 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006097}
Larry Hastings2f936352014-08-05 14:04:04 +10006098#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006099
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006100
Berker Peksag39404992016-09-15 20:45:16 +03006101#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006102/*[clinic input]
6103os.getpid
6104
6105Return the current process id.
6106[clinic start generated code]*/
6107
Larry Hastings2f936352014-08-05 14:04:04 +10006108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006109os_getpid_impl(PyObject *module)
6110/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006111{
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006113}
Berker Peksag39404992016-09-15 20:45:16 +03006114#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006115
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006116#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006117
6118/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006119PyDoc_STRVAR(posix_getgrouplist__doc__,
6120"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6121Returns a list of groups to which a user belongs.\n\n\
6122 user: username to lookup\n\
6123 group: base group id of the user");
6124
6125static PyObject *
6126posix_getgrouplist(PyObject *self, PyObject *args)
6127{
6128#ifdef NGROUPS_MAX
6129#define MAX_GROUPS NGROUPS_MAX
6130#else
6131 /* defined to be 16 on Solaris7, so this should be a small number */
6132#define MAX_GROUPS 64
6133#endif
6134
6135 const char *user;
6136 int i, ngroups;
6137 PyObject *list;
6138#ifdef __APPLE__
6139 int *groups, basegid;
6140#else
6141 gid_t *groups, basegid;
6142#endif
6143 ngroups = MAX_GROUPS;
6144
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006145#ifdef __APPLE__
6146 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006147 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006148#else
6149 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6150 _Py_Gid_Converter, &basegid))
6151 return NULL;
6152#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006153
6154#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006155 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006156#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006157 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006158#endif
6159 if (groups == NULL)
6160 return PyErr_NoMemory();
6161
6162 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6163 PyMem_Del(groups);
6164 return posix_error();
6165 }
6166
Gregory P. Smithefcf08d2018-12-30 22:14:33 -08006167#ifdef _Py_MEMORY_SANITIZER
6168 /* Clang memory sanitizer libc intercepts don't know getgrouplist. */
6169 __msan_unpoison(&ngroups, sizeof(ngroups));
6170 __msan_unpoison(groups, ngroups*sizeof(*groups));
6171#endif
6172
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006173 list = PyList_New(ngroups);
6174 if (list == NULL) {
6175 PyMem_Del(groups);
6176 return NULL;
6177 }
6178
6179 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006180#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006181 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006182#else
6183 PyObject *o = _PyLong_FromGid(groups[i]);
6184#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006185 if (o == NULL) {
6186 Py_DECREF(list);
6187 PyMem_Del(groups);
6188 return NULL;
6189 }
6190 PyList_SET_ITEM(list, i, o);
6191 }
6192
6193 PyMem_Del(groups);
6194
6195 return list;
6196}
Larry Hastings2f936352014-08-05 14:04:04 +10006197#endif /* HAVE_GETGROUPLIST */
6198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006199
Fred Drakec9680921999-12-13 16:37:25 +00006200#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006201/*[clinic input]
6202os.getgroups
6203
6204Return list of supplemental group IDs for the process.
6205[clinic start generated code]*/
6206
Larry Hastings2f936352014-08-05 14:04:04 +10006207static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006208os_getgroups_impl(PyObject *module)
6209/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006210{
6211 PyObject *result = NULL;
6212
Fred Drakec9680921999-12-13 16:37:25 +00006213#ifdef NGROUPS_MAX
6214#define MAX_GROUPS NGROUPS_MAX
6215#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006216 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006217#define MAX_GROUPS 64
6218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006220
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006221 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006222 * This is a helper variable to store the intermediate result when
6223 * that happens.
6224 *
6225 * To keep the code readable the OSX behaviour is unconditional,
6226 * according to the POSIX spec this should be safe on all unix-y
6227 * systems.
6228 */
6229 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006230 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006231
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006232#ifdef __APPLE__
6233 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6234 * there are more groups than can fit in grouplist. Therefore, on OS X
6235 * always first call getgroups with length 0 to get the actual number
6236 * of groups.
6237 */
6238 n = getgroups(0, NULL);
6239 if (n < 0) {
6240 return posix_error();
6241 } else if (n <= MAX_GROUPS) {
6242 /* groups will fit in existing array */
6243 alt_grouplist = grouplist;
6244 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006245 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006246 if (alt_grouplist == NULL) {
Zackery Spytz602d3072018-12-07 05:17:43 -07006247 return PyErr_NoMemory();
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006248 }
6249 }
6250
6251 n = getgroups(n, alt_grouplist);
6252 if (n == -1) {
6253 if (alt_grouplist != grouplist) {
6254 PyMem_Free(alt_grouplist);
6255 }
6256 return posix_error();
6257 }
6258#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006260 if (n < 0) {
6261 if (errno == EINVAL) {
6262 n = getgroups(0, NULL);
6263 if (n == -1) {
6264 return posix_error();
6265 }
6266 if (n == 0) {
6267 /* Avoid malloc(0) */
6268 alt_grouplist = grouplist;
6269 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006270 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006271 if (alt_grouplist == NULL) {
Zackery Spytz602d3072018-12-07 05:17:43 -07006272 return PyErr_NoMemory();
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006273 }
6274 n = getgroups(n, alt_grouplist);
6275 if (n == -1) {
6276 PyMem_Free(alt_grouplist);
6277 return posix_error();
6278 }
6279 }
6280 } else {
6281 return posix_error();
6282 }
6283 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006284#endif
6285
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006286 result = PyList_New(n);
6287 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 int i;
6289 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006290 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006292 Py_DECREF(result);
6293 result = NULL;
6294 break;
Fred Drakec9680921999-12-13 16:37:25 +00006295 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006297 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006298 }
6299
6300 if (alt_grouplist != grouplist) {
6301 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006303
Fred Drakec9680921999-12-13 16:37:25 +00006304 return result;
6305}
Larry Hastings2f936352014-08-05 14:04:04 +10006306#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006307
Antoine Pitroub7572f02009-12-02 20:46:48 +00006308#ifdef HAVE_INITGROUPS
6309PyDoc_STRVAR(posix_initgroups__doc__,
6310"initgroups(username, gid) -> None\n\n\
6311Call the system initgroups() to initialize the group access list with all of\n\
6312the groups of which the specified username is a member, plus the specified\n\
6313group id.");
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006316static PyObject *
6317posix_initgroups(PyObject *self, PyObject *args)
6318{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006319 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006320 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006321 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006322#ifdef __APPLE__
6323 int gid;
6324#else
6325 gid_t gid;
6326#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006327
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006328#ifdef __APPLE__
6329 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6330 PyUnicode_FSConverter, &oname,
6331 &gid))
6332#else
6333 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6334 PyUnicode_FSConverter, &oname,
6335 _Py_Gid_Converter, &gid))
6336#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006338 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006339
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006340 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006341 Py_DECREF(oname);
6342 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006344
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006345 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006346}
Larry Hastings2f936352014-08-05 14:04:04 +10006347#endif /* HAVE_INITGROUPS */
6348
Antoine Pitroub7572f02009-12-02 20:46:48 +00006349
Martin v. Löwis606edc12002-06-13 21:09:11 +00006350#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006351/*[clinic input]
6352os.getpgid
6353
6354 pid: pid_t
6355
6356Call the system call getpgid(), and return the result.
6357[clinic start generated code]*/
6358
Larry Hastings2f936352014-08-05 14:04:04 +10006359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006360os_getpgid_impl(PyObject *module, pid_t pid)
6361/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006362{
6363 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 if (pgid < 0)
6365 return posix_error();
6366 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006367}
6368#endif /* HAVE_GETPGID */
6369
6370
Guido van Rossumb6775db1994-08-01 11:34:53 +00006371#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006372/*[clinic input]
6373os.getpgrp
6374
6375Return the current process group id.
6376[clinic start generated code]*/
6377
Larry Hastings2f936352014-08-05 14:04:04 +10006378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006379os_getpgrp_impl(PyObject *module)
6380/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006381{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006382#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006384#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006386#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006387}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006388#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006389
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006390
Guido van Rossumb6775db1994-08-01 11:34:53 +00006391#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006392/*[clinic input]
6393os.setpgrp
6394
6395Make the current process the leader of its process group.
6396[clinic start generated code]*/
6397
Larry Hastings2f936352014-08-05 14:04:04 +10006398static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006399os_setpgrp_impl(PyObject *module)
6400/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006401{
Guido van Rossum64933891994-10-20 21:56:42 +00006402#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006404#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006406#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006408 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006409}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006410#endif /* HAVE_SETPGRP */
6411
Guido van Rossumad0ee831995-03-01 10:34:45 +00006412#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006413
6414#ifdef MS_WINDOWS
6415#include <tlhelp32.h>
6416
6417static PyObject*
6418win32_getppid()
6419{
6420 HANDLE snapshot;
6421 pid_t mypid;
6422 PyObject* result = NULL;
6423 BOOL have_record;
6424 PROCESSENTRY32 pe;
6425
6426 mypid = getpid(); /* This function never fails */
6427
6428 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6429 if (snapshot == INVALID_HANDLE_VALUE)
6430 return PyErr_SetFromWindowsErr(GetLastError());
6431
6432 pe.dwSize = sizeof(pe);
6433 have_record = Process32First(snapshot, &pe);
6434 while (have_record) {
6435 if (mypid == (pid_t)pe.th32ProcessID) {
6436 /* We could cache the ulong value in a static variable. */
6437 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6438 break;
6439 }
6440
6441 have_record = Process32Next(snapshot, &pe);
6442 }
6443
6444 /* If our loop exits and our pid was not found (result will be NULL)
6445 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6446 * error anyway, so let's raise it. */
6447 if (!result)
6448 result = PyErr_SetFromWindowsErr(GetLastError());
6449
6450 CloseHandle(snapshot);
6451
6452 return result;
6453}
6454#endif /*MS_WINDOWS*/
6455
Larry Hastings2f936352014-08-05 14:04:04 +10006456
6457/*[clinic input]
6458os.getppid
6459
6460Return the parent's process id.
6461
6462If the parent process has already exited, Windows machines will still
6463return its id; others systems will return the id of the 'init' process (1).
6464[clinic start generated code]*/
6465
Larry Hastings2f936352014-08-05 14:04:04 +10006466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006467os_getppid_impl(PyObject *module)
6468/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006469{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006470#ifdef MS_WINDOWS
6471 return win32_getppid();
6472#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006474#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006475}
6476#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006478
Fred Drake12c6e2d1999-12-14 21:25:03 +00006479#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006480/*[clinic input]
6481os.getlogin
6482
6483Return the actual login name.
6484[clinic start generated code]*/
6485
Larry Hastings2f936352014-08-05 14:04:04 +10006486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006487os_getlogin_impl(PyObject *module)
6488/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006489{
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006491#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006492 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006493 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006494
6495 if (GetUserNameW(user_name, &num_chars)) {
6496 /* num_chars is the number of unicode chars plus null terminator */
6497 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006498 }
6499 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006500 result = PyErr_SetFromWindowsErr(GetLastError());
6501#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 char *name;
6503 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 errno = 0;
6506 name = getlogin();
6507 if (name == NULL) {
6508 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006509 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006510 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006511 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 }
6513 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006514 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006516#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006517 return result;
6518}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006519#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006520
Larry Hastings2f936352014-08-05 14:04:04 +10006521
Guido van Rossumad0ee831995-03-01 10:34:45 +00006522#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006523/*[clinic input]
6524os.getuid
6525
6526Return the current process's user id.
6527[clinic start generated code]*/
6528
Larry Hastings2f936352014-08-05 14:04:04 +10006529static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006530os_getuid_impl(PyObject *module)
6531/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006532{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006533 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006534}
Larry Hastings2f936352014-08-05 14:04:04 +10006535#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006537
Brian Curtineb24d742010-04-12 17:16:38 +00006538#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006539#define HAVE_KILL
6540#endif /* MS_WINDOWS */
6541
6542#ifdef HAVE_KILL
6543/*[clinic input]
6544os.kill
6545
6546 pid: pid_t
6547 signal: Py_ssize_t
6548 /
6549
6550Kill a process with a signal.
6551[clinic start generated code]*/
6552
Larry Hastings2f936352014-08-05 14:04:04 +10006553static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006554os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6555/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006556#ifndef MS_WINDOWS
6557{
6558 if (kill(pid, (int)signal) == -1)
6559 return posix_error();
6560 Py_RETURN_NONE;
6561}
6562#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006563{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006564 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006565 DWORD sig = (DWORD)signal;
6566 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006568
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 /* Console processes which share a common console can be sent CTRL+C or
6570 CTRL+BREAK events, provided they handle said events. */
6571 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006572 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 err = GetLastError();
6574 PyErr_SetFromWindowsErr(err);
6575 }
6576 else
6577 Py_RETURN_NONE;
6578 }
Brian Curtineb24d742010-04-12 17:16:38 +00006579
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6581 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006582 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 if (handle == NULL) {
6584 err = GetLastError();
6585 return PyErr_SetFromWindowsErr(err);
6586 }
Brian Curtineb24d742010-04-12 17:16:38 +00006587
Victor Stinner8c62be82010-05-06 00:08:46 +00006588 if (TerminateProcess(handle, sig) == 0) {
6589 err = GetLastError();
6590 result = PyErr_SetFromWindowsErr(err);
6591 } else {
6592 Py_INCREF(Py_None);
6593 result = Py_None;
6594 }
Brian Curtineb24d742010-04-12 17:16:38 +00006595
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 CloseHandle(handle);
6597 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006598}
Larry Hastings2f936352014-08-05 14:04:04 +10006599#endif /* !MS_WINDOWS */
6600#endif /* HAVE_KILL */
6601
6602
6603#ifdef HAVE_KILLPG
6604/*[clinic input]
6605os.killpg
6606
6607 pgid: pid_t
6608 signal: int
6609 /
6610
6611Kill a process group with a signal.
6612[clinic start generated code]*/
6613
Larry Hastings2f936352014-08-05 14:04:04 +10006614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006615os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6616/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006617{
6618 /* XXX some man pages make the `pgid` parameter an int, others
6619 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6620 take the same type. Moreover, pid_t is always at least as wide as
6621 int (else compilation of this module fails), which is safe. */
6622 if (killpg(pgid, signal) == -1)
6623 return posix_error();
6624 Py_RETURN_NONE;
6625}
6626#endif /* HAVE_KILLPG */
6627
Brian Curtineb24d742010-04-12 17:16:38 +00006628
Guido van Rossumc0125471996-06-28 18:55:32 +00006629#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006630#ifdef HAVE_SYS_LOCK_H
6631#include <sys/lock.h>
6632#endif
6633
Larry Hastings2f936352014-08-05 14:04:04 +10006634/*[clinic input]
6635os.plock
6636 op: int
6637 /
6638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006640[clinic start generated code]*/
6641
Larry Hastings2f936352014-08-05 14:04:04 +10006642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006643os_plock_impl(PyObject *module, int op)
6644/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006645{
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 if (plock(op) == -1)
6647 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006648 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006649}
Larry Hastings2f936352014-08-05 14:04:04 +10006650#endif /* HAVE_PLOCK */
6651
Guido van Rossumc0125471996-06-28 18:55:32 +00006652
Guido van Rossumb6775db1994-08-01 11:34:53 +00006653#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006654/*[clinic input]
6655os.setuid
6656
6657 uid: uid_t
6658 /
6659
6660Set the current process's user id.
6661[clinic start generated code]*/
6662
Larry Hastings2f936352014-08-05 14:04:04 +10006663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006664os_setuid_impl(PyObject *module, uid_t uid)
6665/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006666{
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 if (setuid(uid) < 0)
6668 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006669 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006670}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006671#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006673
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006674#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006675/*[clinic input]
6676os.seteuid
6677
6678 euid: uid_t
6679 /
6680
6681Set the current process's effective user id.
6682[clinic start generated code]*/
6683
Larry Hastings2f936352014-08-05 14:04:04 +10006684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006685os_seteuid_impl(PyObject *module, uid_t euid)
6686/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006687{
6688 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006690 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006691}
6692#endif /* HAVE_SETEUID */
6693
Larry Hastings2f936352014-08-05 14:04:04 +10006694
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006695#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006696/*[clinic input]
6697os.setegid
6698
6699 egid: gid_t
6700 /
6701
6702Set the current process's effective group id.
6703[clinic start generated code]*/
6704
Larry Hastings2f936352014-08-05 14:04:04 +10006705static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006706os_setegid_impl(PyObject *module, gid_t egid)
6707/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006708{
6709 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006711 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006712}
6713#endif /* HAVE_SETEGID */
6714
Larry Hastings2f936352014-08-05 14:04:04 +10006715
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006716#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006717/*[clinic input]
6718os.setreuid
6719
6720 ruid: uid_t
6721 euid: uid_t
6722 /
6723
6724Set the current process's real and effective user ids.
6725[clinic start generated code]*/
6726
Larry Hastings2f936352014-08-05 14:04:04 +10006727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006728os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6729/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006730{
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 if (setreuid(ruid, euid) < 0) {
6732 return posix_error();
6733 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006734 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006736}
6737#endif /* HAVE_SETREUID */
6738
Larry Hastings2f936352014-08-05 14:04:04 +10006739
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006740#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006741/*[clinic input]
6742os.setregid
6743
6744 rgid: gid_t
6745 egid: gid_t
6746 /
6747
6748Set the current process's real and effective group ids.
6749[clinic start generated code]*/
6750
Larry Hastings2f936352014-08-05 14:04:04 +10006751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006752os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6753/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006754{
6755 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006757 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006758}
6759#endif /* HAVE_SETREGID */
6760
Larry Hastings2f936352014-08-05 14:04:04 +10006761
Guido van Rossumb6775db1994-08-01 11:34:53 +00006762#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006763/*[clinic input]
6764os.setgid
6765 gid: gid_t
6766 /
6767
6768Set the current process's group id.
6769[clinic start generated code]*/
6770
Larry Hastings2f936352014-08-05 14:04:04 +10006771static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006772os_setgid_impl(PyObject *module, gid_t gid)
6773/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006774{
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 if (setgid(gid) < 0)
6776 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006777 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006778}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006779#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006780
Larry Hastings2f936352014-08-05 14:04:04 +10006781
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006782#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006783/*[clinic input]
6784os.setgroups
6785
6786 groups: object
6787 /
6788
6789Set the groups of the current process to list.
6790[clinic start generated code]*/
6791
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006793os_setgroups(PyObject *module, PyObject *groups)
6794/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006795{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006796 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006798
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 if (!PySequence_Check(groups)) {
6800 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6801 return NULL;
6802 }
6803 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006804 if (len < 0) {
6805 return NULL;
6806 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 if (len > MAX_GROUPS) {
6808 PyErr_SetString(PyExc_ValueError, "too many groups");
6809 return NULL;
6810 }
6811 for(i = 0; i < len; i++) {
6812 PyObject *elem;
6813 elem = PySequence_GetItem(groups, i);
6814 if (!elem)
6815 return NULL;
6816 if (!PyLong_Check(elem)) {
6817 PyErr_SetString(PyExc_TypeError,
6818 "groups must be integers");
6819 Py_DECREF(elem);
6820 return NULL;
6821 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006822 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 Py_DECREF(elem);
6824 return NULL;
6825 }
6826 }
6827 Py_DECREF(elem);
6828 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006829
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 if (setgroups(len, grouplist) < 0)
6831 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006832 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006833}
6834#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006835
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6837static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006838wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006839{
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 PyObject *result;
6841 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006842 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 if (pid == -1)
6845 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 if (struct_rusage == NULL) {
6848 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6849 if (m == NULL)
6850 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006851 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 Py_DECREF(m);
6853 if (struct_rusage == NULL)
6854 return NULL;
6855 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006856
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6858 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6859 if (!result)
6860 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006861
6862#ifndef doubletime
6863#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6864#endif
6865
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006867 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006869 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006870#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6872 SET_INT(result, 2, ru->ru_maxrss);
6873 SET_INT(result, 3, ru->ru_ixrss);
6874 SET_INT(result, 4, ru->ru_idrss);
6875 SET_INT(result, 5, ru->ru_isrss);
6876 SET_INT(result, 6, ru->ru_minflt);
6877 SET_INT(result, 7, ru->ru_majflt);
6878 SET_INT(result, 8, ru->ru_nswap);
6879 SET_INT(result, 9, ru->ru_inblock);
6880 SET_INT(result, 10, ru->ru_oublock);
6881 SET_INT(result, 11, ru->ru_msgsnd);
6882 SET_INT(result, 12, ru->ru_msgrcv);
6883 SET_INT(result, 13, ru->ru_nsignals);
6884 SET_INT(result, 14, ru->ru_nvcsw);
6885 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886#undef SET_INT
6887
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 if (PyErr_Occurred()) {
6889 Py_DECREF(result);
6890 return NULL;
6891 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894}
6895#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6896
Larry Hastings2f936352014-08-05 14:04:04 +10006897
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006898#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006899/*[clinic input]
6900os.wait3
6901
6902 options: int
6903Wait for completion of a child process.
6904
6905Returns a tuple of information about the child process:
6906 (pid, status, rusage)
6907[clinic start generated code]*/
6908
Larry Hastings2f936352014-08-05 14:04:04 +10006909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006910os_wait3_impl(PyObject *module, int options)
6911/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006912{
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006915 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 WAIT_TYPE status;
6917 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006918
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006919 do {
6920 Py_BEGIN_ALLOW_THREADS
6921 pid = wait3(&status, options, &ru);
6922 Py_END_ALLOW_THREADS
6923 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6924 if (pid < 0)
6925 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006926
Victor Stinner4195b5c2012-02-08 23:03:19 +01006927 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006928}
6929#endif /* HAVE_WAIT3 */
6930
Larry Hastings2f936352014-08-05 14:04:04 +10006931
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006932#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006933/*[clinic input]
6934
6935os.wait4
6936
6937 pid: pid_t
6938 options: int
6939
6940Wait for completion of a specific child process.
6941
6942Returns a tuple of information about the child process:
6943 (pid, status, rusage)
6944[clinic start generated code]*/
6945
Larry Hastings2f936352014-08-05 14:04:04 +10006946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006947os_wait4_impl(PyObject *module, pid_t pid, int options)
6948/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006949{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006950 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006952 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 WAIT_TYPE status;
6954 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006955
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006956 do {
6957 Py_BEGIN_ALLOW_THREADS
6958 res = wait4(pid, &status, options, &ru);
6959 Py_END_ALLOW_THREADS
6960 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6961 if (res < 0)
6962 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006963
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006964 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006965}
6966#endif /* HAVE_WAIT4 */
6967
Larry Hastings2f936352014-08-05 14:04:04 +10006968
Ross Lagerwall7807c352011-03-17 20:20:30 +02006969#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006970/*[clinic input]
6971os.waitid
6972
6973 idtype: idtype_t
6974 Must be one of be P_PID, P_PGID or P_ALL.
6975 id: id_t
6976 The id to wait on.
6977 options: int
6978 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6979 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6980 /
6981
6982Returns the result of waiting for a process or processes.
6983
6984Returns either waitid_result or None if WNOHANG is specified and there are
6985no children in a waitable state.
6986[clinic start generated code]*/
6987
Larry Hastings2f936352014-08-05 14:04:04 +10006988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006989os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6990/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006991{
6992 PyObject *result;
6993 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006994 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006995 siginfo_t si;
6996 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006997
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006998 do {
6999 Py_BEGIN_ALLOW_THREADS
7000 res = waitid(idtype, id, &si, options);
7001 Py_END_ALLOW_THREADS
7002 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7003 if (res < 0)
7004 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007005
7006 if (si.si_pid == 0)
7007 Py_RETURN_NONE;
7008
7009 result = PyStructSequence_New(&WaitidResultType);
7010 if (!result)
7011 return NULL;
7012
7013 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007014 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007015 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7016 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7017 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7018 if (PyErr_Occurred()) {
7019 Py_DECREF(result);
7020 return NULL;
7021 }
7022
7023 return result;
7024}
Larry Hastings2f936352014-08-05 14:04:04 +10007025#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007026
Larry Hastings2f936352014-08-05 14:04:04 +10007027
7028#if defined(HAVE_WAITPID)
7029/*[clinic input]
7030os.waitpid
7031 pid: pid_t
7032 options: int
7033 /
7034
7035Wait for completion of a given child process.
7036
7037Returns a tuple of information regarding the child process:
7038 (pid, status)
7039
7040The options argument is ignored on Windows.
7041[clinic start generated code]*/
7042
Larry Hastings2f936352014-08-05 14:04:04 +10007043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007044os_waitpid_impl(PyObject *module, pid_t pid, int options)
7045/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007046{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007047 pid_t res;
7048 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 WAIT_TYPE status;
7050 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007051
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007052 do {
7053 Py_BEGIN_ALLOW_THREADS
7054 res = waitpid(pid, &status, options);
7055 Py_END_ALLOW_THREADS
7056 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7057 if (res < 0)
7058 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007059
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007060 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007061}
Tim Petersab034fa2002-02-01 11:27:43 +00007062#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007063/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007064/*[clinic input]
7065os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007066 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007067 options: int
7068 /
7069
7070Wait for completion of a given process.
7071
7072Returns a tuple of information regarding the process:
7073 (pid, status << 8)
7074
7075The options argument is ignored on Windows.
7076[clinic start generated code]*/
7077
Larry Hastings2f936352014-08-05 14:04:04 +10007078static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007079os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007080/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007081{
7082 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007083 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007084 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007085
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007086 do {
7087 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007088 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007089 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007090 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007091 Py_END_ALLOW_THREADS
7092 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007093 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007094 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007095
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007097 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007098}
Larry Hastings2f936352014-08-05 14:04:04 +10007099#endif
7100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007101
Guido van Rossumad0ee831995-03-01 10:34:45 +00007102#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007103/*[clinic input]
7104os.wait
7105
7106Wait for completion of a child process.
7107
7108Returns a tuple of information about the child process:
7109 (pid, status)
7110[clinic start generated code]*/
7111
Larry Hastings2f936352014-08-05 14:04:04 +10007112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007113os_wait_impl(PyObject *module)
7114/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007115{
Victor Stinner8c62be82010-05-06 00:08:46 +00007116 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007117 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 WAIT_TYPE status;
7119 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007120
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007121 do {
7122 Py_BEGIN_ALLOW_THREADS
7123 pid = wait(&status);
7124 Py_END_ALLOW_THREADS
7125 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7126 if (pid < 0)
7127 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007128
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007130}
Larry Hastings2f936352014-08-05 14:04:04 +10007131#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007133
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7135PyDoc_STRVAR(readlink__doc__,
7136"readlink(path, *, dir_fd=None) -> path\n\n\
7137Return a string representing the path to which the symbolic link points.\n\
7138\n\
7139If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7140 and path should be relative; path will then be relative to that directory.\n\
7141dir_fd may not be implemented on your platform.\n\
7142 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007143#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007144
Guido van Rossumb6775db1994-08-01 11:34:53 +00007145#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007146
Larry Hastings2f936352014-08-05 14:04:04 +10007147/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007148static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007149posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007150{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007151 path_t path;
7152 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007153 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154 ssize_t length;
7155 PyObject *return_value = NULL;
7156 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007157
Larry Hastings9cf065c2012-06-22 16:30:09 -07007158 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007159 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7161 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007162 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007164
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166#ifdef HAVE_READLINKAT
7167 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007168 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007169 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007171 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007172 Py_END_ALLOW_THREADS
7173
7174 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007175 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007176 goto exit;
7177 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007178 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007179
7180 if (PyUnicode_Check(path.object))
7181 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7182 else
7183 return_value = PyBytes_FromStringAndSize(buffer, length);
7184exit:
7185 path_cleanup(&path);
7186 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007187}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007188
Guido van Rossumb6775db1994-08-01 11:34:53 +00007189#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007190
Larry Hastings2f936352014-08-05 14:04:04 +10007191#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7192
7193static PyObject *
7194win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7195{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007196 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007197 DWORD n_bytes_returned;
7198 DWORD io_result;
7199 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007200 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007201 HANDLE reparse_point_handle;
7202
Martin Panter70214ad2016-08-04 02:38:59 +00007203 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7204 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007205 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007206
7207 static char *keywords[] = {"path", "dir_fd", NULL};
7208
7209 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7210 &po,
7211 dir_fd_unavailable, &dir_fd
7212 ))
7213 return NULL;
7214
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007215 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007216 if (path == NULL)
7217 return NULL;
7218
7219 /* First get a handle to the reparse point */
7220 Py_BEGIN_ALLOW_THREADS
7221 reparse_point_handle = CreateFileW(
7222 path,
7223 0,
7224 0,
7225 0,
7226 OPEN_EXISTING,
7227 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7228 0);
7229 Py_END_ALLOW_THREADS
7230
7231 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7232 return win32_error_object("readlink", po);
7233
7234 Py_BEGIN_ALLOW_THREADS
7235 /* New call DeviceIoControl to read the reparse point */
7236 io_result = DeviceIoControl(
7237 reparse_point_handle,
7238 FSCTL_GET_REPARSE_POINT,
7239 0, 0, /* in buffer */
7240 target_buffer, sizeof(target_buffer),
7241 &n_bytes_returned,
7242 0 /* we're not using OVERLAPPED_IO */
7243 );
7244 CloseHandle(reparse_point_handle);
7245 Py_END_ALLOW_THREADS
7246
7247 if (io_result==0)
7248 return win32_error_object("readlink", po);
7249
7250 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7251 {
7252 PyErr_SetString(PyExc_ValueError,
7253 "not a symbolic link");
7254 return NULL;
7255 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007256 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7257 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007258
7259 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007260 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007261 return result;
7262}
7263
7264#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7265
7266
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007267
Larry Hastings9cf065c2012-06-22 16:30:09 -07007268#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007269
7270#if defined(MS_WINDOWS)
7271
7272/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007273static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007274
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007276check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007277{
7278 HINSTANCE hKernel32;
7279 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007280 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007281 return 1;
7282 hKernel32 = GetModuleHandleW(L"KERNEL32");
7283 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7284 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007285 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007286}
7287
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007288/* Remove the last portion of the path - return 0 on success */
7289static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007290_dirnameW(WCHAR *path)
7291{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007292 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007293 size_t length = wcsnlen_s(path, MAX_PATH);
7294 if (length == MAX_PATH) {
7295 return -1;
7296 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297
7298 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007299 for(ptr = path + length; ptr != path; ptr--) {
7300 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007301 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007302 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007303 }
7304 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007305 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007306}
7307
Victor Stinner31b3b922013-06-05 01:49:17 +02007308/* Is this path absolute? */
7309static int
7310_is_absW(const WCHAR *path)
7311{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007312 return path[0] == L'\\' || path[0] == L'/' ||
7313 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314}
7315
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007316/* join root and rest with a backslash - return 0 on success */
7317static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007318_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7319{
Victor Stinner31b3b922013-06-05 01:49:17 +02007320 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007321 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007322 }
7323
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007324 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7325 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007326 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007327
7328 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7329 return -1;
7330 }
7331
7332 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333}
7334
Victor Stinner31b3b922013-06-05 01:49:17 +02007335/* Return True if the path at src relative to dest is a directory */
7336static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007337_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007338{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007339 WIN32_FILE_ATTRIBUTE_DATA src_info;
7340 WCHAR dest_parent[MAX_PATH];
7341 WCHAR src_resolved[MAX_PATH] = L"";
7342
7343 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007344 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7345 _dirnameW(dest_parent)) {
7346 return 0;
7347 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007348 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007349 if (_joinW(src_resolved, dest_parent, src)) {
7350 return 0;
7351 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007352 return (
7353 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7354 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7355 );
7356}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007357#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007358
Larry Hastings2f936352014-08-05 14:04:04 +10007359
7360/*[clinic input]
7361os.symlink
7362 src: path_t
7363 dst: path_t
7364 target_is_directory: bool = False
7365 *
7366 dir_fd: dir_fd(requires='symlinkat')=None
7367
7368# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7369
7370Create a symbolic link pointing to src named dst.
7371
7372target_is_directory is required on Windows if the target is to be
7373 interpreted as a directory. (On Windows, symlink requires
7374 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7375 target_is_directory is ignored on non-Windows platforms.
7376
7377If dir_fd is not None, it should be a file descriptor open to a directory,
7378 and path should be relative; path will then be relative to that directory.
7379dir_fd may not be implemented on your platform.
7380 If it is unavailable, using it will raise a NotImplementedError.
7381
7382[clinic start generated code]*/
7383
Larry Hastings2f936352014-08-05 14:04:04 +10007384static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007385os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007386 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007387/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007388{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007389#ifdef MS_WINDOWS
7390 DWORD result;
7391#else
7392 int result;
7393#endif
7394
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395#ifdef MS_WINDOWS
7396 if (!check_CreateSymbolicLink()) {
7397 PyErr_SetString(PyExc_NotImplementedError,
7398 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007399 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007400 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007401 if (!win32_can_symlink) {
7402 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007403 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007404 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405#endif
7406
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007408
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007410 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007411 /* if src is a directory, ensure target_is_directory==1 */
7412 target_is_directory |= _check_dirW(src->wide, dst->wide);
7413 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7414 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007415 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007416 Py_END_ALLOW_THREADS
7417
Larry Hastings2f936352014-08-05 14:04:04 +10007418 if (!result)
7419 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007420
7421#else
7422
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007423 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7424 PyErr_SetString(PyExc_ValueError,
7425 "symlink: src and dst must be the same type");
7426 return NULL;
7427 }
7428
Larry Hastings9cf065c2012-06-22 16:30:09 -07007429 Py_BEGIN_ALLOW_THREADS
7430#if HAVE_SYMLINKAT
7431 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007432 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433 else
7434#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007435 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007436 Py_END_ALLOW_THREADS
7437
Larry Hastings2f936352014-08-05 14:04:04 +10007438 if (result)
7439 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007440#endif
7441
Larry Hastings2f936352014-08-05 14:04:04 +10007442 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007443}
7444#endif /* HAVE_SYMLINK */
7445
Larry Hastings9cf065c2012-06-22 16:30:09 -07007446
Brian Curtind40e6f72010-07-08 21:39:08 +00007447
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007448
Larry Hastings605a62d2012-06-24 04:33:36 -07007449static PyStructSequence_Field times_result_fields[] = {
7450 {"user", "user time"},
7451 {"system", "system time"},
7452 {"children_user", "user time of children"},
7453 {"children_system", "system time of children"},
7454 {"elapsed", "elapsed time since an arbitrary point in the past"},
7455 {NULL}
7456};
7457
7458PyDoc_STRVAR(times_result__doc__,
7459"times_result: Result from os.times().\n\n\
7460This object may be accessed either as a tuple of\n\
7461 (user, system, children_user, children_system, elapsed),\n\
7462or via the attributes user, system, children_user, children_system,\n\
7463and elapsed.\n\
7464\n\
7465See os.times for more information.");
7466
7467static PyStructSequence_Desc times_result_desc = {
7468 "times_result", /* name */
7469 times_result__doc__, /* doc */
7470 times_result_fields,
7471 5
7472};
7473
7474static PyTypeObject TimesResultType;
7475
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007476#ifdef MS_WINDOWS
7477#define HAVE_TIMES /* mandatory, for the method table */
7478#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007479
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007480#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007481
7482static PyObject *
7483build_times_result(double user, double system,
7484 double children_user, double children_system,
7485 double elapsed)
7486{
7487 PyObject *value = PyStructSequence_New(&TimesResultType);
7488 if (value == NULL)
7489 return NULL;
7490
7491#define SET(i, field) \
7492 { \
7493 PyObject *o = PyFloat_FromDouble(field); \
7494 if (!o) { \
7495 Py_DECREF(value); \
7496 return NULL; \
7497 } \
7498 PyStructSequence_SET_ITEM(value, i, o); \
7499 } \
7500
7501 SET(0, user);
7502 SET(1, system);
7503 SET(2, children_user);
7504 SET(3, children_system);
7505 SET(4, elapsed);
7506
7507#undef SET
7508
7509 return value;
7510}
7511
Larry Hastings605a62d2012-06-24 04:33:36 -07007512
Larry Hastings2f936352014-08-05 14:04:04 +10007513#ifndef MS_WINDOWS
7514#define NEED_TICKS_PER_SECOND
7515static long ticks_per_second = -1;
7516#endif /* MS_WINDOWS */
7517
7518/*[clinic input]
7519os.times
7520
7521Return a collection containing process timing information.
7522
7523The object returned behaves like a named tuple with these fields:
7524 (utime, stime, cutime, cstime, elapsed_time)
7525All fields are floating point numbers.
7526[clinic start generated code]*/
7527
Larry Hastings2f936352014-08-05 14:04:04 +10007528static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007529os_times_impl(PyObject *module)
7530/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007531#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007532{
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 FILETIME create, exit, kernel, user;
7534 HANDLE hProc;
7535 hProc = GetCurrentProcess();
7536 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7537 /* The fields of a FILETIME structure are the hi and lo part
7538 of a 64-bit value expressed in 100 nanosecond units.
7539 1e7 is one second in such units; 1e-7 the inverse.
7540 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7541 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007542 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007543 (double)(user.dwHighDateTime*429.4967296 +
7544 user.dwLowDateTime*1e-7),
7545 (double)(kernel.dwHighDateTime*429.4967296 +
7546 kernel.dwLowDateTime*1e-7),
7547 (double)0,
7548 (double)0,
7549 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007550}
Larry Hastings2f936352014-08-05 14:04:04 +10007551#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007552{
Larry Hastings2f936352014-08-05 14:04:04 +10007553
7554
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007555 struct tms t;
7556 clock_t c;
7557 errno = 0;
7558 c = times(&t);
7559 if (c == (clock_t) -1)
7560 return posix_error();
7561 return build_times_result(
7562 (double)t.tms_utime / ticks_per_second,
7563 (double)t.tms_stime / ticks_per_second,
7564 (double)t.tms_cutime / ticks_per_second,
7565 (double)t.tms_cstime / ticks_per_second,
7566 (double)c / ticks_per_second);
7567}
Larry Hastings2f936352014-08-05 14:04:04 +10007568#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007569#endif /* HAVE_TIMES */
7570
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007571
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007572#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007573/*[clinic input]
7574os.getsid
7575
7576 pid: pid_t
7577 /
7578
7579Call the system call getsid(pid) and return the result.
7580[clinic start generated code]*/
7581
Larry Hastings2f936352014-08-05 14:04:04 +10007582static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007583os_getsid_impl(PyObject *module, pid_t pid)
7584/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007585{
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007587 sid = getsid(pid);
7588 if (sid < 0)
7589 return posix_error();
7590 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007591}
7592#endif /* HAVE_GETSID */
7593
7594
Guido van Rossumb6775db1994-08-01 11:34:53 +00007595#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007596/*[clinic input]
7597os.setsid
7598
7599Call the system call setsid().
7600[clinic start generated code]*/
7601
Larry Hastings2f936352014-08-05 14:04:04 +10007602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007603os_setsid_impl(PyObject *module)
7604/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007605{
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 if (setsid() < 0)
7607 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007608 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007610#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007611
Larry Hastings2f936352014-08-05 14:04:04 +10007612
Guido van Rossumb6775db1994-08-01 11:34:53 +00007613#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007614/*[clinic input]
7615os.setpgid
7616
7617 pid: pid_t
7618 pgrp: pid_t
7619 /
7620
7621Call the system call setpgid(pid, pgrp).
7622[clinic start generated code]*/
7623
Larry Hastings2f936352014-08-05 14:04:04 +10007624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007625os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7626/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007627{
Victor Stinner8c62be82010-05-06 00:08:46 +00007628 if (setpgid(pid, pgrp) < 0)
7629 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007630 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007631}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007632#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007633
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007634
Guido van Rossumb6775db1994-08-01 11:34:53 +00007635#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007636/*[clinic input]
7637os.tcgetpgrp
7638
7639 fd: int
7640 /
7641
7642Return the process group associated with the terminal specified by fd.
7643[clinic start generated code]*/
7644
Larry Hastings2f936352014-08-05 14:04:04 +10007645static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007646os_tcgetpgrp_impl(PyObject *module, int fd)
7647/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007648{
7649 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007650 if (pgid < 0)
7651 return posix_error();
7652 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007653}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007654#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007655
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007656
Guido van Rossumb6775db1994-08-01 11:34:53 +00007657#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007658/*[clinic input]
7659os.tcsetpgrp
7660
7661 fd: int
7662 pgid: pid_t
7663 /
7664
7665Set the process group associated with the terminal specified by fd.
7666[clinic start generated code]*/
7667
Larry Hastings2f936352014-08-05 14:04:04 +10007668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007669os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7670/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007671{
Victor Stinner8c62be82010-05-06 00:08:46 +00007672 if (tcsetpgrp(fd, pgid) < 0)
7673 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007674 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007675}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007676#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007677
Guido van Rossum687dd131993-05-17 08:34:16 +00007678/* Functions acting on file descriptors */
7679
Victor Stinnerdaf45552013-08-28 00:53:59 +02007680#ifdef O_CLOEXEC
7681extern int _Py_open_cloexec_works;
7682#endif
7683
Larry Hastings2f936352014-08-05 14:04:04 +10007684
7685/*[clinic input]
7686os.open -> int
7687 path: path_t
7688 flags: int
7689 mode: int = 0o777
7690 *
7691 dir_fd: dir_fd(requires='openat') = None
7692
7693# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7694
7695Open a file for low level IO. Returns a file descriptor (integer).
7696
7697If dir_fd is not None, it should be a file descriptor open to a directory,
7698 and path should be relative; path will then be relative to that directory.
7699dir_fd may not be implemented on your platform.
7700 If it is unavailable, using it will raise a NotImplementedError.
7701[clinic start generated code]*/
7702
Larry Hastings2f936352014-08-05 14:04:04 +10007703static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007704os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7705/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007706{
7707 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007708 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007709
Victor Stinnerdaf45552013-08-28 00:53:59 +02007710#ifdef O_CLOEXEC
7711 int *atomic_flag_works = &_Py_open_cloexec_works;
7712#elif !defined(MS_WINDOWS)
7713 int *atomic_flag_works = NULL;
7714#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007715
Victor Stinnerdaf45552013-08-28 00:53:59 +02007716#ifdef MS_WINDOWS
7717 flags |= O_NOINHERIT;
7718#elif defined(O_CLOEXEC)
7719 flags |= O_CLOEXEC;
7720#endif
7721
Steve Dower8fc89802015-04-12 00:26:27 -04007722 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007723 do {
7724 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007725#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007726 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007727#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007728#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007729 if (dir_fd != DEFAULT_DIR_FD)
7730 fd = openat(dir_fd, path->narrow, flags, mode);
7731 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007732#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007733 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007734#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007735 Py_END_ALLOW_THREADS
7736 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007737 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007738
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007739 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007740 if (!async_err)
7741 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007742 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743 }
7744
Victor Stinnerdaf45552013-08-28 00:53:59 +02007745#ifndef MS_WINDOWS
7746 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7747 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007748 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007749 }
7750#endif
7751
Larry Hastings2f936352014-08-05 14:04:04 +10007752 return fd;
7753}
7754
7755
7756/*[clinic input]
7757os.close
7758
7759 fd: int
7760
7761Close a file descriptor.
7762[clinic start generated code]*/
7763
Barry Warsaw53699e91996-12-10 23:23:01 +00007764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007765os_close_impl(PyObject *module, int fd)
7766/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007767{
Larry Hastings2f936352014-08-05 14:04:04 +10007768 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007769 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7770 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7771 * for more details.
7772 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007774 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007776 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 Py_END_ALLOW_THREADS
7778 if (res < 0)
7779 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007780 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007781}
7782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007783
Larry Hastings2f936352014-08-05 14:04:04 +10007784/*[clinic input]
7785os.closerange
7786
7787 fd_low: int
7788 fd_high: int
7789 /
7790
7791Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7792[clinic start generated code]*/
7793
Larry Hastings2f936352014-08-05 14:04:04 +10007794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007795os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7796/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007797{
7798 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007800 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007801 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007802 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007803 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 Py_END_ALLOW_THREADS
7805 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007806}
7807
7808
Larry Hastings2f936352014-08-05 14:04:04 +10007809/*[clinic input]
7810os.dup -> int
7811
7812 fd: int
7813 /
7814
7815Return a duplicate of a file descriptor.
7816[clinic start generated code]*/
7817
Larry Hastings2f936352014-08-05 14:04:04 +10007818static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007819os_dup_impl(PyObject *module, int fd)
7820/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007821{
7822 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007823}
7824
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007825
Larry Hastings2f936352014-08-05 14:04:04 +10007826/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007827os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007828 fd: int
7829 fd2: int
7830 inheritable: bool=True
7831
7832Duplicate file descriptor.
7833[clinic start generated code]*/
7834
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007835static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007836os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007837/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007838{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007839 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840#if defined(HAVE_DUP3) && \
7841 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7842 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007843 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007844#endif
7845
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007846 if (fd < 0 || fd2 < 0) {
7847 posix_error();
7848 return -1;
7849 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007850
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007851 /* dup2() can fail with EINTR if the target FD is already open, because it
7852 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7853 * upon close(), and therefore below.
7854 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007855#ifdef MS_WINDOWS
7856 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007857 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007859 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007861 if (res < 0) {
7862 posix_error();
7863 return -1;
7864 }
7865 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007866
7867 /* Character files like console cannot be make non-inheritable */
7868 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7869 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007870 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007871 }
7872
7873#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7874 Py_BEGIN_ALLOW_THREADS
7875 if (!inheritable)
7876 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7877 else
7878 res = dup2(fd, fd2);
7879 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007880 if (res < 0) {
7881 posix_error();
7882 return -1;
7883 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007884
7885#else
7886
7887#ifdef HAVE_DUP3
7888 if (!inheritable && dup3_works != 0) {
7889 Py_BEGIN_ALLOW_THREADS
7890 res = dup3(fd, fd2, O_CLOEXEC);
7891 Py_END_ALLOW_THREADS
7892 if (res < 0) {
7893 if (dup3_works == -1)
7894 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007895 if (dup3_works) {
7896 posix_error();
7897 return -1;
7898 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007899 }
7900 }
7901
7902 if (inheritable || dup3_works == 0)
7903 {
7904#endif
7905 Py_BEGIN_ALLOW_THREADS
7906 res = dup2(fd, fd2);
7907 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007908 if (res < 0) {
7909 posix_error();
7910 return -1;
7911 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007912
7913 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7914 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007915 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007916 }
7917#ifdef HAVE_DUP3
7918 }
7919#endif
7920
7921#endif
7922
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007923 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007924}
7925
Larry Hastings2f936352014-08-05 14:04:04 +10007926
Ross Lagerwall7807c352011-03-17 20:20:30 +02007927#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007928/*[clinic input]
7929os.lockf
7930
7931 fd: int
7932 An open file descriptor.
7933 command: int
7934 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7935 length: Py_off_t
7936 The number of bytes to lock, starting at the current position.
7937 /
7938
7939Apply, test or remove a POSIX lock on an open file descriptor.
7940
7941[clinic start generated code]*/
7942
Larry Hastings2f936352014-08-05 14:04:04 +10007943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007944os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7945/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007946{
7947 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007948
7949 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007950 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007951 Py_END_ALLOW_THREADS
7952
7953 if (res < 0)
7954 return posix_error();
7955
7956 Py_RETURN_NONE;
7957}
Larry Hastings2f936352014-08-05 14:04:04 +10007958#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007960
Larry Hastings2f936352014-08-05 14:04:04 +10007961/*[clinic input]
7962os.lseek -> Py_off_t
7963
7964 fd: int
7965 position: Py_off_t
7966 how: int
7967 /
7968
7969Set the position of a file descriptor. Return the new position.
7970
7971Return the new cursor position in number of bytes
7972relative to the beginning of the file.
7973[clinic start generated code]*/
7974
Larry Hastings2f936352014-08-05 14:04:04 +10007975static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007976os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7977/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007978{
7979 Py_off_t result;
7980
Guido van Rossum687dd131993-05-17 08:34:16 +00007981#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7983 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007984 case 0: how = SEEK_SET; break;
7985 case 1: how = SEEK_CUR; break;
7986 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007988#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007989
Victor Stinner8c62be82010-05-06 00:08:46 +00007990 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007991 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007992
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007994 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007995#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007996 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007997#else
Larry Hastings2f936352014-08-05 14:04:04 +10007998 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007999#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008000 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008002 if (result < 0)
8003 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008004
Larry Hastings2f936352014-08-05 14:04:04 +10008005 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008006}
8007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008008
Larry Hastings2f936352014-08-05 14:04:04 +10008009/*[clinic input]
8010os.read
8011 fd: int
8012 length: Py_ssize_t
8013 /
8014
8015Read from a file descriptor. Returns a bytes object.
8016[clinic start generated code]*/
8017
Larry Hastings2f936352014-08-05 14:04:04 +10008018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008019os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8020/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008021{
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 Py_ssize_t n;
8023 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008024
8025 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 errno = EINVAL;
8027 return posix_error();
8028 }
Larry Hastings2f936352014-08-05 14:04:04 +10008029
Miss Islington (bot)18f33272018-11-22 06:17:34 -08008030 length = Py_MIN(length, _PY_READ_MAX);
Larry Hastings2f936352014-08-05 14:04:04 +10008031
8032 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 if (buffer == NULL)
8034 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008035
Victor Stinner66aab0c2015-03-19 22:53:20 +01008036 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8037 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008038 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008039 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 }
Larry Hastings2f936352014-08-05 14:04:04 +10008041
8042 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008044
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008046}
8047
Ross Lagerwall7807c352011-03-17 20:20:30 +02008048#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008049 || defined(__APPLE__))) \
8050 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8051 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8052static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008053iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008055 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008056
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057 *iov = PyMem_New(struct iovec, cnt);
8058 if (*iov == NULL) {
8059 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008060 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008062
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063 *buf = PyMem_New(Py_buffer, cnt);
8064 if (*buf == NULL) {
8065 PyMem_Del(*iov);
8066 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008067 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068 }
8069
8070 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008071 PyObject *item = PySequence_GetItem(seq, i);
8072 if (item == NULL)
8073 goto fail;
8074 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8075 Py_DECREF(item);
8076 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008078 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008080 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008081 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008082 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008083
8084fail:
8085 PyMem_Del(*iov);
8086 for (j = 0; j < i; j++) {
8087 PyBuffer_Release(&(*buf)[j]);
8088 }
8089 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008090 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091}
8092
8093static void
8094iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8095{
8096 int i;
8097 PyMem_Del(iov);
8098 for (i = 0; i < cnt; i++) {
8099 PyBuffer_Release(&buf[i]);
8100 }
8101 PyMem_Del(buf);
8102}
8103#endif
8104
Larry Hastings2f936352014-08-05 14:04:04 +10008105
Ross Lagerwall7807c352011-03-17 20:20:30 +02008106#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008107/*[clinic input]
8108os.readv -> Py_ssize_t
8109
8110 fd: int
8111 buffers: object
8112 /
8113
8114Read from a file descriptor fd into an iterable of buffers.
8115
8116The buffers should be mutable buffers accepting bytes.
8117readv will transfer data into each buffer until it is full
8118and then move on to the next buffer in the sequence to hold
8119the rest of the data.
8120
8121readv returns the total number of bytes read,
8122which may be less than the total capacity of all the buffers.
8123[clinic start generated code]*/
8124
Larry Hastings2f936352014-08-05 14:04:04 +10008125static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008126os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8127/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008128{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008129 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008130 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008131 struct iovec *iov;
8132 Py_buffer *buf;
8133
Larry Hastings2f936352014-08-05 14:04:04 +10008134 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008135 PyErr_SetString(PyExc_TypeError,
8136 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008137 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008138 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008139
Larry Hastings2f936352014-08-05 14:04:04 +10008140 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008141 if (cnt < 0)
8142 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008143
8144 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8145 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008146
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008147 do {
8148 Py_BEGIN_ALLOW_THREADS
8149 n = readv(fd, iov, cnt);
8150 Py_END_ALLOW_THREADS
8151 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008152
8153 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008154 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008155 if (!async_err)
8156 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008157 return -1;
8158 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008159
Larry Hastings2f936352014-08-05 14:04:04 +10008160 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008161}
Larry Hastings2f936352014-08-05 14:04:04 +10008162#endif /* HAVE_READV */
8163
Ross Lagerwall7807c352011-03-17 20:20:30 +02008164
8165#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008166/*[clinic input]
8167# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8168os.pread
8169
8170 fd: int
8171 length: int
8172 offset: Py_off_t
8173 /
8174
8175Read a number of bytes from a file descriptor starting at a particular offset.
8176
8177Read length bytes from file descriptor fd, starting at offset bytes from
8178the beginning of the file. The file offset remains unchanged.
8179[clinic start generated code]*/
8180
Larry Hastings2f936352014-08-05 14:04:04 +10008181static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008182os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8183/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008184{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008185 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008186 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008187 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008188
Larry Hastings2f936352014-08-05 14:04:04 +10008189 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008190 errno = EINVAL;
8191 return posix_error();
8192 }
Larry Hastings2f936352014-08-05 14:04:04 +10008193 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194 if (buffer == NULL)
8195 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008196
8197 do {
8198 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008199 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008200 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008201 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008202 Py_END_ALLOW_THREADS
8203 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8204
Ross Lagerwall7807c352011-03-17 20:20:30 +02008205 if (n < 0) {
8206 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008207 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208 }
Larry Hastings2f936352014-08-05 14:04:04 +10008209 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008210 _PyBytes_Resize(&buffer, n);
8211 return buffer;
8212}
Larry Hastings2f936352014-08-05 14:04:04 +10008213#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008214
Pablo Galindo4defba32018-01-27 16:16:37 +00008215#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8216/*[clinic input]
8217os.preadv -> Py_ssize_t
8218
8219 fd: int
8220 buffers: object
8221 offset: Py_off_t
8222 flags: int = 0
8223 /
8224
8225Reads from a file descriptor into a number of mutable bytes-like objects.
8226
8227Combines the functionality of readv() and pread(). As readv(), it will
8228transfer data into each buffer until it is full and then move on to the next
8229buffer in the sequence to hold the rest of the data. Its fourth argument,
8230specifies the file offset at which the input operation is to be performed. It
8231will return the total number of bytes read (which can be less than the total
8232capacity of all the objects).
8233
8234The flags argument contains a bitwise OR of zero or more of the following flags:
8235
8236- RWF_HIPRI
8237- RWF_NOWAIT
8238
8239Using non-zero flags requires Linux 4.6 or newer.
8240[clinic start generated code]*/
8241
8242static Py_ssize_t
8243os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8244 int flags)
8245/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8246{
8247 Py_ssize_t cnt, n;
8248 int async_err = 0;
8249 struct iovec *iov;
8250 Py_buffer *buf;
8251
8252 if (!PySequence_Check(buffers)) {
8253 PyErr_SetString(PyExc_TypeError,
8254 "preadv2() arg 2 must be a sequence");
8255 return -1;
8256 }
8257
8258 cnt = PySequence_Size(buffers);
8259 if (cnt < 0) {
8260 return -1;
8261 }
8262
8263#ifndef HAVE_PREADV2
8264 if(flags != 0) {
8265 argument_unavailable_error("preadv2", "flags");
8266 return -1;
8267 }
8268#endif
8269
8270 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8271 return -1;
8272 }
8273#ifdef HAVE_PREADV2
8274 do {
8275 Py_BEGIN_ALLOW_THREADS
8276 _Py_BEGIN_SUPPRESS_IPH
8277 n = preadv2(fd, iov, cnt, offset, flags);
8278 _Py_END_SUPPRESS_IPH
8279 Py_END_ALLOW_THREADS
8280 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8281#else
8282 do {
8283 Py_BEGIN_ALLOW_THREADS
8284 _Py_BEGIN_SUPPRESS_IPH
8285 n = preadv(fd, iov, cnt, offset);
8286 _Py_END_SUPPRESS_IPH
8287 Py_END_ALLOW_THREADS
8288 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8289#endif
8290
8291 iov_cleanup(iov, buf, cnt);
8292 if (n < 0) {
8293 if (!async_err) {
8294 posix_error();
8295 }
8296 return -1;
8297 }
8298
8299 return n;
8300}
8301#endif /* HAVE_PREADV */
8302
Larry Hastings2f936352014-08-05 14:04:04 +10008303
8304/*[clinic input]
8305os.write -> Py_ssize_t
8306
8307 fd: int
8308 data: Py_buffer
8309 /
8310
8311Write a bytes object to a file descriptor.
8312[clinic start generated code]*/
8313
Larry Hastings2f936352014-08-05 14:04:04 +10008314static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008315os_write_impl(PyObject *module, int fd, Py_buffer *data)
8316/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008317{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008318 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008319}
8320
8321#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008323"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008324sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008326Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008327
Larry Hastings2f936352014-08-05 14:04:04 +10008328/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008329static PyObject *
8330posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8331{
8332 int in, out;
8333 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008334 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335 off_t offset;
8336
8337#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8338#ifndef __APPLE__
8339 Py_ssize_t len;
8340#endif
8341 PyObject *headers = NULL, *trailers = NULL;
8342 Py_buffer *hbuf, *tbuf;
8343 off_t sbytes;
8344 struct sf_hdtr sf;
8345 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008346 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008347 static char *keywords[] = {"out", "in",
8348 "offset", "count",
8349 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008350
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008351 sf.headers = NULL;
8352 sf.trailers = NULL;
8353
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008354#ifdef __APPLE__
8355 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008356 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008357#else
8358 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008359 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008360#endif
8361 &headers, &trailers, &flags))
8362 return NULL;
8363 if (headers != NULL) {
8364 if (!PySequence_Check(headers)) {
8365 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008366 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008367 return NULL;
8368 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008369 Py_ssize_t i = PySequence_Size(headers);
8370 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008371 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008372 if (i > INT_MAX) {
8373 PyErr_SetString(PyExc_OverflowError,
8374 "sendfile() header is too large");
8375 return NULL;
8376 }
8377 if (i > 0) {
8378 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008379 if (iov_setup(&(sf.headers), &hbuf,
8380 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008381 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008382#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008383 for (i = 0; i < sf.hdr_cnt; i++) {
8384 Py_ssize_t blen = sf.headers[i].iov_len;
8385# define OFF_T_MAX 0x7fffffffffffffff
8386 if (sbytes >= OFF_T_MAX - blen) {
8387 PyErr_SetString(PyExc_OverflowError,
8388 "sendfile() header is too large");
8389 return NULL;
8390 }
8391 sbytes += blen;
8392 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008393#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008394 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008395 }
8396 }
8397 if (trailers != NULL) {
8398 if (!PySequence_Check(trailers)) {
8399 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008400 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008401 return NULL;
8402 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008403 Py_ssize_t i = PySequence_Size(trailers);
8404 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008405 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008406 if (i > INT_MAX) {
8407 PyErr_SetString(PyExc_OverflowError,
8408 "sendfile() trailer is too large");
8409 return NULL;
8410 }
8411 if (i > 0) {
8412 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008413 if (iov_setup(&(sf.trailers), &tbuf,
8414 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008415 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008416 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008417 }
8418 }
8419
Steve Dower8fc89802015-04-12 00:26:27 -04008420 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008421 do {
8422 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008423#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008424 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008425#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008426 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008427#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008428 Py_END_ALLOW_THREADS
8429 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008430 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008431
8432 if (sf.headers != NULL)
8433 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8434 if (sf.trailers != NULL)
8435 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8436
8437 if (ret < 0) {
8438 if ((errno == EAGAIN) || (errno == EBUSY)) {
8439 if (sbytes != 0) {
8440 // some data has been sent
8441 goto done;
8442 }
8443 else {
8444 // no data has been sent; upper application is supposed
8445 // to retry on EAGAIN or EBUSY
8446 return posix_error();
8447 }
8448 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008449 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008450 }
8451 goto done;
8452
8453done:
8454 #if !defined(HAVE_LARGEFILE_SUPPORT)
8455 return Py_BuildValue("l", sbytes);
8456 #else
8457 return Py_BuildValue("L", sbytes);
8458 #endif
8459
8460#else
8461 Py_ssize_t count;
8462 PyObject *offobj;
8463 static char *keywords[] = {"out", "in",
8464 "offset", "count", NULL};
8465 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8466 keywords, &out, &in, &offobj, &count))
8467 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008468#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008469 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008470 do {
8471 Py_BEGIN_ALLOW_THREADS
8472 ret = sendfile(out, in, NULL, count);
8473 Py_END_ALLOW_THREADS
8474 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008475 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008476 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008477 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008478 }
8479#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008480 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008481 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008482
8483 do {
8484 Py_BEGIN_ALLOW_THREADS
8485 ret = sendfile(out, in, &offset, count);
8486 Py_END_ALLOW_THREADS
8487 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008488 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008489 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008490 return Py_BuildValue("n", ret);
8491#endif
8492}
Larry Hastings2f936352014-08-05 14:04:04 +10008493#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008494
Larry Hastings2f936352014-08-05 14:04:04 +10008495
8496/*[clinic input]
8497os.fstat
8498
8499 fd : int
8500
8501Perform a stat system call on the given file descriptor.
8502
8503Like stat(), but for an open file descriptor.
8504Equivalent to os.stat(fd).
8505[clinic start generated code]*/
8506
Larry Hastings2f936352014-08-05 14:04:04 +10008507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008508os_fstat_impl(PyObject *module, int fd)
8509/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008510{
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 STRUCT_STAT st;
8512 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008513 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008514
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008515 do {
8516 Py_BEGIN_ALLOW_THREADS
8517 res = FSTAT(fd, &st);
8518 Py_END_ALLOW_THREADS
8519 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008521#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008522 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008523#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008524 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008525#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 }
Tim Peters5aa91602002-01-30 05:46:57 +00008527
Victor Stinner4195b5c2012-02-08 23:03:19 +01008528 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008529}
8530
Larry Hastings2f936352014-08-05 14:04:04 +10008531
8532/*[clinic input]
8533os.isatty -> bool
8534 fd: int
8535 /
8536
8537Return True if the fd is connected to a terminal.
8538
8539Return True if the file descriptor is an open file descriptor
8540connected to the slave end of a terminal.
8541[clinic start generated code]*/
8542
Larry Hastings2f936352014-08-05 14:04:04 +10008543static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008544os_isatty_impl(PyObject *module, int fd)
8545/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008546{
Steve Dower8fc89802015-04-12 00:26:27 -04008547 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008548 _Py_BEGIN_SUPPRESS_IPH
8549 return_value = isatty(fd);
8550 _Py_END_SUPPRESS_IPH
8551 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008552}
8553
8554
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008555#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008556/*[clinic input]
8557os.pipe
8558
8559Create a pipe.
8560
8561Returns a tuple of two file descriptors:
8562 (read_fd, write_fd)
8563[clinic start generated code]*/
8564
Larry Hastings2f936352014-08-05 14:04:04 +10008565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008566os_pipe_impl(PyObject *module)
8567/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008568{
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008570#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008572 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008574#else
8575 int res;
8576#endif
8577
8578#ifdef MS_WINDOWS
8579 attr.nLength = sizeof(attr);
8580 attr.lpSecurityDescriptor = NULL;
8581 attr.bInheritHandle = FALSE;
8582
8583 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008584 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008585 ok = CreatePipe(&read, &write, &attr, 0);
8586 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008587 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8588 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008589 if (fds[0] == -1 || fds[1] == -1) {
8590 CloseHandle(read);
8591 CloseHandle(write);
8592 ok = 0;
8593 }
8594 }
Steve Dowerc3630612016-11-19 18:41:16 -08008595 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008596 Py_END_ALLOW_THREADS
8597
Victor Stinner8c62be82010-05-06 00:08:46 +00008598 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008599 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008600#else
8601
8602#ifdef HAVE_PIPE2
8603 Py_BEGIN_ALLOW_THREADS
8604 res = pipe2(fds, O_CLOEXEC);
8605 Py_END_ALLOW_THREADS
8606
8607 if (res != 0 && errno == ENOSYS)
8608 {
8609#endif
8610 Py_BEGIN_ALLOW_THREADS
8611 res = pipe(fds);
8612 Py_END_ALLOW_THREADS
8613
8614 if (res == 0) {
8615 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8616 close(fds[0]);
8617 close(fds[1]);
8618 return NULL;
8619 }
8620 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8621 close(fds[0]);
8622 close(fds[1]);
8623 return NULL;
8624 }
8625 }
8626#ifdef HAVE_PIPE2
8627 }
8628#endif
8629
8630 if (res != 0)
8631 return PyErr_SetFromErrno(PyExc_OSError);
8632#endif /* !MS_WINDOWS */
8633 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008634}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008635#endif /* HAVE_PIPE */
8636
Larry Hastings2f936352014-08-05 14:04:04 +10008637
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008638#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008639/*[clinic input]
8640os.pipe2
8641
8642 flags: int
8643 /
8644
8645Create a pipe with flags set atomically.
8646
8647Returns a tuple of two file descriptors:
8648 (read_fd, write_fd)
8649
8650flags can be constructed by ORing together one or more of these values:
8651O_NONBLOCK, O_CLOEXEC.
8652[clinic start generated code]*/
8653
Larry Hastings2f936352014-08-05 14:04:04 +10008654static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008655os_pipe2_impl(PyObject *module, int flags)
8656/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008657{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008658 int fds[2];
8659 int res;
8660
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008661 res = pipe2(fds, flags);
8662 if (res != 0)
8663 return posix_error();
8664 return Py_BuildValue("(ii)", fds[0], fds[1]);
8665}
8666#endif /* HAVE_PIPE2 */
8667
Larry Hastings2f936352014-08-05 14:04:04 +10008668
Ross Lagerwall7807c352011-03-17 20:20:30 +02008669#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008670/*[clinic input]
8671os.writev -> Py_ssize_t
8672 fd: int
8673 buffers: object
8674 /
8675
8676Iterate over buffers, and write the contents of each to a file descriptor.
8677
8678Returns the total number of bytes written.
8679buffers must be a sequence of bytes-like objects.
8680[clinic start generated code]*/
8681
Larry Hastings2f936352014-08-05 14:04:04 +10008682static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008683os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8684/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008685{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008686 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008687 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008688 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008689 struct iovec *iov;
8690 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008691
8692 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008693 PyErr_SetString(PyExc_TypeError,
8694 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008695 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696 }
Larry Hastings2f936352014-08-05 14:04:04 +10008697 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008698 if (cnt < 0)
8699 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008700
Larry Hastings2f936352014-08-05 14:04:04 +10008701 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8702 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008703 }
8704
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008705 do {
8706 Py_BEGIN_ALLOW_THREADS
8707 result = writev(fd, iov, cnt);
8708 Py_END_ALLOW_THREADS
8709 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008710
8711 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008712 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008713 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008714
Georg Brandl306336b2012-06-24 12:55:33 +02008715 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008716}
Larry Hastings2f936352014-08-05 14:04:04 +10008717#endif /* HAVE_WRITEV */
8718
8719
8720#ifdef HAVE_PWRITE
8721/*[clinic input]
8722os.pwrite -> Py_ssize_t
8723
8724 fd: int
8725 buffer: Py_buffer
8726 offset: Py_off_t
8727 /
8728
8729Write bytes to a file descriptor starting at a particular offset.
8730
8731Write buffer to fd, starting at offset bytes from the beginning of
8732the file. Returns the number of bytes writte. Does not change the
8733current file offset.
8734[clinic start generated code]*/
8735
Larry Hastings2f936352014-08-05 14:04:04 +10008736static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008737os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8738/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008739{
8740 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008741 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008742
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008743 do {
8744 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008745 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008746 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008747 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008748 Py_END_ALLOW_THREADS
8749 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008750
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008751 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008752 posix_error();
8753 return size;
8754}
8755#endif /* HAVE_PWRITE */
8756
Pablo Galindo4defba32018-01-27 16:16:37 +00008757#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8758/*[clinic input]
8759os.pwritev -> Py_ssize_t
8760
8761 fd: int
8762 buffers: object
8763 offset: Py_off_t
8764 flags: int = 0
8765 /
8766
8767Writes the contents of bytes-like objects to a file descriptor at a given offset.
8768
8769Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8770of bytes-like objects. Buffers are processed in array order. Entire contents of first
8771buffer is written before proceeding to second, and so on. The operating system may
8772set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8773This function writes the contents of each object to the file descriptor and returns
8774the total number of bytes written.
8775
8776The flags argument contains a bitwise OR of zero or more of the following flags:
8777
8778- RWF_DSYNC
8779- RWF_SYNC
8780
8781Using non-zero flags requires Linux 4.7 or newer.
8782[clinic start generated code]*/
8783
8784static Py_ssize_t
8785os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8786 int flags)
8787/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8788{
8789 Py_ssize_t cnt;
8790 Py_ssize_t result;
8791 int async_err = 0;
8792 struct iovec *iov;
8793 Py_buffer *buf;
8794
8795 if (!PySequence_Check(buffers)) {
8796 PyErr_SetString(PyExc_TypeError,
8797 "pwritev() arg 2 must be a sequence");
8798 return -1;
8799 }
8800
8801 cnt = PySequence_Size(buffers);
8802 if (cnt < 0) {
8803 return -1;
8804 }
8805
8806#ifndef HAVE_PWRITEV2
8807 if(flags != 0) {
8808 argument_unavailable_error("pwritev2", "flags");
8809 return -1;
8810 }
8811#endif
8812
8813 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8814 return -1;
8815 }
8816#ifdef HAVE_PWRITEV2
8817 do {
8818 Py_BEGIN_ALLOW_THREADS
8819 _Py_BEGIN_SUPPRESS_IPH
8820 result = pwritev2(fd, iov, cnt, offset, flags);
8821 _Py_END_SUPPRESS_IPH
8822 Py_END_ALLOW_THREADS
8823 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8824#else
8825 do {
8826 Py_BEGIN_ALLOW_THREADS
8827 _Py_BEGIN_SUPPRESS_IPH
8828 result = pwritev(fd, iov, cnt, offset);
8829 _Py_END_SUPPRESS_IPH
8830 Py_END_ALLOW_THREADS
8831 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8832#endif
8833
8834 iov_cleanup(iov, buf, cnt);
8835 if (result < 0) {
8836 if (!async_err) {
8837 posix_error();
8838 }
8839 return -1;
8840 }
8841
8842 return result;
8843}
8844#endif /* HAVE_PWRITEV */
8845
8846
8847
Larry Hastings2f936352014-08-05 14:04:04 +10008848
8849#ifdef HAVE_MKFIFO
8850/*[clinic input]
8851os.mkfifo
8852
8853 path: path_t
8854 mode: int=0o666
8855 *
8856 dir_fd: dir_fd(requires='mkfifoat')=None
8857
8858Create a "fifo" (a POSIX named pipe).
8859
8860If dir_fd is not None, it should be a file descriptor open to a directory,
8861 and path should be relative; path will then be relative to that directory.
8862dir_fd may not be implemented on your platform.
8863 If it is unavailable, using it will raise a NotImplementedError.
8864[clinic start generated code]*/
8865
Larry Hastings2f936352014-08-05 14:04:04 +10008866static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008867os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8868/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008869{
8870 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008871 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008872
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008873 do {
8874 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008875#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008876 if (dir_fd != DEFAULT_DIR_FD)
8877 result = mkfifoat(dir_fd, path->narrow, mode);
8878 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008879#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008880 result = mkfifo(path->narrow, mode);
8881 Py_END_ALLOW_THREADS
8882 } while (result != 0 && errno == EINTR &&
8883 !(async_err = PyErr_CheckSignals()));
8884 if (result != 0)
8885 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008886
8887 Py_RETURN_NONE;
8888}
8889#endif /* HAVE_MKFIFO */
8890
8891
8892#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8893/*[clinic input]
8894os.mknod
8895
8896 path: path_t
8897 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008898 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008899 *
8900 dir_fd: dir_fd(requires='mknodat')=None
8901
8902Create a node in the file system.
8903
8904Create a node in the file system (file, device special file or named pipe)
8905at path. mode specifies both the permissions to use and the
8906type of node to be created, being combined (bitwise OR) with one of
8907S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8908device defines the newly created device special file (probably using
8909os.makedev()). Otherwise device is ignored.
8910
8911If dir_fd is not None, it should be a file descriptor open to a directory,
8912 and path should be relative; path will then be relative to that directory.
8913dir_fd may not be implemented on your platform.
8914 If it is unavailable, using it will raise a NotImplementedError.
8915[clinic start generated code]*/
8916
Larry Hastings2f936352014-08-05 14:04:04 +10008917static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008918os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008919 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008920/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008921{
8922 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008923 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008924
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008925 do {
8926 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008927#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008928 if (dir_fd != DEFAULT_DIR_FD)
8929 result = mknodat(dir_fd, path->narrow, mode, device);
8930 else
Larry Hastings2f936352014-08-05 14:04:04 +10008931#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008932 result = mknod(path->narrow, mode, device);
8933 Py_END_ALLOW_THREADS
8934 } while (result != 0 && errno == EINTR &&
8935 !(async_err = PyErr_CheckSignals()));
8936 if (result != 0)
8937 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008938
8939 Py_RETURN_NONE;
8940}
8941#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8942
8943
8944#ifdef HAVE_DEVICE_MACROS
8945/*[clinic input]
8946os.major -> unsigned_int
8947
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008948 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008949 /
8950
8951Extracts a device major number from a raw device number.
8952[clinic start generated code]*/
8953
Larry Hastings2f936352014-08-05 14:04:04 +10008954static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008955os_major_impl(PyObject *module, dev_t device)
8956/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008957{
8958 return major(device);
8959}
8960
8961
8962/*[clinic input]
8963os.minor -> unsigned_int
8964
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008965 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008966 /
8967
8968Extracts a device minor number from a raw device number.
8969[clinic start generated code]*/
8970
Larry Hastings2f936352014-08-05 14:04:04 +10008971static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008972os_minor_impl(PyObject *module, dev_t device)
8973/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008974{
8975 return minor(device);
8976}
8977
8978
8979/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008980os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008981
8982 major: int
8983 minor: int
8984 /
8985
8986Composes a raw device number from the major and minor device numbers.
8987[clinic start generated code]*/
8988
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008989static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008990os_makedev_impl(PyObject *module, int major, int minor)
8991/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008992{
8993 return makedev(major, minor);
8994}
8995#endif /* HAVE_DEVICE_MACROS */
8996
8997
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008998#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008999/*[clinic input]
9000os.ftruncate
9001
9002 fd: int
9003 length: Py_off_t
9004 /
9005
9006Truncate a file, specified by file descriptor, to a specific length.
9007[clinic start generated code]*/
9008
Larry Hastings2f936352014-08-05 14:04:04 +10009009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009010os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9011/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009012{
9013 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009014 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009015
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009016 do {
9017 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009018 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009019#ifdef MS_WINDOWS
9020 result = _chsize_s(fd, length);
9021#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009022 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009023#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009024 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009025 Py_END_ALLOW_THREADS
9026 } while (result != 0 && errno == EINTR &&
9027 !(async_err = PyErr_CheckSignals()));
9028 if (result != 0)
9029 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009030 Py_RETURN_NONE;
9031}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009032#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009033
9034
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009035#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009036/*[clinic input]
9037os.truncate
9038 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9039 length: Py_off_t
9040
9041Truncate a file, specified by path, to a specific length.
9042
9043On some platforms, path may also be specified as an open file descriptor.
9044 If this functionality is unavailable, using it raises an exception.
9045[clinic start generated code]*/
9046
Larry Hastings2f936352014-08-05 14:04:04 +10009047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009048os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9049/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009050{
9051 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009052#ifdef MS_WINDOWS
9053 int fd;
9054#endif
9055
9056 if (path->fd != -1)
9057 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009058
9059 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009060 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009061#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009062 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009063 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009064 result = -1;
9065 else {
9066 result = _chsize_s(fd, length);
9067 close(fd);
9068 if (result < 0)
9069 errno = result;
9070 }
9071#else
9072 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009073#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009074 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009075 Py_END_ALLOW_THREADS
9076 if (result < 0)
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07009077 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009078
9079 Py_RETURN_NONE;
9080}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009081#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009082
Ross Lagerwall7807c352011-03-17 20:20:30 +02009083
Victor Stinnerd6b17692014-09-30 12:20:05 +02009084/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9085 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9086 defined, which is the case in Python on AIX. AIX bug report:
9087 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9088#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9089# define POSIX_FADVISE_AIX_BUG
9090#endif
9091
Victor Stinnerec39e262014-09-30 12:35:58 +02009092
Victor Stinnerd6b17692014-09-30 12:20:05 +02009093#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009094/*[clinic input]
9095os.posix_fallocate
9096
9097 fd: int
9098 offset: Py_off_t
9099 length: Py_off_t
9100 /
9101
9102Ensure a file has allocated at least a particular number of bytes on disk.
9103
9104Ensure that the file specified by fd encompasses a range of bytes
9105starting at offset bytes from the beginning and continuing for length bytes.
9106[clinic start generated code]*/
9107
Larry Hastings2f936352014-08-05 14:04:04 +10009108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009109os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009110 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009111/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009112{
9113 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009114 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009115
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009116 do {
9117 Py_BEGIN_ALLOW_THREADS
9118 result = posix_fallocate(fd, offset, length);
9119 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009120 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9121
9122 if (result == 0)
9123 Py_RETURN_NONE;
9124
9125 if (async_err)
9126 return NULL;
9127
9128 errno = result;
9129 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009130}
Victor Stinnerec39e262014-09-30 12:35:58 +02009131#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009132
Ross Lagerwall7807c352011-03-17 20:20:30 +02009133
Victor Stinnerd6b17692014-09-30 12:20:05 +02009134#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009135/*[clinic input]
9136os.posix_fadvise
9137
9138 fd: int
9139 offset: Py_off_t
9140 length: Py_off_t
9141 advice: int
9142 /
9143
9144Announce an intention to access data in a specific pattern.
9145
9146Announce an intention to access data in a specific pattern, thus allowing
9147the kernel to make optimizations.
9148The advice applies to the region of the file specified by fd starting at
9149offset and continuing for length bytes.
9150advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9151POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9152POSIX_FADV_DONTNEED.
9153[clinic start generated code]*/
9154
Larry Hastings2f936352014-08-05 14:04:04 +10009155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009156os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009157 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009158/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009159{
9160 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009161 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009162
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009163 do {
9164 Py_BEGIN_ALLOW_THREADS
9165 result = posix_fadvise(fd, offset, length, advice);
9166 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009167 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9168
9169 if (result == 0)
9170 Py_RETURN_NONE;
9171
9172 if (async_err)
9173 return NULL;
9174
9175 errno = result;
9176 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009177}
Victor Stinnerec39e262014-09-30 12:35:58 +02009178#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009179
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009180#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009181
Fred Drake762e2061999-08-26 17:23:54 +00009182/* Save putenv() parameters as values here, so we can collect them when they
9183 * get re-set with another call for the same key. */
9184static PyObject *posix_putenv_garbage;
9185
Larry Hastings2f936352014-08-05 14:04:04 +10009186static void
9187posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009188{
Larry Hastings2f936352014-08-05 14:04:04 +10009189 /* Install the first arg and newstr in posix_putenv_garbage;
9190 * this will cause previous value to be collected. This has to
9191 * happen after the real putenv() call because the old value
9192 * was still accessible until then. */
9193 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9194 /* really not much we can do; just leak */
9195 PyErr_Clear();
9196 else
9197 Py_DECREF(value);
9198}
9199
9200
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009201#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009202/*[clinic input]
9203os.putenv
9204
9205 name: unicode
9206 value: unicode
9207 /
9208
9209Change or add an environment variable.
9210[clinic start generated code]*/
9211
Larry Hastings2f936352014-08-05 14:04:04 +10009212static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009213os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9214/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009215{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009216 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009217 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009218
Serhiy Storchaka77703942017-06-25 07:33:01 +03009219 /* Search from index 1 because on Windows starting '=' is allowed for
9220 defining hidden environment variables. */
9221 if (PyUnicode_GET_LENGTH(name) == 0 ||
9222 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9223 {
9224 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9225 return NULL;
9226 }
Larry Hastings2f936352014-08-05 14:04:04 +10009227 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9228 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009229 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009230 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009231
9232 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9233 if (env == NULL)
9234 goto error;
9235 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009236 PyErr_Format(PyExc_ValueError,
9237 "the environment variable is longer than %u characters",
9238 _MAX_ENV);
9239 goto error;
9240 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009241 if (wcslen(env) != (size_t)size) {
9242 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009243 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009244 }
9245
Larry Hastings2f936352014-08-05 14:04:04 +10009246 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009248 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009250
Larry Hastings2f936352014-08-05 14:04:04 +10009251 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009252 Py_RETURN_NONE;
9253
9254error:
Larry Hastings2f936352014-08-05 14:04:04 +10009255 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009256 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009257}
Larry Hastings2f936352014-08-05 14:04:04 +10009258#else /* MS_WINDOWS */
9259/*[clinic input]
9260os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009261
Larry Hastings2f936352014-08-05 14:04:04 +10009262 name: FSConverter
9263 value: FSConverter
9264 /
9265
9266Change or add an environment variable.
9267[clinic start generated code]*/
9268
Larry Hastings2f936352014-08-05 14:04:04 +10009269static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009270os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9271/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009272{
9273 PyObject *bytes = NULL;
9274 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009275 const char *name_string = PyBytes_AS_STRING(name);
9276 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009277
Serhiy Storchaka77703942017-06-25 07:33:01 +03009278 if (strchr(name_string, '=') != NULL) {
9279 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9280 return NULL;
9281 }
Larry Hastings2f936352014-08-05 14:04:04 +10009282 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9283 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009284 return NULL;
9285 }
9286
9287 env = PyBytes_AS_STRING(bytes);
9288 if (putenv(env)) {
9289 Py_DECREF(bytes);
9290 return posix_error();
9291 }
9292
9293 posix_putenv_garbage_setitem(name, bytes);
9294 Py_RETURN_NONE;
9295}
9296#endif /* MS_WINDOWS */
9297#endif /* HAVE_PUTENV */
9298
9299
9300#ifdef HAVE_UNSETENV
9301/*[clinic input]
9302os.unsetenv
9303 name: FSConverter
9304 /
9305
9306Delete an environment variable.
9307[clinic start generated code]*/
9308
Larry Hastings2f936352014-08-05 14:04:04 +10009309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009310os_unsetenv_impl(PyObject *module, PyObject *name)
9311/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009312{
Victor Stinner984890f2011-11-24 13:53:38 +01009313#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009314 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009315#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009316
Victor Stinner984890f2011-11-24 13:53:38 +01009317#ifdef HAVE_BROKEN_UNSETENV
9318 unsetenv(PyBytes_AS_STRING(name));
9319#else
Victor Stinner65170952011-11-22 22:16:17 +01009320 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009321 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009322 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009323#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009324
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 /* Remove the key from posix_putenv_garbage;
9326 * this will cause it to be collected. This has to
9327 * happen after the real unsetenv() call because the
9328 * old value was still accessible until then.
9329 */
Victor Stinner65170952011-11-22 22:16:17 +01009330 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 /* really not much we can do; just leak */
9332 PyErr_Clear();
9333 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009334 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009335}
Larry Hastings2f936352014-08-05 14:04:04 +10009336#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009337
Larry Hastings2f936352014-08-05 14:04:04 +10009338
9339/*[clinic input]
9340os.strerror
9341
9342 code: int
9343 /
9344
9345Translate an error code to a message string.
9346[clinic start generated code]*/
9347
Larry Hastings2f936352014-08-05 14:04:04 +10009348static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009349os_strerror_impl(PyObject *module, int code)
9350/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009351{
9352 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 if (message == NULL) {
9354 PyErr_SetString(PyExc_ValueError,
9355 "strerror() argument out of range");
9356 return NULL;
9357 }
Victor Stinner1b579672011-12-17 05:47:23 +01009358 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009359}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009360
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009361
Guido van Rossumc9641791998-08-04 15:26:23 +00009362#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009363#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009364/*[clinic input]
9365os.WCOREDUMP -> bool
9366
9367 status: int
9368 /
9369
9370Return True if the process returning status was dumped to a core file.
9371[clinic start generated code]*/
9372
Larry Hastings2f936352014-08-05 14:04:04 +10009373static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009374os_WCOREDUMP_impl(PyObject *module, int status)
9375/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009376{
9377 WAIT_TYPE wait_status;
9378 WAIT_STATUS_INT(wait_status) = status;
9379 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009380}
9381#endif /* WCOREDUMP */
9382
Larry Hastings2f936352014-08-05 14:04:04 +10009383
Fred Drake106c1a02002-04-23 15:58:02 +00009384#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009385/*[clinic input]
9386os.WIFCONTINUED -> bool
9387
9388 status: int
9389
9390Return True if a particular process was continued from a job control stop.
9391
9392Return True if the process returning status was continued from a
9393job control stop.
9394[clinic start generated code]*/
9395
Larry Hastings2f936352014-08-05 14:04:04 +10009396static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009397os_WIFCONTINUED_impl(PyObject *module, int status)
9398/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009399{
9400 WAIT_TYPE wait_status;
9401 WAIT_STATUS_INT(wait_status) = status;
9402 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009403}
9404#endif /* WIFCONTINUED */
9405
Larry Hastings2f936352014-08-05 14:04:04 +10009406
Guido van Rossumc9641791998-08-04 15:26:23 +00009407#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009408/*[clinic input]
9409os.WIFSTOPPED -> bool
9410
9411 status: int
9412
9413Return True if the process returning status was stopped.
9414[clinic start generated code]*/
9415
Larry Hastings2f936352014-08-05 14:04:04 +10009416static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009417os_WIFSTOPPED_impl(PyObject *module, int status)
9418/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009419{
9420 WAIT_TYPE wait_status;
9421 WAIT_STATUS_INT(wait_status) = status;
9422 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009423}
9424#endif /* WIFSTOPPED */
9425
Larry Hastings2f936352014-08-05 14:04:04 +10009426
Guido van Rossumc9641791998-08-04 15:26:23 +00009427#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009428/*[clinic input]
9429os.WIFSIGNALED -> bool
9430
9431 status: int
9432
9433Return True if the process returning status was terminated by a signal.
9434[clinic start generated code]*/
9435
Larry Hastings2f936352014-08-05 14:04:04 +10009436static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009437os_WIFSIGNALED_impl(PyObject *module, int status)
9438/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009439{
9440 WAIT_TYPE wait_status;
9441 WAIT_STATUS_INT(wait_status) = status;
9442 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009443}
9444#endif /* WIFSIGNALED */
9445
Larry Hastings2f936352014-08-05 14:04:04 +10009446
Guido van Rossumc9641791998-08-04 15:26:23 +00009447#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009448/*[clinic input]
9449os.WIFEXITED -> bool
9450
9451 status: int
9452
9453Return True if the process returning status exited via the exit() system call.
9454[clinic start generated code]*/
9455
Larry Hastings2f936352014-08-05 14:04:04 +10009456static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009457os_WIFEXITED_impl(PyObject *module, int status)
9458/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009459{
9460 WAIT_TYPE wait_status;
9461 WAIT_STATUS_INT(wait_status) = status;
9462 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009463}
9464#endif /* WIFEXITED */
9465
Larry Hastings2f936352014-08-05 14:04:04 +10009466
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009467#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009468/*[clinic input]
9469os.WEXITSTATUS -> int
9470
9471 status: int
9472
9473Return the process return code from status.
9474[clinic start generated code]*/
9475
Larry Hastings2f936352014-08-05 14:04:04 +10009476static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009477os_WEXITSTATUS_impl(PyObject *module, int status)
9478/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009479{
9480 WAIT_TYPE wait_status;
9481 WAIT_STATUS_INT(wait_status) = status;
9482 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009483}
9484#endif /* WEXITSTATUS */
9485
Larry Hastings2f936352014-08-05 14:04:04 +10009486
Guido van Rossumc9641791998-08-04 15:26:23 +00009487#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009488/*[clinic input]
9489os.WTERMSIG -> int
9490
9491 status: int
9492
9493Return the signal that terminated the process that provided the status value.
9494[clinic start generated code]*/
9495
Larry Hastings2f936352014-08-05 14:04:04 +10009496static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009497os_WTERMSIG_impl(PyObject *module, int status)
9498/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009499{
9500 WAIT_TYPE wait_status;
9501 WAIT_STATUS_INT(wait_status) = status;
9502 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009503}
9504#endif /* WTERMSIG */
9505
Larry Hastings2f936352014-08-05 14:04:04 +10009506
Guido van Rossumc9641791998-08-04 15:26:23 +00009507#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009508/*[clinic input]
9509os.WSTOPSIG -> int
9510
9511 status: int
9512
9513Return the signal that stopped the process that provided the status value.
9514[clinic start generated code]*/
9515
Larry Hastings2f936352014-08-05 14:04:04 +10009516static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009517os_WSTOPSIG_impl(PyObject *module, int status)
9518/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009519{
9520 WAIT_TYPE wait_status;
9521 WAIT_STATUS_INT(wait_status) = status;
9522 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009523}
9524#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009525#endif /* HAVE_SYS_WAIT_H */
9526
9527
Thomas Wouters477c8d52006-05-27 19:21:47 +00009528#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009529#ifdef _SCO_DS
9530/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9531 needed definitions in sys/statvfs.h */
9532#define _SVID3
9533#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009534#include <sys/statvfs.h>
9535
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009536static PyObject*
9537_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9539 if (v == NULL)
9540 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009541
9542#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9544 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9545 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9546 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9547 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9548 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9549 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9550 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9551 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9552 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009553#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9555 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9556 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009557 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009559 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009561 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009563 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009565 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009567 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9569 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009570#endif
Michael Felt502d5512018-01-05 13:01:58 +01009571/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9572 * (issue #32390). */
9573#if defined(_AIX) && defined(_ALL_SOURCE)
9574 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9575#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009576 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009577#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009578 if (PyErr_Occurred()) {
9579 Py_DECREF(v);
9580 return NULL;
9581 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009582
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009584}
9585
Larry Hastings2f936352014-08-05 14:04:04 +10009586
9587/*[clinic input]
9588os.fstatvfs
9589 fd: int
9590 /
9591
9592Perform an fstatvfs system call on the given fd.
9593
9594Equivalent to statvfs(fd).
9595[clinic start generated code]*/
9596
Larry Hastings2f936352014-08-05 14:04:04 +10009597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009598os_fstatvfs_impl(PyObject *module, int fd)
9599/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009600{
9601 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009602 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009604
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009605 do {
9606 Py_BEGIN_ALLOW_THREADS
9607 result = fstatvfs(fd, &st);
9608 Py_END_ALLOW_THREADS
9609 } while (result != 0 && errno == EINTR &&
9610 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009611 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009612 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009613
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009615}
Larry Hastings2f936352014-08-05 14:04:04 +10009616#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009617
9618
Thomas Wouters477c8d52006-05-27 19:21:47 +00009619#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009620#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009621/*[clinic input]
9622os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009623
Larry Hastings2f936352014-08-05 14:04:04 +10009624 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9625
9626Perform a statvfs system call on the given path.
9627
9628path may always be specified as a string.
9629On some platforms, path may also be specified as an open file descriptor.
9630 If this functionality is unavailable, using it raises an exception.
9631[clinic start generated code]*/
9632
Larry Hastings2f936352014-08-05 14:04:04 +10009633static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009634os_statvfs_impl(PyObject *module, path_t *path)
9635/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009636{
9637 int result;
9638 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009639
9640 Py_BEGIN_ALLOW_THREADS
9641#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009642 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009643#ifdef __APPLE__
9644 /* handle weak-linking on Mac OS X 10.3 */
9645 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009646 fd_specified("statvfs", path->fd);
9647 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009648 }
9649#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009650 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009651 }
9652 else
9653#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009654 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009655 Py_END_ALLOW_THREADS
9656
9657 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009658 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009659 }
9660
Larry Hastings2f936352014-08-05 14:04:04 +10009661 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009662}
Larry Hastings2f936352014-08-05 14:04:04 +10009663#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9664
Guido van Rossum94f6f721999-01-06 18:42:14 +00009665
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009666#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009667/*[clinic input]
9668os._getdiskusage
9669
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009670 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009671
9672Return disk usage statistics about the given path as a (total, free) tuple.
9673[clinic start generated code]*/
9674
Larry Hastings2f936352014-08-05 14:04:04 +10009675static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009676os__getdiskusage_impl(PyObject *module, path_t *path)
9677/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009678{
9679 BOOL retval;
9680 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009681
9682 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009683 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009684 Py_END_ALLOW_THREADS
9685 if (retval == 0)
9686 return PyErr_SetFromWindowsErr(0);
9687
9688 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9689}
Larry Hastings2f936352014-08-05 14:04:04 +10009690#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009691
9692
Fred Drakec9680921999-12-13 16:37:25 +00009693/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9694 * It maps strings representing configuration variable names to
9695 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009696 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009697 * rarely-used constants. There are three separate tables that use
9698 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009699 *
9700 * This code is always included, even if none of the interfaces that
9701 * need it are included. The #if hackery needed to avoid it would be
9702 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009703 */
9704struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009705 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009706 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009707};
9708
Fred Drake12c6e2d1999-12-14 21:25:03 +00009709static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009710conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009711 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009712{
Christian Heimes217cfd12007-12-02 14:31:20 +00009713 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009714 int value = _PyLong_AsInt(arg);
9715 if (value == -1 && PyErr_Occurred())
9716 return 0;
9717 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009718 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009719 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009720 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009721 /* look up the value in the table using a binary search */
9722 size_t lo = 0;
9723 size_t mid;
9724 size_t hi = tablesize;
9725 int cmp;
9726 const char *confname;
9727 if (!PyUnicode_Check(arg)) {
9728 PyErr_SetString(PyExc_TypeError,
9729 "configuration names must be strings or integers");
9730 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009732 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009733 if (confname == NULL)
9734 return 0;
9735 while (lo < hi) {
9736 mid = (lo + hi) / 2;
9737 cmp = strcmp(confname, table[mid].name);
9738 if (cmp < 0)
9739 hi = mid;
9740 else if (cmp > 0)
9741 lo = mid + 1;
9742 else {
9743 *valuep = table[mid].value;
9744 return 1;
9745 }
9746 }
9747 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9748 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009750}
9751
9752
9753#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9754static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009755#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
Fred Drakec9680921999-12-13 16:37:25 +00009761#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009806#ifdef _PC_ACL_ENABLED
9807 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9808#endif
9809#ifdef _PC_MIN_HOLE_SIZE
9810 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9811#endif
9812#ifdef _PC_ALLOC_SIZE_MIN
9813 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9814#endif
9815#ifdef _PC_REC_INCR_XFER_SIZE
9816 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9817#endif
9818#ifdef _PC_REC_MAX_XFER_SIZE
9819 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9820#endif
9821#ifdef _PC_REC_MIN_XFER_SIZE
9822 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9823#endif
9824#ifdef _PC_REC_XFER_ALIGN
9825 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9826#endif
9827#ifdef _PC_SYMLINK_MAX
9828 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9829#endif
9830#ifdef _PC_XATTR_ENABLED
9831 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9832#endif
9833#ifdef _PC_XATTR_EXISTS
9834 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9835#endif
9836#ifdef _PC_TIMESTAMP_RESOLUTION
9837 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9838#endif
Fred Drakec9680921999-12-13 16:37:25 +00009839};
9840
Fred Drakec9680921999-12-13 16:37:25 +00009841static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009842conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009843{
9844 return conv_confname(arg, valuep, posix_constants_pathconf,
9845 sizeof(posix_constants_pathconf)
9846 / sizeof(struct constdef));
9847}
9848#endif
9849
Larry Hastings2f936352014-08-05 14:04:04 +10009850
Fred Drakec9680921999-12-13 16:37:25 +00009851#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009852/*[clinic input]
9853os.fpathconf -> long
9854
9855 fd: int
9856 name: path_confname
9857 /
9858
9859Return the configuration limit name for the file descriptor fd.
9860
9861If there is no limit, return -1.
9862[clinic start generated code]*/
9863
Larry Hastings2f936352014-08-05 14:04:04 +10009864static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009865os_fpathconf_impl(PyObject *module, int fd, int name)
9866/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009867{
9868 long limit;
9869
9870 errno = 0;
9871 limit = fpathconf(fd, name);
9872 if (limit == -1 && errno != 0)
9873 posix_error();
9874
9875 return limit;
9876}
9877#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009878
9879
9880#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009881/*[clinic input]
9882os.pathconf -> long
9883 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9884 name: path_confname
9885
9886Return the configuration limit name for the file or directory path.
9887
9888If there is no limit, return -1.
9889On some platforms, path may also be specified as an open file descriptor.
9890 If this functionality is unavailable, using it raises an exception.
9891[clinic start generated code]*/
9892
Larry Hastings2f936352014-08-05 14:04:04 +10009893static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009894os_pathconf_impl(PyObject *module, path_t *path, int name)
9895/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009896{
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009898
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009900#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009901 if (path->fd != -1)
9902 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009903 else
9904#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009905 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 if (limit == -1 && errno != 0) {
9907 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009908 /* could be a path or name problem */
9909 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009910 else
Larry Hastings2f936352014-08-05 14:04:04 +10009911 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 }
Larry Hastings2f936352014-08-05 14:04:04 +10009913
9914 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009915}
Larry Hastings2f936352014-08-05 14:04:04 +10009916#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009917
9918#ifdef HAVE_CONFSTR
9919static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009920#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009922#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009923#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009925#endif
9926#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009928#endif
Fred Draked86ed291999-12-15 15:34:33 +00009929#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009931#endif
9932#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009934#endif
9935#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009937#endif
9938#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009940#endif
Fred Drakec9680921999-12-13 16:37:25 +00009941#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
Fred Draked86ed291999-12-15 15:34:33 +00009965#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009967#endif
Fred Drakec9680921999-12-13 16:37:25 +00009968#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
Fred Draked86ed291999-12-15 15:34:33 +00009971#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
9974#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009976#endif
9977#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009979#endif
9980#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009982#endif
Fred Drakec9680921999-12-13 16:37:25 +00009983#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
Fred Draked86ed291999-12-15 15:34:33 +000010031#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010033#endif
10034#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010036#endif
10037#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010039#endif
10040#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010042#endif
10043#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010045#endif
10046#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010048#endif
10049#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010051#endif
10052#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010054#endif
10055#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010057#endif
10058#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010060#endif
10061#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010063#endif
10064#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010066#endif
10067#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010069#endif
Fred Drakec9680921999-12-13 16:37:25 +000010070};
10071
10072static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010073conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010074{
10075 return conv_confname(arg, valuep, posix_constants_confstr,
10076 sizeof(posix_constants_confstr)
10077 / sizeof(struct constdef));
10078}
10079
Larry Hastings2f936352014-08-05 14:04:04 +100010080
10081/*[clinic input]
10082os.confstr
10083
10084 name: confstr_confname
10085 /
10086
10087Return a string-valued system configuration variable.
10088[clinic start generated code]*/
10089
Larry Hastings2f936352014-08-05 14:04:04 +100010090static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010091os_confstr_impl(PyObject *module, int name)
10092/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010093{
10094 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010095 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010096 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010097
Victor Stinnercb043522010-09-10 23:49:04 +000010098 errno = 0;
10099 len = confstr(name, buffer, sizeof(buffer));
10100 if (len == 0) {
10101 if (errno) {
10102 posix_error();
10103 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010104 }
10105 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010106 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010107 }
10108 }
Victor Stinnercb043522010-09-10 23:49:04 +000010109
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010110 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010111 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010112 char *buf = PyMem_Malloc(len);
10113 if (buf == NULL)
10114 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010115 len2 = confstr(name, buf, len);
10116 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010117 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010118 PyMem_Free(buf);
10119 }
10120 else
10121 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010122 return result;
10123}
Larry Hastings2f936352014-08-05 14:04:04 +100010124#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010125
10126
10127#ifdef HAVE_SYSCONF
10128static struct constdef posix_constants_sysconf[] = {
10129#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
Fred Draked86ed291999-12-15 15:34:33 +000010159#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010161#endif
10162#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010164#endif
Fred Drakec9680921999-12-13 16:37:25 +000010165#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
Fred Drakec9680921999-12-13 16:37:25 +000010168#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
Fred Draked86ed291999-12-15 15:34:33 +000010183#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010185#endif
Fred Drakec9680921999-12-13 16:37:25 +000010186#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
Fred Draked86ed291999-12-15 15:34:33 +000010201#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010203#endif
Fred Drakec9680921999-12-13 16:37:25 +000010204#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
Fred Draked86ed291999-12-15 15:34:33 +000010273#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010275#endif
Fred Drakec9680921999-12-13 16:37:25 +000010276#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
Fred Draked86ed291999-12-15 15:34:33 +000010285#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010287#endif
Fred Drakec9680921999-12-13 16:37:25 +000010288#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
Fred Draked86ed291999-12-15 15:34:33 +000010291#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010293#endif
10294#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010296#endif
Fred Drakec9680921999-12-13 16:37:25 +000010297#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
Fred Draked86ed291999-12-15 15:34:33 +000010309#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010311#endif
Fred Drakec9680921999-12-13 16:37:25 +000010312#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
Fred Draked86ed291999-12-15 15:34:33 +000010333#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010335#endif
Fred Drakec9680921999-12-13 16:37:25 +000010336#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
Fred Draked86ed291999-12-15 15:34:33 +000010342#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010344#endif
Fred Drakec9680921999-12-13 16:37:25 +000010345#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
Fred Draked86ed291999-12-15 15:34:33 +000010372#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010374#endif
10375#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010377#endif
Fred Drakec9680921999-12-13 16:37:25 +000010378#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010407#endif
10408#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
10411#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010413#endif
10414#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010416#endif
10417#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010419#endif
10420#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010422#endif
10423#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010425#endif
10426#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010428#endif
10429#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010431#endif
10432#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010434#endif
10435#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010437#endif
10438#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010440#endif
10441#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010443#endif
10444#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010446#endif
10447#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010449#endif
10450#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010452#endif
10453#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010455#endif
10456#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010458#endif
10459#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010461#endif
10462#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010464#endif
10465#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010467#endif
10468#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010470#endif
10471#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010473#endif
10474#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010476#endif
10477#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010479#endif
10480#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010481 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010482#endif
Fred Draked86ed291999-12-15 15:34:33 +000010483#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010485#endif
Fred Drakec9680921999-12-13 16:37:25 +000010486#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010488#endif
10489#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010491#endif
10492#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010494#endif
10495#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010496 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010497#endif
10498#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010500#endif
10501#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010503#endif
10504#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010505 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010506#endif
10507#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010509#endif
10510#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010511 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010512#endif
10513#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010515#endif
10516#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010517 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010518#endif
10519#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010521#endif
10522#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010524#endif
10525#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010527#endif
10528#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010530#endif
10531#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010533#endif
10534#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010536#endif
10537#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010539#endif
10540#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010542#endif
10543#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010545#endif
10546#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010548#endif
10549#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010550 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010551#endif
10552#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010554#endif
10555#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010557#endif
10558#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010560#endif
10561#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010563#endif
10564#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010566#endif
10567#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010569#endif
10570#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010572#endif
10573#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010575#endif
10576#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010578#endif
10579#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010581#endif
10582#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010584#endif
10585#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010587#endif
10588#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010590#endif
10591#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010593#endif
10594#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010596#endif
10597#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010599#endif
10600#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010602#endif
10603#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010605#endif
10606#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010608#endif
10609#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010611#endif
10612#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010614#endif
10615#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010617#endif
10618#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010620#endif
10621};
10622
10623static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010624conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010625{
10626 return conv_confname(arg, valuep, posix_constants_sysconf,
10627 sizeof(posix_constants_sysconf)
10628 / sizeof(struct constdef));
10629}
10630
Larry Hastings2f936352014-08-05 14:04:04 +100010631
10632/*[clinic input]
10633os.sysconf -> long
10634 name: sysconf_confname
10635 /
10636
10637Return an integer-valued system configuration variable.
10638[clinic start generated code]*/
10639
Larry Hastings2f936352014-08-05 14:04:04 +100010640static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010641os_sysconf_impl(PyObject *module, int name)
10642/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010643{
10644 long value;
10645
10646 errno = 0;
10647 value = sysconf(name);
10648 if (value == -1 && errno != 0)
10649 posix_error();
10650 return value;
10651}
10652#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010653
10654
Fred Drakebec628d1999-12-15 18:31:10 +000010655/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010656 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010657 * the exported dictionaries that are used to publish information about the
10658 * names available on the host platform.
10659 *
10660 * Sorting the table at runtime ensures that the table is properly ordered
10661 * when used, even for platforms we're not able to test on. It also makes
10662 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010663 */
Fred Drakebec628d1999-12-15 18:31:10 +000010664
10665static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010666cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010667{
10668 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010670 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010671 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010672
10673 return strcmp(c1->name, c2->name);
10674}
10675
10676static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010677setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010678 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010679{
Fred Drakebec628d1999-12-15 18:31:10 +000010680 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010681 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010682
10683 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10684 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010685 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010687
Barry Warsaw3155db32000-04-13 15:20:40 +000010688 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010689 PyObject *o = PyLong_FromLong(table[i].value);
10690 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10691 Py_XDECREF(o);
10692 Py_DECREF(d);
10693 return -1;
10694 }
10695 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010696 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010697 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010698}
10699
Fred Drakebec628d1999-12-15 18:31:10 +000010700/* Return -1 on failure, 0 on success. */
10701static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010702setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010703{
10704#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010705 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010706 sizeof(posix_constants_pathconf)
10707 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010708 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010709 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010710#endif
10711#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010712 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010713 sizeof(posix_constants_confstr)
10714 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010715 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010716 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010717#endif
10718#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010719 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010720 sizeof(posix_constants_sysconf)
10721 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010722 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010723 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010724#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010725 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010726}
Fred Draked86ed291999-12-15 15:34:33 +000010727
10728
Larry Hastings2f936352014-08-05 14:04:04 +100010729/*[clinic input]
10730os.abort
10731
10732Abort the interpreter immediately.
10733
10734This function 'dumps core' or otherwise fails in the hardest way possible
10735on the hosting operating system. This function never returns.
10736[clinic start generated code]*/
10737
Larry Hastings2f936352014-08-05 14:04:04 +100010738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010739os_abort_impl(PyObject *module)
10740/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010741{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010742 abort();
10743 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010744#ifndef __clang__
10745 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10746 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10747 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010748 Py_FatalError("abort() called from Python code didn't abort!");
10749 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010750#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010751}
Fred Drakebec628d1999-12-15 18:31:10 +000010752
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010753#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010754/* Grab ShellExecute dynamically from shell32 */
10755static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010756static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10757 LPCWSTR, INT);
10758static int
10759check_ShellExecute()
10760{
10761 HINSTANCE hShell32;
10762
10763 /* only recheck */
10764 if (-1 == has_ShellExecute) {
10765 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010766 /* Security note: this call is not vulnerable to "DLL hijacking".
10767 SHELL32 is part of "KnownDLLs" and so Windows always load
10768 the system SHELL32.DLL, even if there is another SHELL32.DLL
10769 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010770 hShell32 = LoadLibraryW(L"SHELL32");
10771 Py_END_ALLOW_THREADS
10772 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010773 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10774 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010775 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010776 } else {
10777 has_ShellExecute = 0;
10778 }
10779 }
10780 return has_ShellExecute;
10781}
10782
10783
Steve Dowercc16be82016-09-08 10:35:16 -070010784/*[clinic input]
10785os.startfile
10786 filepath: path_t
10787 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010788
Steve Dowercc16be82016-09-08 10:35:16 -070010789startfile(filepath [, operation])
10790
10791Start a file with its associated application.
10792
10793When "operation" is not specified or "open", this acts like
10794double-clicking the file in Explorer, or giving the file name as an
10795argument to the DOS "start" command: the file is opened with whatever
10796application (if any) its extension is associated.
10797When another "operation" is given, it specifies what should be done with
10798the file. A typical operation is "print".
10799
10800startfile returns as soon as the associated application is launched.
10801There is no option to wait for the application to close, and no way
10802to retrieve the application's exit status.
10803
10804The filepath is relative to the current directory. If you want to use
10805an absolute path, make sure the first character is not a slash ("/");
10806the underlying Win32 ShellExecute function doesn't work if it is.
10807[clinic start generated code]*/
10808
10809static PyObject *
Serhiy Storchaka45a7b762018-12-14 11:56:48 +020010810os_startfile_impl(PyObject *module, path_t *filepath,
10811 const Py_UNICODE *operation)
10812/*[clinic end generated code: output=66dc311c94d50797 input=63950bf2986380d0]*/
Steve Dowercc16be82016-09-08 10:35:16 -070010813{
10814 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010815
10816 if(!check_ShellExecute()) {
10817 /* If the OS doesn't have ShellExecute, return a
10818 NotImplementedError. */
10819 return PyErr_Format(PyExc_NotImplementedError,
10820 "startfile not available on this platform");
10821 }
10822
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010824 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010825 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 Py_END_ALLOW_THREADS
10827
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010829 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010830 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 }
Steve Dowercc16be82016-09-08 10:35:16 -070010832 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010833}
Larry Hastings2f936352014-08-05 14:04:04 +100010834#endif /* MS_WINDOWS */
10835
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010836
Martin v. Löwis438b5342002-12-27 10:16:42 +000010837#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010838/*[clinic input]
10839os.getloadavg
10840
10841Return average recent system load information.
10842
10843Return the number of processes in the system run queue averaged over
10844the last 1, 5, and 15 minutes as a tuple of three floats.
10845Raises OSError if the load average was unobtainable.
10846[clinic start generated code]*/
10847
Larry Hastings2f936352014-08-05 14:04:04 +100010848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010849os_getloadavg_impl(PyObject *module)
10850/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010851{
10852 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010853 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010854 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10855 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010856 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010857 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010858}
Larry Hastings2f936352014-08-05 14:04:04 +100010859#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010860
Larry Hastings2f936352014-08-05 14:04:04 +100010861
10862/*[clinic input]
10863os.device_encoding
10864 fd: int
10865
10866Return a string describing the encoding of a terminal's file descriptor.
10867
10868The file descriptor must be attached to a terminal.
10869If the device is not a terminal, return None.
10870[clinic start generated code]*/
10871
Larry Hastings2f936352014-08-05 14:04:04 +100010872static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010873os_device_encoding_impl(PyObject *module, int fd)
10874/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010875{
Brett Cannonefb00c02012-02-29 18:31:31 -050010876 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010877}
10878
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010879
Larry Hastings2f936352014-08-05 14:04:04 +100010880#ifdef HAVE_SETRESUID
10881/*[clinic input]
10882os.setresuid
10883
10884 ruid: uid_t
10885 euid: uid_t
10886 suid: uid_t
10887 /
10888
10889Set the current process's real, effective, and saved user ids.
10890[clinic start generated code]*/
10891
Larry Hastings2f936352014-08-05 14:04:04 +100010892static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010893os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10894/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010895{
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 if (setresuid(ruid, euid, suid) < 0)
10897 return posix_error();
10898 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010899}
Larry Hastings2f936352014-08-05 14:04:04 +100010900#endif /* HAVE_SETRESUID */
10901
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010902
10903#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010904/*[clinic input]
10905os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010906
Larry Hastings2f936352014-08-05 14:04:04 +100010907 rgid: gid_t
10908 egid: gid_t
10909 sgid: gid_t
10910 /
10911
10912Set the current process's real, effective, and saved group ids.
10913[clinic start generated code]*/
10914
Larry Hastings2f936352014-08-05 14:04:04 +100010915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010916os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10917/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010918{
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 if (setresgid(rgid, egid, sgid) < 0)
10920 return posix_error();
10921 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010922}
Larry Hastings2f936352014-08-05 14:04:04 +100010923#endif /* HAVE_SETRESGID */
10924
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010925
10926#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010927/*[clinic input]
10928os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010929
Larry Hastings2f936352014-08-05 14:04:04 +100010930Return a tuple of the current process's real, effective, and saved user ids.
10931[clinic start generated code]*/
10932
Larry Hastings2f936352014-08-05 14:04:04 +100010933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010934os_getresuid_impl(PyObject *module)
10935/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010936{
Victor Stinner8c62be82010-05-06 00:08:46 +000010937 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 if (getresuid(&ruid, &euid, &suid) < 0)
10939 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010940 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10941 _PyLong_FromUid(euid),
10942 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010943}
Larry Hastings2f936352014-08-05 14:04:04 +100010944#endif /* HAVE_GETRESUID */
10945
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010946
10947#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010948/*[clinic input]
10949os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010950
Larry Hastings2f936352014-08-05 14:04:04 +100010951Return a tuple of the current process's real, effective, and saved group ids.
10952[clinic start generated code]*/
10953
Larry Hastings2f936352014-08-05 14:04:04 +100010954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010955os_getresgid_impl(PyObject *module)
10956/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010957{
10958 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 if (getresgid(&rgid, &egid, &sgid) < 0)
10960 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010961 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10962 _PyLong_FromGid(egid),
10963 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010964}
Larry Hastings2f936352014-08-05 14:04:04 +100010965#endif /* HAVE_GETRESGID */
10966
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010967
Benjamin Peterson9428d532011-09-14 11:45:52 -040010968#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010969/*[clinic input]
10970os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010971
Larry Hastings2f936352014-08-05 14:04:04 +100010972 path: path_t(allow_fd=True)
10973 attribute: path_t
10974 *
10975 follow_symlinks: bool = True
10976
10977Return the value of extended attribute attribute on path.
10978
BNMetrics08026b12018-11-02 17:56:25 +000010979path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100010980If follow_symlinks is False, and the last element of the path is a symbolic
10981 link, getxattr will examine the symbolic link itself instead of the file
10982 the link points to.
10983
10984[clinic start generated code]*/
10985
Larry Hastings2f936352014-08-05 14:04:04 +100010986static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010987os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010988 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000010989/*[clinic end generated code: output=5f2f44200a43cff2 input=025789491708f7eb]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010990{
10991 Py_ssize_t i;
10992 PyObject *buffer = NULL;
10993
10994 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10995 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010996
Larry Hastings9cf065c2012-06-22 16:30:09 -070010997 for (i = 0; ; i++) {
10998 void *ptr;
10999 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011000 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070011001 Py_ssize_t buffer_size = buffer_sizes[i];
11002 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011003 path_error(path);
11004 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 }
11006 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11007 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011008 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011010
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011012 if (path->fd >= 0)
11013 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011014 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011015 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011016 else
Larry Hastings2f936352014-08-05 14:04:04 +100011017 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011018 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011019
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 if (result < 0) {
11021 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011022 if (errno == ERANGE)
11023 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011024 path_error(path);
11025 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011026 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011027
Larry Hastings9cf065c2012-06-22 16:30:09 -070011028 if (result != buffer_size) {
11029 /* Can only shrink. */
11030 _PyBytes_Resize(&buffer, result);
11031 }
11032 break;
11033 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011034
Larry Hastings9cf065c2012-06-22 16:30:09 -070011035 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011036}
11037
Larry Hastings2f936352014-08-05 14:04:04 +100011038
11039/*[clinic input]
11040os.setxattr
11041
11042 path: path_t(allow_fd=True)
11043 attribute: path_t
11044 value: Py_buffer
11045 flags: int = 0
11046 *
11047 follow_symlinks: bool = True
11048
11049Set extended attribute attribute on path to value.
11050
BNMetrics08026b12018-11-02 17:56:25 +000011051path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011052If follow_symlinks is False, and the last element of the path is a symbolic
11053 link, setxattr will modify the symbolic link itself instead of the file
11054 the link points to.
11055
11056[clinic start generated code]*/
11057
Benjamin Peterson799bd802011-08-31 22:15:17 -040011058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011059os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011060 Py_buffer *value, int flags, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011061/*[clinic end generated code: output=98b83f63fdde26bb input=c17c0103009042f0]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011062{
Larry Hastings2f936352014-08-05 14:04:04 +100011063 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011064
Larry Hastings2f936352014-08-05 14:04:04 +100011065 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011066 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011067
Benjamin Peterson799bd802011-08-31 22:15:17 -040011068 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011069 if (path->fd > -1)
11070 result = fsetxattr(path->fd, attribute->narrow,
11071 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011072 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011073 result = setxattr(path->narrow, attribute->narrow,
11074 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011075 else
Larry Hastings2f936352014-08-05 14:04:04 +100011076 result = lsetxattr(path->narrow, attribute->narrow,
11077 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011078 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011079
Larry Hastings9cf065c2012-06-22 16:30:09 -070011080 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011081 path_error(path);
11082 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011083 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011084
Larry Hastings2f936352014-08-05 14:04:04 +100011085 Py_RETURN_NONE;
11086}
11087
11088
11089/*[clinic input]
11090os.removexattr
11091
11092 path: path_t(allow_fd=True)
11093 attribute: path_t
11094 *
11095 follow_symlinks: bool = True
11096
11097Remove extended attribute attribute on path.
11098
BNMetrics08026b12018-11-02 17:56:25 +000011099path may be either a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011100If follow_symlinks is False, and the last element of the path is a symbolic
11101 link, removexattr will modify the symbolic link itself instead of the file
11102 the link points to.
11103
11104[clinic start generated code]*/
11105
Larry Hastings2f936352014-08-05 14:04:04 +100011106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011107os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011108 int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011109/*[clinic end generated code: output=521a51817980cda6 input=3d9a7d36fe2f7c4e]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011110{
11111 ssize_t result;
11112
11113 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11114 return NULL;
11115
11116 Py_BEGIN_ALLOW_THREADS;
11117 if (path->fd > -1)
11118 result = fremovexattr(path->fd, attribute->narrow);
11119 else if (follow_symlinks)
11120 result = removexattr(path->narrow, attribute->narrow);
11121 else
11122 result = lremovexattr(path->narrow, attribute->narrow);
11123 Py_END_ALLOW_THREADS;
11124
11125 if (result) {
11126 return path_error(path);
11127 }
11128
11129 Py_RETURN_NONE;
11130}
11131
11132
11133/*[clinic input]
11134os.listxattr
11135
11136 path: path_t(allow_fd=True, nullable=True) = None
11137 *
11138 follow_symlinks: bool = True
11139
11140Return a list of extended attributes on path.
11141
BNMetrics08026b12018-11-02 17:56:25 +000011142path may be either None, a string, a path-like object, or an open file descriptor.
Larry Hastings2f936352014-08-05 14:04:04 +100011143if path is None, listxattr will examine the current directory.
11144If follow_symlinks is False, and the last element of the path is a symbolic
11145 link, listxattr will examine the symbolic link itself instead of the file
11146 the link points to.
11147[clinic start generated code]*/
11148
Larry Hastings2f936352014-08-05 14:04:04 +100011149static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011150os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
BNMetrics08026b12018-11-02 17:56:25 +000011151/*[clinic end generated code: output=bebdb4e2ad0ce435 input=9826edf9fdb90869]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011152{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011153 Py_ssize_t i;
11154 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011155 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011156 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011157
Larry Hastings2f936352014-08-05 14:04:04 +100011158 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011159 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011160
Larry Hastings2f936352014-08-05 14:04:04 +100011161 name = path->narrow ? path->narrow : ".";
11162
Larry Hastings9cf065c2012-06-22 16:30:09 -070011163 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011164 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011165 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011166 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011167 Py_ssize_t buffer_size = buffer_sizes[i];
11168 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011169 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011170 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011171 break;
11172 }
11173 buffer = PyMem_MALLOC(buffer_size);
11174 if (!buffer) {
11175 PyErr_NoMemory();
11176 break;
11177 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011178
Larry Hastings9cf065c2012-06-22 16:30:09 -070011179 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011180 if (path->fd > -1)
11181 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011182 else if (follow_symlinks)
11183 length = listxattr(name, buffer, buffer_size);
11184 else
11185 length = llistxattr(name, buffer, buffer_size);
11186 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011187
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011189 if (errno == ERANGE) {
11190 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011191 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011192 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011193 }
Larry Hastings2f936352014-08-05 14:04:04 +100011194 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011195 break;
11196 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011197
Larry Hastings9cf065c2012-06-22 16:30:09 -070011198 result = PyList_New(0);
11199 if (!result) {
11200 goto exit;
11201 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011202
Larry Hastings9cf065c2012-06-22 16:30:09 -070011203 end = buffer + length;
11204 for (trace = start = buffer; trace != end; trace++) {
11205 if (!*trace) {
11206 int error;
11207 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11208 trace - start);
11209 if (!attribute) {
11210 Py_DECREF(result);
11211 result = NULL;
11212 goto exit;
11213 }
11214 error = PyList_Append(result, attribute);
11215 Py_DECREF(attribute);
11216 if (error) {
11217 Py_DECREF(result);
11218 result = NULL;
11219 goto exit;
11220 }
11221 start = trace + 1;
11222 }
11223 }
11224 break;
11225 }
11226exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011227 if (buffer)
11228 PyMem_FREE(buffer);
11229 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011230}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011231#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011232
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011233
Larry Hastings2f936352014-08-05 14:04:04 +100011234/*[clinic input]
11235os.urandom
11236
11237 size: Py_ssize_t
11238 /
11239
11240Return a bytes object containing random bytes suitable for cryptographic use.
11241[clinic start generated code]*/
11242
Larry Hastings2f936352014-08-05 14:04:04 +100011243static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011244os_urandom_impl(PyObject *module, Py_ssize_t size)
11245/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011246{
11247 PyObject *bytes;
11248 int result;
11249
Georg Brandl2fb477c2012-02-21 00:33:36 +010011250 if (size < 0)
11251 return PyErr_Format(PyExc_ValueError,
11252 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011253 bytes = PyBytes_FromStringAndSize(NULL, size);
11254 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011255 return NULL;
11256
Victor Stinnere66987e2016-09-06 16:33:52 -070011257 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011258 if (result == -1) {
11259 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011260 return NULL;
11261 }
Larry Hastings2f936352014-08-05 14:04:04 +100011262 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011263}
11264
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011265/* Terminal size querying */
11266
11267static PyTypeObject TerminalSizeType;
11268
11269PyDoc_STRVAR(TerminalSize_docstring,
11270 "A tuple of (columns, lines) for holding terminal window size");
11271
11272static PyStructSequence_Field TerminalSize_fields[] = {
11273 {"columns", "width of the terminal window in characters"},
11274 {"lines", "height of the terminal window in characters"},
11275 {NULL, NULL}
11276};
11277
11278static PyStructSequence_Desc TerminalSize_desc = {
11279 "os.terminal_size",
11280 TerminalSize_docstring,
11281 TerminalSize_fields,
11282 2,
11283};
11284
11285#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011286/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011287PyDoc_STRVAR(termsize__doc__,
11288 "Return the size of the terminal window as (columns, lines).\n" \
11289 "\n" \
11290 "The optional argument fd (default standard output) specifies\n" \
11291 "which file descriptor should be queried.\n" \
11292 "\n" \
11293 "If the file descriptor is not connected to a terminal, an OSError\n" \
11294 "is thrown.\n" \
11295 "\n" \
11296 "This function will only be defined if an implementation is\n" \
11297 "available for this system.\n" \
11298 "\n" \
11299 "shutil.get_terminal_size is the high-level function which should \n" \
11300 "normally be used, os.get_terminal_size is the low-level implementation.");
11301
11302static PyObject*
11303get_terminal_size(PyObject *self, PyObject *args)
11304{
11305 int columns, lines;
11306 PyObject *termsize;
11307
11308 int fd = fileno(stdout);
11309 /* Under some conditions stdout may not be connected and
11310 * fileno(stdout) may point to an invalid file descriptor. For example
11311 * GUI apps don't have valid standard streams by default.
11312 *
11313 * If this happens, and the optional fd argument is not present,
11314 * the ioctl below will fail returning EBADF. This is what we want.
11315 */
11316
11317 if (!PyArg_ParseTuple(args, "|i", &fd))
11318 return NULL;
11319
11320#ifdef TERMSIZE_USE_IOCTL
11321 {
11322 struct winsize w;
11323 if (ioctl(fd, TIOCGWINSZ, &w))
11324 return PyErr_SetFromErrno(PyExc_OSError);
11325 columns = w.ws_col;
11326 lines = w.ws_row;
11327 }
11328#endif /* TERMSIZE_USE_IOCTL */
11329
11330#ifdef TERMSIZE_USE_CONIO
11331 {
11332 DWORD nhandle;
11333 HANDLE handle;
11334 CONSOLE_SCREEN_BUFFER_INFO csbi;
11335 switch (fd) {
11336 case 0: nhandle = STD_INPUT_HANDLE;
11337 break;
11338 case 1: nhandle = STD_OUTPUT_HANDLE;
11339 break;
11340 case 2: nhandle = STD_ERROR_HANDLE;
11341 break;
11342 default:
11343 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11344 }
11345 handle = GetStdHandle(nhandle);
11346 if (handle == NULL)
11347 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11348 if (handle == INVALID_HANDLE_VALUE)
11349 return PyErr_SetFromWindowsErr(0);
11350
11351 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11352 return PyErr_SetFromWindowsErr(0);
11353
11354 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11355 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11356 }
11357#endif /* TERMSIZE_USE_CONIO */
11358
11359 termsize = PyStructSequence_New(&TerminalSizeType);
11360 if (termsize == NULL)
11361 return NULL;
11362 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11363 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11364 if (PyErr_Occurred()) {
11365 Py_DECREF(termsize);
11366 return NULL;
11367 }
11368 return termsize;
11369}
11370#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11371
Larry Hastings2f936352014-08-05 14:04:04 +100011372
11373/*[clinic input]
11374os.cpu_count
11375
Charles-François Natali80d62e62015-08-13 20:37:08 +010011376Return the number of CPUs in the system; return None if indeterminable.
11377
11378This number is not equivalent to the number of CPUs the current process can
11379use. The number of usable CPUs can be obtained with
11380``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011381[clinic start generated code]*/
11382
Larry Hastings2f936352014-08-05 14:04:04 +100011383static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011384os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011385/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011386{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011387 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011388#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011389 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11390 Need to fallback to Vista behavior if this call isn't present */
11391 HINSTANCE hKernel32;
11392 hKernel32 = GetModuleHandleW(L"KERNEL32");
11393
11394 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11395 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11396 "GetMaximumProcessorCount");
11397 if (_GetMaximumProcessorCount != NULL) {
11398 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11399 }
11400 else {
11401 SYSTEM_INFO sysinfo;
11402 GetSystemInfo(&sysinfo);
11403 ncpu = sysinfo.dwNumberOfProcessors;
11404 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011405#elif defined(__hpux)
11406 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11407#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11408 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011409#elif defined(__DragonFly__) || \
11410 defined(__OpenBSD__) || \
11411 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011412 defined(__NetBSD__) || \
11413 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011414 int mib[2];
11415 size_t len = sizeof(ncpu);
11416 mib[0] = CTL_HW;
11417 mib[1] = HW_NCPU;
11418 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11419 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011420#endif
11421 if (ncpu >= 1)
11422 return PyLong_FromLong(ncpu);
11423 else
11424 Py_RETURN_NONE;
11425}
11426
Victor Stinnerdaf45552013-08-28 00:53:59 +020011427
Larry Hastings2f936352014-08-05 14:04:04 +100011428/*[clinic input]
11429os.get_inheritable -> bool
11430
11431 fd: int
11432 /
11433
11434Get the close-on-exe flag of the specified file descriptor.
11435[clinic start generated code]*/
11436
Larry Hastings2f936352014-08-05 14:04:04 +100011437static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011438os_get_inheritable_impl(PyObject *module, int fd)
11439/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011440{
Steve Dower8fc89802015-04-12 00:26:27 -040011441 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011442 _Py_BEGIN_SUPPRESS_IPH
11443 return_value = _Py_get_inheritable(fd);
11444 _Py_END_SUPPRESS_IPH
11445 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011446}
11447
11448
11449/*[clinic input]
11450os.set_inheritable
11451 fd: int
11452 inheritable: int
11453 /
11454
11455Set the inheritable flag of the specified file descriptor.
11456[clinic start generated code]*/
11457
Larry Hastings2f936352014-08-05 14:04:04 +100011458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011459os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11460/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011461{
Steve Dower8fc89802015-04-12 00:26:27 -040011462 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011463
Steve Dower8fc89802015-04-12 00:26:27 -040011464 _Py_BEGIN_SUPPRESS_IPH
11465 result = _Py_set_inheritable(fd, inheritable, NULL);
11466 _Py_END_SUPPRESS_IPH
11467 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011468 return NULL;
11469 Py_RETURN_NONE;
11470}
11471
11472
11473#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011474/*[clinic input]
11475os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011476 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011477 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011478
Larry Hastings2f936352014-08-05 14:04:04 +100011479Get the close-on-exe flag of the specified file descriptor.
11480[clinic start generated code]*/
11481
Larry Hastings2f936352014-08-05 14:04:04 +100011482static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011483os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011484/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011485{
11486 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011487
11488 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11489 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011490 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011491 }
11492
Larry Hastings2f936352014-08-05 14:04:04 +100011493 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011494}
11495
Victor Stinnerdaf45552013-08-28 00:53:59 +020011496
Larry Hastings2f936352014-08-05 14:04:04 +100011497/*[clinic input]
11498os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011499 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011500 inheritable: bool
11501 /
11502
11503Set the inheritable flag of the specified handle.
11504[clinic start generated code]*/
11505
Larry Hastings2f936352014-08-05 14:04:04 +100011506static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011507os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011508 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011509/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011510{
11511 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011512 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11513 PyErr_SetFromWindowsErr(0);
11514 return NULL;
11515 }
11516 Py_RETURN_NONE;
11517}
Larry Hastings2f936352014-08-05 14:04:04 +100011518#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011519
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011520#ifndef MS_WINDOWS
11521PyDoc_STRVAR(get_blocking__doc__,
11522 "get_blocking(fd) -> bool\n" \
11523 "\n" \
11524 "Get the blocking mode of the file descriptor:\n" \
11525 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11526
11527static PyObject*
11528posix_get_blocking(PyObject *self, PyObject *args)
11529{
11530 int fd;
11531 int blocking;
11532
11533 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11534 return NULL;
11535
Steve Dower8fc89802015-04-12 00:26:27 -040011536 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011537 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011538 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011539 if (blocking < 0)
11540 return NULL;
11541 return PyBool_FromLong(blocking);
11542}
11543
11544PyDoc_STRVAR(set_blocking__doc__,
11545 "set_blocking(fd, blocking)\n" \
11546 "\n" \
11547 "Set the blocking mode of the specified file descriptor.\n" \
11548 "Set the O_NONBLOCK flag if blocking is False,\n" \
11549 "clear the O_NONBLOCK flag otherwise.");
11550
11551static PyObject*
11552posix_set_blocking(PyObject *self, PyObject *args)
11553{
Steve Dower8fc89802015-04-12 00:26:27 -040011554 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011555
11556 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11557 return NULL;
11558
Steve Dower8fc89802015-04-12 00:26:27 -040011559 _Py_BEGIN_SUPPRESS_IPH
11560 result = _Py_set_blocking(fd, blocking);
11561 _Py_END_SUPPRESS_IPH
11562 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011563 return NULL;
11564 Py_RETURN_NONE;
11565}
11566#endif /* !MS_WINDOWS */
11567
11568
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011569/*[clinic input]
11570class os.DirEntry "DirEntry *" "&DirEntryType"
11571[clinic start generated code]*/
11572/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011573
11574typedef struct {
11575 PyObject_HEAD
11576 PyObject *name;
11577 PyObject *path;
11578 PyObject *stat;
11579 PyObject *lstat;
11580#ifdef MS_WINDOWS
11581 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011582 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011583 int got_file_index;
11584#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011585#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011586 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011587#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011588 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011589 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011590#endif
11591} DirEntry;
11592
11593static void
11594DirEntry_dealloc(DirEntry *entry)
11595{
11596 Py_XDECREF(entry->name);
11597 Py_XDECREF(entry->path);
11598 Py_XDECREF(entry->stat);
11599 Py_XDECREF(entry->lstat);
11600 Py_TYPE(entry)->tp_free((PyObject *)entry);
11601}
11602
11603/* Forward reference */
11604static int
11605DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11606
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011607/*[clinic input]
11608os.DirEntry.is_symlink -> bool
11609
11610Return True if the entry is a symbolic link; cached per entry.
11611[clinic start generated code]*/
11612
Victor Stinner6036e442015-03-08 01:58:04 +010011613static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011614os_DirEntry_is_symlink_impl(DirEntry *self)
11615/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011616{
11617#ifdef MS_WINDOWS
11618 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011619#elif defined(HAVE_DIRENT_D_TYPE)
11620 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011621 if (self->d_type != DT_UNKNOWN)
11622 return self->d_type == DT_LNK;
11623 else
11624 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011625#else
11626 /* POSIX without d_type */
11627 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011628#endif
11629}
11630
11631static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011632DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11633{
11634 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011635 STRUCT_STAT st;
11636 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011637
11638#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011639 if (!PyUnicode_FSDecoder(self->path, &ub))
11640 return NULL;
11641 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011642#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011643 if (!PyUnicode_FSConverter(self->path, &ub))
11644 return NULL;
11645 const char *path = PyBytes_AS_STRING(ub);
11646 if (self->dir_fd != DEFAULT_DIR_FD) {
11647#ifdef HAVE_FSTATAT
11648 result = fstatat(self->dir_fd, path, &st,
11649 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11650#else
11651 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11652 return NULL;
11653#endif /* HAVE_FSTATAT */
11654 }
11655 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011656#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011657 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011658 if (follow_symlinks)
11659 result = STAT(path, &st);
11660 else
11661 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011662 }
11663 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011664
11665 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011666 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011667
11668 return _pystat_fromstructstat(&st);
11669}
11670
11671static PyObject *
11672DirEntry_get_lstat(DirEntry *self)
11673{
11674 if (!self->lstat) {
11675#ifdef MS_WINDOWS
11676 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11677#else /* POSIX */
11678 self->lstat = DirEntry_fetch_stat(self, 0);
11679#endif
11680 }
11681 Py_XINCREF(self->lstat);
11682 return self->lstat;
11683}
11684
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011685/*[clinic input]
11686os.DirEntry.stat
11687 *
11688 follow_symlinks: bool = True
11689
11690Return stat_result object for the entry; cached per entry.
11691[clinic start generated code]*/
11692
Victor Stinner6036e442015-03-08 01:58:04 +010011693static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011694os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11695/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011696{
11697 if (!follow_symlinks)
11698 return DirEntry_get_lstat(self);
11699
11700 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011701 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011702 if (result == -1)
11703 return NULL;
11704 else if (result)
11705 self->stat = DirEntry_fetch_stat(self, 1);
11706 else
11707 self->stat = DirEntry_get_lstat(self);
11708 }
11709
11710 Py_XINCREF(self->stat);
11711 return self->stat;
11712}
11713
Victor Stinner6036e442015-03-08 01:58:04 +010011714/* Set exception and return -1 on error, 0 for False, 1 for True */
11715static int
11716DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11717{
11718 PyObject *stat = NULL;
11719 PyObject *st_mode = NULL;
11720 long mode;
11721 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011722#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011723 int is_symlink;
11724 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011725#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011726#ifdef MS_WINDOWS
11727 unsigned long dir_bits;
11728#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011729 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011730
11731#ifdef MS_WINDOWS
11732 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11733 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011734#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011735 is_symlink = self->d_type == DT_LNK;
11736 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11737#endif
11738
Victor Stinner35a97c02015-03-08 02:59:09 +010011739#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011740 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011741#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011742 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011743 if (!stat) {
11744 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11745 /* If file doesn't exist (anymore), then return False
11746 (i.e., say it's not a file/directory) */
11747 PyErr_Clear();
11748 return 0;
11749 }
11750 goto error;
11751 }
11752 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11753 if (!st_mode)
11754 goto error;
11755
11756 mode = PyLong_AsLong(st_mode);
11757 if (mode == -1 && PyErr_Occurred())
11758 goto error;
11759 Py_CLEAR(st_mode);
11760 Py_CLEAR(stat);
11761 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011762#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011763 }
11764 else if (is_symlink) {
11765 assert(mode_bits != S_IFLNK);
11766 result = 0;
11767 }
11768 else {
11769 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11770#ifdef MS_WINDOWS
11771 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11772 if (mode_bits == S_IFDIR)
11773 result = dir_bits != 0;
11774 else
11775 result = dir_bits == 0;
11776#else /* POSIX */
11777 if (mode_bits == S_IFDIR)
11778 result = self->d_type == DT_DIR;
11779 else
11780 result = self->d_type == DT_REG;
11781#endif
11782 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011783#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011784
11785 return result;
11786
11787error:
11788 Py_XDECREF(st_mode);
11789 Py_XDECREF(stat);
11790 return -1;
11791}
11792
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011793/*[clinic input]
11794os.DirEntry.is_dir -> bool
11795 *
11796 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011797
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011798Return True if the entry is a directory; cached per entry.
11799[clinic start generated code]*/
11800
11801static int
11802os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11803/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11804{
11805 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011806}
11807
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011808/*[clinic input]
11809os.DirEntry.is_file -> bool
11810 *
11811 follow_symlinks: bool = True
11812
11813Return True if the entry is a file; cached per entry.
11814[clinic start generated code]*/
11815
11816static int
11817os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11818/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011819{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011820 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011821}
11822
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011823/*[clinic input]
11824os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011825
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011826Return inode of the entry; cached per entry.
11827[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011828
11829static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011830os_DirEntry_inode_impl(DirEntry *self)
11831/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011832{
11833#ifdef MS_WINDOWS
11834 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011835 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011836 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011837 STRUCT_STAT stat;
11838 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011839
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011840 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011841 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011842 path = PyUnicode_AsUnicode(unicode);
11843 result = LSTAT(path, &stat);
11844 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011845
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011846 if (result != 0)
11847 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011848
11849 self->win32_file_index = stat.st_ino;
11850 self->got_file_index = 1;
11851 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011852 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11853 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011854#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011855 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11856 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011857#endif
11858}
11859
11860static PyObject *
11861DirEntry_repr(DirEntry *self)
11862{
11863 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11864}
11865
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011866/*[clinic input]
11867os.DirEntry.__fspath__
11868
11869Returns the path for the entry.
11870[clinic start generated code]*/
11871
Brett Cannon96881cd2016-06-10 14:37:21 -070011872static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011873os_DirEntry___fspath___impl(DirEntry *self)
11874/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011875{
11876 Py_INCREF(self->path);
11877 return self->path;
11878}
11879
Victor Stinner6036e442015-03-08 01:58:04 +010011880static PyMemberDef DirEntry_members[] = {
11881 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11882 "the entry's base filename, relative to scandir() \"path\" argument"},
11883 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11884 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11885 {NULL}
11886};
11887
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011888#include "clinic/posixmodule.c.h"
11889
Victor Stinner6036e442015-03-08 01:58:04 +010011890static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011891 OS_DIRENTRY_IS_DIR_METHODDEF
11892 OS_DIRENTRY_IS_FILE_METHODDEF
11893 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11894 OS_DIRENTRY_STAT_METHODDEF
11895 OS_DIRENTRY_INODE_METHODDEF
11896 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011897 {NULL}
11898};
11899
Benjamin Peterson5646de42015-04-12 17:56:34 -040011900static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011901 PyVarObject_HEAD_INIT(NULL, 0)
11902 MODNAME ".DirEntry", /* tp_name */
11903 sizeof(DirEntry), /* tp_basicsize */
11904 0, /* tp_itemsize */
11905 /* methods */
11906 (destructor)DirEntry_dealloc, /* tp_dealloc */
11907 0, /* tp_print */
11908 0, /* tp_getattr */
11909 0, /* tp_setattr */
11910 0, /* tp_compare */
11911 (reprfunc)DirEntry_repr, /* tp_repr */
11912 0, /* tp_as_number */
11913 0, /* tp_as_sequence */
11914 0, /* tp_as_mapping */
11915 0, /* tp_hash */
11916 0, /* tp_call */
11917 0, /* tp_str */
11918 0, /* tp_getattro */
11919 0, /* tp_setattro */
11920 0, /* tp_as_buffer */
11921 Py_TPFLAGS_DEFAULT, /* tp_flags */
11922 0, /* tp_doc */
11923 0, /* tp_traverse */
11924 0, /* tp_clear */
11925 0, /* tp_richcompare */
11926 0, /* tp_weaklistoffset */
11927 0, /* tp_iter */
11928 0, /* tp_iternext */
11929 DirEntry_methods, /* tp_methods */
11930 DirEntry_members, /* tp_members */
11931};
11932
11933#ifdef MS_WINDOWS
11934
11935static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011936join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011937{
11938 Py_ssize_t path_len;
11939 Py_ssize_t size;
11940 wchar_t *result;
11941 wchar_t ch;
11942
11943 if (!path_wide) { /* Default arg: "." */
11944 path_wide = L".";
11945 path_len = 1;
11946 }
11947 else {
11948 path_len = wcslen(path_wide);
11949 }
11950
11951 /* The +1's are for the path separator and the NUL */
11952 size = path_len + 1 + wcslen(filename) + 1;
11953 result = PyMem_New(wchar_t, size);
11954 if (!result) {
11955 PyErr_NoMemory();
11956 return NULL;
11957 }
11958 wcscpy(result, path_wide);
11959 if (path_len > 0) {
11960 ch = result[path_len - 1];
11961 if (ch != SEP && ch != ALTSEP && ch != L':')
11962 result[path_len++] = SEP;
11963 wcscpy(result + path_len, filename);
11964 }
11965 return result;
11966}
11967
11968static PyObject *
11969DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11970{
11971 DirEntry *entry;
11972 BY_HANDLE_FILE_INFORMATION file_info;
11973 ULONG reparse_tag;
11974 wchar_t *joined_path;
11975
11976 entry = PyObject_New(DirEntry, &DirEntryType);
11977 if (!entry)
11978 return NULL;
11979 entry->name = NULL;
11980 entry->path = NULL;
11981 entry->stat = NULL;
11982 entry->lstat = NULL;
11983 entry->got_file_index = 0;
11984
11985 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11986 if (!entry->name)
11987 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011988 if (path->narrow) {
11989 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11990 if (!entry->name)
11991 goto error;
11992 }
Victor Stinner6036e442015-03-08 01:58:04 +010011993
11994 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11995 if (!joined_path)
11996 goto error;
11997
11998 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11999 PyMem_Free(joined_path);
12000 if (!entry->path)
12001 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070012002 if (path->narrow) {
12003 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12004 if (!entry->path)
12005 goto error;
12006 }
Victor Stinner6036e442015-03-08 01:58:04 +010012007
Steve Dowercc16be82016-09-08 10:35:16 -070012008 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012009 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12010
12011 return (PyObject *)entry;
12012
12013error:
12014 Py_DECREF(entry);
12015 return NULL;
12016}
12017
12018#else /* POSIX */
12019
12020static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012021join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012022{
12023 Py_ssize_t path_len;
12024 Py_ssize_t size;
12025 char *result;
12026
12027 if (!path_narrow) { /* Default arg: "." */
12028 path_narrow = ".";
12029 path_len = 1;
12030 }
12031 else {
12032 path_len = strlen(path_narrow);
12033 }
12034
12035 if (filename_len == -1)
12036 filename_len = strlen(filename);
12037
12038 /* The +1's are for the path separator and the NUL */
12039 size = path_len + 1 + filename_len + 1;
12040 result = PyMem_New(char, size);
12041 if (!result) {
12042 PyErr_NoMemory();
12043 return NULL;
12044 }
12045 strcpy(result, path_narrow);
12046 if (path_len > 0 && result[path_len - 1] != '/')
12047 result[path_len++] = '/';
12048 strcpy(result + path_len, filename);
12049 return result;
12050}
12051
12052static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012053DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012054 ino_t d_ino
12055#ifdef HAVE_DIRENT_D_TYPE
12056 , unsigned char d_type
12057#endif
12058 )
Victor Stinner6036e442015-03-08 01:58:04 +010012059{
12060 DirEntry *entry;
12061 char *joined_path;
12062
12063 entry = PyObject_New(DirEntry, &DirEntryType);
12064 if (!entry)
12065 return NULL;
12066 entry->name = NULL;
12067 entry->path = NULL;
12068 entry->stat = NULL;
12069 entry->lstat = NULL;
12070
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012071 if (path->fd != -1) {
12072 entry->dir_fd = path->fd;
12073 joined_path = NULL;
12074 }
12075 else {
12076 entry->dir_fd = DEFAULT_DIR_FD;
12077 joined_path = join_path_filename(path->narrow, name, name_len);
12078 if (!joined_path)
12079 goto error;
12080 }
Victor Stinner6036e442015-03-08 01:58:04 +010012081
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012082 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012083 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012084 if (joined_path)
12085 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012086 }
12087 else {
12088 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012089 if (joined_path)
12090 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012091 }
12092 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012093 if (!entry->name)
12094 goto error;
12095
12096 if (path->fd != -1) {
12097 entry->path = entry->name;
12098 Py_INCREF(entry->path);
12099 }
12100 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012101 goto error;
12102
Victor Stinner35a97c02015-03-08 02:59:09 +010012103#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012104 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012105#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012106 entry->d_ino = d_ino;
12107
12108 return (PyObject *)entry;
12109
12110error:
12111 Py_XDECREF(entry);
12112 return NULL;
12113}
12114
12115#endif
12116
12117
12118typedef struct {
12119 PyObject_HEAD
12120 path_t path;
12121#ifdef MS_WINDOWS
12122 HANDLE handle;
12123 WIN32_FIND_DATAW file_data;
12124 int first_time;
12125#else /* POSIX */
12126 DIR *dirp;
12127#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012128#ifdef HAVE_FDOPENDIR
12129 int fd;
12130#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012131} ScandirIterator;
12132
12133#ifdef MS_WINDOWS
12134
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012135static int
12136ScandirIterator_is_closed(ScandirIterator *iterator)
12137{
12138 return iterator->handle == INVALID_HANDLE_VALUE;
12139}
12140
Victor Stinner6036e442015-03-08 01:58:04 +010012141static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012142ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012143{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012144 HANDLE handle = iterator->handle;
12145
12146 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012147 return;
12148
Victor Stinner6036e442015-03-08 01:58:04 +010012149 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012150 Py_BEGIN_ALLOW_THREADS
12151 FindClose(handle);
12152 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012153}
12154
12155static PyObject *
12156ScandirIterator_iternext(ScandirIterator *iterator)
12157{
12158 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12159 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012160 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012161
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012162 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012163 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012164 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012165
12166 while (1) {
12167 if (!iterator->first_time) {
12168 Py_BEGIN_ALLOW_THREADS
12169 success = FindNextFileW(iterator->handle, file_data);
12170 Py_END_ALLOW_THREADS
12171 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012172 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012173 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012174 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012175 break;
12176 }
12177 }
12178 iterator->first_time = 0;
12179
12180 /* Skip over . and .. */
12181 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012182 wcscmp(file_data->cFileName, L"..") != 0) {
12183 entry = DirEntry_from_find_data(&iterator->path, file_data);
12184 if (!entry)
12185 break;
12186 return entry;
12187 }
Victor Stinner6036e442015-03-08 01:58:04 +010012188
12189 /* Loop till we get a non-dot directory or finish iterating */
12190 }
12191
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012192 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012193 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012194 return NULL;
12195}
12196
12197#else /* POSIX */
12198
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012199static int
12200ScandirIterator_is_closed(ScandirIterator *iterator)
12201{
12202 return !iterator->dirp;
12203}
12204
Victor Stinner6036e442015-03-08 01:58:04 +010012205static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012206ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012207{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012208 DIR *dirp = iterator->dirp;
12209
12210 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012211 return;
12212
Victor Stinner6036e442015-03-08 01:58:04 +010012213 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012214 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012215#ifdef HAVE_FDOPENDIR
12216 if (iterator->path.fd != -1)
12217 rewinddir(dirp);
12218#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012219 closedir(dirp);
12220 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012221 return;
12222}
12223
12224static PyObject *
12225ScandirIterator_iternext(ScandirIterator *iterator)
12226{
12227 struct dirent *direntp;
12228 Py_ssize_t name_len;
12229 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012230 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012231
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012232 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012233 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012234 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012235
12236 while (1) {
12237 errno = 0;
12238 Py_BEGIN_ALLOW_THREADS
12239 direntp = readdir(iterator->dirp);
12240 Py_END_ALLOW_THREADS
12241
12242 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012243 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012244 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012245 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012246 break;
12247 }
12248
12249 /* Skip over . and .. */
12250 name_len = NAMLEN(direntp);
12251 is_dot = direntp->d_name[0] == '.' &&
12252 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12253 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012254 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012255 name_len, direntp->d_ino
12256#ifdef HAVE_DIRENT_D_TYPE
12257 , direntp->d_type
12258#endif
12259 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012260 if (!entry)
12261 break;
12262 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012263 }
12264
12265 /* Loop till we get a non-dot directory or finish iterating */
12266 }
12267
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012268 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012269 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012270 return NULL;
12271}
12272
12273#endif
12274
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012275static PyObject *
12276ScandirIterator_close(ScandirIterator *self, PyObject *args)
12277{
12278 ScandirIterator_closedir(self);
12279 Py_RETURN_NONE;
12280}
12281
12282static PyObject *
12283ScandirIterator_enter(PyObject *self, PyObject *args)
12284{
12285 Py_INCREF(self);
12286 return self;
12287}
12288
12289static PyObject *
12290ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12291{
12292 ScandirIterator_closedir(self);
12293 Py_RETURN_NONE;
12294}
12295
Victor Stinner6036e442015-03-08 01:58:04 +010012296static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012297ScandirIterator_finalize(ScandirIterator *iterator)
12298{
12299 PyObject *error_type, *error_value, *error_traceback;
12300
12301 /* Save the current exception, if any. */
12302 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12303
12304 if (!ScandirIterator_is_closed(iterator)) {
12305 ScandirIterator_closedir(iterator);
12306
12307 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12308 "unclosed scandir iterator %R", iterator)) {
12309 /* Spurious errors can appear at shutdown */
12310 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12311 PyErr_WriteUnraisable((PyObject *) iterator);
12312 }
12313 }
12314 }
12315
Victor Stinner7bfa4092016-03-23 00:43:54 +010012316 path_cleanup(&iterator->path);
12317
12318 /* Restore the saved exception. */
12319 PyErr_Restore(error_type, error_value, error_traceback);
12320}
12321
12322static void
Victor Stinner6036e442015-03-08 01:58:04 +010012323ScandirIterator_dealloc(ScandirIterator *iterator)
12324{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012325 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12326 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012327
Victor Stinner6036e442015-03-08 01:58:04 +010012328 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12329}
12330
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012331static PyMethodDef ScandirIterator_methods[] = {
12332 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12333 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12334 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12335 {NULL}
12336};
12337
Benjamin Peterson5646de42015-04-12 17:56:34 -040012338static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012339 PyVarObject_HEAD_INIT(NULL, 0)
12340 MODNAME ".ScandirIterator", /* tp_name */
12341 sizeof(ScandirIterator), /* tp_basicsize */
12342 0, /* tp_itemsize */
12343 /* methods */
12344 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12345 0, /* tp_print */
12346 0, /* tp_getattr */
12347 0, /* tp_setattr */
12348 0, /* tp_compare */
12349 0, /* tp_repr */
12350 0, /* tp_as_number */
12351 0, /* tp_as_sequence */
12352 0, /* tp_as_mapping */
12353 0, /* tp_hash */
12354 0, /* tp_call */
12355 0, /* tp_str */
12356 0, /* tp_getattro */
12357 0, /* tp_setattro */
12358 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012359 Py_TPFLAGS_DEFAULT
12360 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012361 0, /* tp_doc */
12362 0, /* tp_traverse */
12363 0, /* tp_clear */
12364 0, /* tp_richcompare */
12365 0, /* tp_weaklistoffset */
12366 PyObject_SelfIter, /* tp_iter */
12367 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012368 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012369 0, /* tp_members */
12370 0, /* tp_getset */
12371 0, /* tp_base */
12372 0, /* tp_dict */
12373 0, /* tp_descr_get */
12374 0, /* tp_descr_set */
12375 0, /* tp_dictoffset */
12376 0, /* tp_init */
12377 0, /* tp_alloc */
12378 0, /* tp_new */
12379 0, /* tp_free */
12380 0, /* tp_is_gc */
12381 0, /* tp_bases */
12382 0, /* tp_mro */
12383 0, /* tp_cache */
12384 0, /* tp_subclasses */
12385 0, /* tp_weaklist */
12386 0, /* tp_del */
12387 0, /* tp_version_tag */
12388 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012389};
12390
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012391/*[clinic input]
12392os.scandir
12393
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012394 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012395
12396Return an iterator of DirEntry objects for given path.
12397
BNMetrics08026b12018-11-02 17:56:25 +000012398path can be specified as either str, bytes, or a path-like object. If path
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012399is bytes, the names of yielded DirEntry objects will also be bytes; in
12400all other circumstances they will be str.
12401
12402If path is None, uses the path='.'.
12403[clinic start generated code]*/
12404
Victor Stinner6036e442015-03-08 01:58:04 +010012405static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012406os_scandir_impl(PyObject *module, path_t *path)
BNMetrics08026b12018-11-02 17:56:25 +000012407/*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012408{
12409 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012410#ifdef MS_WINDOWS
12411 wchar_t *path_strW;
12412#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012413 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012414#ifdef HAVE_FDOPENDIR
12415 int fd = -1;
12416#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012417#endif
12418
12419 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12420 if (!iterator)
12421 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012422
12423#ifdef MS_WINDOWS
12424 iterator->handle = INVALID_HANDLE_VALUE;
12425#else
12426 iterator->dirp = NULL;
12427#endif
12428
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012429 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012430 /* Move the ownership to iterator->path */
12431 path->object = NULL;
12432 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012433
12434#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012435 iterator->first_time = 1;
12436
12437 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12438 if (!path_strW)
12439 goto error;
12440
12441 Py_BEGIN_ALLOW_THREADS
12442 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12443 Py_END_ALLOW_THREADS
12444
12445 PyMem_Free(path_strW);
12446
12447 if (iterator->handle == INVALID_HANDLE_VALUE) {
12448 path_error(&iterator->path);
12449 goto error;
12450 }
12451#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012452 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012453#ifdef HAVE_FDOPENDIR
12454 if (path->fd != -1) {
12455 /* closedir() closes the FD, so we duplicate it */
12456 fd = _Py_dup(path->fd);
12457 if (fd == -1)
12458 goto error;
12459
12460 Py_BEGIN_ALLOW_THREADS
12461 iterator->dirp = fdopendir(fd);
12462 Py_END_ALLOW_THREADS
12463 }
12464 else
12465#endif
12466 {
12467 if (iterator->path.narrow)
12468 path_str = iterator->path.narrow;
12469 else
12470 path_str = ".";
12471
12472 Py_BEGIN_ALLOW_THREADS
12473 iterator->dirp = opendir(path_str);
12474 Py_END_ALLOW_THREADS
12475 }
Victor Stinner6036e442015-03-08 01:58:04 +010012476
12477 if (!iterator->dirp) {
12478 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012479#ifdef HAVE_FDOPENDIR
12480 if (fd != -1) {
12481 Py_BEGIN_ALLOW_THREADS
12482 close(fd);
12483 Py_END_ALLOW_THREADS
12484 }
12485#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012486 goto error;
12487 }
12488#endif
12489
12490 return (PyObject *)iterator;
12491
12492error:
12493 Py_DECREF(iterator);
12494 return NULL;
12495}
12496
Ethan Furman410ef8e2016-06-04 12:06:26 -070012497/*
12498 Return the file system path representation of the object.
12499
12500 If the object is str or bytes, then allow it to pass through with
12501 an incremented refcount. If the object defines __fspath__(), then
12502 return the result of that method. All other types raise a TypeError.
12503*/
12504PyObject *
12505PyOS_FSPath(PyObject *path)
12506{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012507 /* For error message reasons, this function is manually inlined in
12508 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012509 _Py_IDENTIFIER(__fspath__);
12510 PyObject *func = NULL;
12511 PyObject *path_repr = NULL;
12512
12513 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12514 Py_INCREF(path);
12515 return path;
12516 }
12517
12518 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12519 if (NULL == func) {
12520 return PyErr_Format(PyExc_TypeError,
12521 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012522 "not %.200s",
12523 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012524 }
12525
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012526 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012527 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012528 if (NULL == path_repr) {
12529 return NULL;
12530 }
12531
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012532 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12533 PyErr_Format(PyExc_TypeError,
12534 "expected %.200s.__fspath__() to return str or bytes, "
12535 "not %.200s", Py_TYPE(path)->tp_name,
12536 Py_TYPE(path_repr)->tp_name);
12537 Py_DECREF(path_repr);
12538 return NULL;
12539 }
12540
Ethan Furman410ef8e2016-06-04 12:06:26 -070012541 return path_repr;
12542}
12543
12544/*[clinic input]
12545os.fspath
12546
12547 path: object
12548
12549Return the file system path representation of the object.
12550
Brett Cannonb4f43e92016-06-09 14:32:08 -070012551If the object is str or bytes, then allow it to pass through as-is. If the
12552object defines __fspath__(), then return the result of that method. All other
12553types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012554[clinic start generated code]*/
12555
12556static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012557os_fspath_impl(PyObject *module, PyObject *path)
12558/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012559{
12560 return PyOS_FSPath(path);
12561}
Victor Stinner6036e442015-03-08 01:58:04 +010012562
Victor Stinner9b1f4742016-09-06 16:18:52 -070012563#ifdef HAVE_GETRANDOM_SYSCALL
12564/*[clinic input]
12565os.getrandom
12566
12567 size: Py_ssize_t
12568 flags: int=0
12569
12570Obtain a series of random bytes.
12571[clinic start generated code]*/
12572
12573static PyObject *
12574os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12575/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12576{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012577 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012578 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012579
12580 if (size < 0) {
12581 errno = EINVAL;
12582 return posix_error();
12583 }
12584
Victor Stinnerec2319c2016-09-20 23:00:59 +020012585 bytes = PyBytes_FromStringAndSize(NULL, size);
12586 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012587 PyErr_NoMemory();
12588 return NULL;
12589 }
12590
12591 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012592 n = syscall(SYS_getrandom,
12593 PyBytes_AS_STRING(bytes),
12594 PyBytes_GET_SIZE(bytes),
12595 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012596 if (n < 0 && errno == EINTR) {
12597 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012598 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012599 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012600
12601 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012602 continue;
12603 }
12604 break;
12605 }
12606
12607 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012608 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012609 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012610 }
12611
Victor Stinnerec2319c2016-09-20 23:00:59 +020012612 if (n != size) {
12613 _PyBytes_Resize(&bytes, n);
12614 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012615
12616 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012617
12618error:
12619 Py_DECREF(bytes);
12620 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012621}
12622#endif /* HAVE_GETRANDOM_SYSCALL */
12623
Larry Hastings31826802013-10-19 00:09:25 -070012624
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012625static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012626
12627 OS_STAT_METHODDEF
12628 OS_ACCESS_METHODDEF
12629 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012630 OS_CHDIR_METHODDEF
12631 OS_CHFLAGS_METHODDEF
12632 OS_CHMOD_METHODDEF
12633 OS_FCHMOD_METHODDEF
12634 OS_LCHMOD_METHODDEF
12635 OS_CHOWN_METHODDEF
12636 OS_FCHOWN_METHODDEF
12637 OS_LCHOWN_METHODDEF
12638 OS_LCHFLAGS_METHODDEF
12639 OS_CHROOT_METHODDEF
12640 OS_CTERMID_METHODDEF
12641 OS_GETCWD_METHODDEF
12642 OS_GETCWDB_METHODDEF
12643 OS_LINK_METHODDEF
12644 OS_LISTDIR_METHODDEF
12645 OS_LSTAT_METHODDEF
12646 OS_MKDIR_METHODDEF
12647 OS_NICE_METHODDEF
12648 OS_GETPRIORITY_METHODDEF
12649 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012650#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012651 {"readlink", (PyCFunction)posix_readlink,
12652 METH_VARARGS | METH_KEYWORDS,
12653 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012654#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012655#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012656 {"readlink", (PyCFunction)win_readlink,
12657 METH_VARARGS | METH_KEYWORDS,
12658 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012659#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012660 OS_RENAME_METHODDEF
12661 OS_REPLACE_METHODDEF
12662 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012663 OS_SYMLINK_METHODDEF
12664 OS_SYSTEM_METHODDEF
12665 OS_UMASK_METHODDEF
12666 OS_UNAME_METHODDEF
12667 OS_UNLINK_METHODDEF
12668 OS_REMOVE_METHODDEF
12669 OS_UTIME_METHODDEF
12670 OS_TIMES_METHODDEF
12671 OS__EXIT_METHODDEF
12672 OS_EXECV_METHODDEF
12673 OS_EXECVE_METHODDEF
12674 OS_SPAWNV_METHODDEF
12675 OS_SPAWNVE_METHODDEF
12676 OS_FORK1_METHODDEF
12677 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012678 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012679 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12680 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12681 OS_SCHED_GETPARAM_METHODDEF
12682 OS_SCHED_GETSCHEDULER_METHODDEF
12683 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12684 OS_SCHED_SETPARAM_METHODDEF
12685 OS_SCHED_SETSCHEDULER_METHODDEF
12686 OS_SCHED_YIELD_METHODDEF
12687 OS_SCHED_SETAFFINITY_METHODDEF
12688 OS_SCHED_GETAFFINITY_METHODDEF
12689 OS_OPENPTY_METHODDEF
12690 OS_FORKPTY_METHODDEF
12691 OS_GETEGID_METHODDEF
12692 OS_GETEUID_METHODDEF
12693 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012694#ifdef HAVE_GETGROUPLIST
12695 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12696#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012697 OS_GETGROUPS_METHODDEF
12698 OS_GETPID_METHODDEF
12699 OS_GETPGRP_METHODDEF
12700 OS_GETPPID_METHODDEF
12701 OS_GETUID_METHODDEF
12702 OS_GETLOGIN_METHODDEF
12703 OS_KILL_METHODDEF
12704 OS_KILLPG_METHODDEF
12705 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012706#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012707 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012708#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012709 OS_SETUID_METHODDEF
12710 OS_SETEUID_METHODDEF
12711 OS_SETREUID_METHODDEF
12712 OS_SETGID_METHODDEF
12713 OS_SETEGID_METHODDEF
12714 OS_SETREGID_METHODDEF
12715 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012716#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012717 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012718#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012719 OS_GETPGID_METHODDEF
12720 OS_SETPGRP_METHODDEF
12721 OS_WAIT_METHODDEF
12722 OS_WAIT3_METHODDEF
12723 OS_WAIT4_METHODDEF
12724 OS_WAITID_METHODDEF
12725 OS_WAITPID_METHODDEF
12726 OS_GETSID_METHODDEF
12727 OS_SETSID_METHODDEF
12728 OS_SETPGID_METHODDEF
12729 OS_TCGETPGRP_METHODDEF
12730 OS_TCSETPGRP_METHODDEF
12731 OS_OPEN_METHODDEF
12732 OS_CLOSE_METHODDEF
12733 OS_CLOSERANGE_METHODDEF
12734 OS_DEVICE_ENCODING_METHODDEF
12735 OS_DUP_METHODDEF
12736 OS_DUP2_METHODDEF
12737 OS_LOCKF_METHODDEF
12738 OS_LSEEK_METHODDEF
12739 OS_READ_METHODDEF
12740 OS_READV_METHODDEF
12741 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012742 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012743 OS_WRITE_METHODDEF
12744 OS_WRITEV_METHODDEF
12745 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012746 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012747#ifdef HAVE_SENDFILE
12748 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12749 posix_sendfile__doc__},
12750#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012751 OS_FSTAT_METHODDEF
12752 OS_ISATTY_METHODDEF
12753 OS_PIPE_METHODDEF
12754 OS_PIPE2_METHODDEF
12755 OS_MKFIFO_METHODDEF
12756 OS_MKNOD_METHODDEF
12757 OS_MAJOR_METHODDEF
12758 OS_MINOR_METHODDEF
12759 OS_MAKEDEV_METHODDEF
12760 OS_FTRUNCATE_METHODDEF
12761 OS_TRUNCATE_METHODDEF
12762 OS_POSIX_FALLOCATE_METHODDEF
12763 OS_POSIX_FADVISE_METHODDEF
12764 OS_PUTENV_METHODDEF
12765 OS_UNSETENV_METHODDEF
12766 OS_STRERROR_METHODDEF
12767 OS_FCHDIR_METHODDEF
12768 OS_FSYNC_METHODDEF
12769 OS_SYNC_METHODDEF
12770 OS_FDATASYNC_METHODDEF
12771 OS_WCOREDUMP_METHODDEF
12772 OS_WIFCONTINUED_METHODDEF
12773 OS_WIFSTOPPED_METHODDEF
12774 OS_WIFSIGNALED_METHODDEF
12775 OS_WIFEXITED_METHODDEF
12776 OS_WEXITSTATUS_METHODDEF
12777 OS_WTERMSIG_METHODDEF
12778 OS_WSTOPSIG_METHODDEF
12779 OS_FSTATVFS_METHODDEF
12780 OS_STATVFS_METHODDEF
12781 OS_CONFSTR_METHODDEF
12782 OS_SYSCONF_METHODDEF
12783 OS_FPATHCONF_METHODDEF
12784 OS_PATHCONF_METHODDEF
12785 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012786 OS__GETFULLPATHNAME_METHODDEF
12787 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012788 OS__GETDISKUSAGE_METHODDEF
12789 OS__GETFINALPATHNAME_METHODDEF
12790 OS__GETVOLUMEPATHNAME_METHODDEF
12791 OS_GETLOADAVG_METHODDEF
12792 OS_URANDOM_METHODDEF
12793 OS_SETRESUID_METHODDEF
12794 OS_SETRESGID_METHODDEF
12795 OS_GETRESUID_METHODDEF
12796 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012797
Larry Hastings2f936352014-08-05 14:04:04 +100012798 OS_GETXATTR_METHODDEF
12799 OS_SETXATTR_METHODDEF
12800 OS_REMOVEXATTR_METHODDEF
12801 OS_LISTXATTR_METHODDEF
12802
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012803#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12804 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12805#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012806 OS_CPU_COUNT_METHODDEF
12807 OS_GET_INHERITABLE_METHODDEF
12808 OS_SET_INHERITABLE_METHODDEF
12809 OS_GET_HANDLE_INHERITABLE_METHODDEF
12810 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012811#ifndef MS_WINDOWS
12812 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12813 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12814#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012815 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012816 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012817 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012818 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012819};
12820
12821
Brian Curtin52173d42010-12-02 18:29:18 +000012822#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012823static int
Brian Curtin52173d42010-12-02 18:29:18 +000012824enable_symlink()
12825{
12826 HANDLE tok;
12827 TOKEN_PRIVILEGES tok_priv;
12828 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012829
12830 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012831 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012832
12833 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012834 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012835
12836 tok_priv.PrivilegeCount = 1;
12837 tok_priv.Privileges[0].Luid = luid;
12838 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12839
12840 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12841 sizeof(TOKEN_PRIVILEGES),
12842 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012843 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012844
Brian Curtin3b4499c2010-12-28 14:31:47 +000012845 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12846 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012847}
12848#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12849
Barry Warsaw4a342091996-12-19 23:50:02 +000012850static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012852{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012853#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012855#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012856#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012858#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012859#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012861#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012862#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012863 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012864#endif
Fred Drakec9680921999-12-13 16:37:25 +000012865#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012867#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012868#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012870#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012871#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012873#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012874#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012876#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012877#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012879#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012880#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012882#endif
12883#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012885#endif
12886#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012888#endif
12889#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012891#endif
12892#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012894#endif
12895#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012897#endif
12898#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012900#endif
12901#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012903#endif
12904#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012906#endif
12907#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012909#endif
12910#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012911 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012912#endif
12913#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012915#endif
12916#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012917 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012918#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012919#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012920 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012921#endif
12922#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012923 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012924#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012925#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012926 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012927#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012928#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012929 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012930#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012931#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012932#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012934#endif
12935#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012937#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012938#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012939#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012941#endif
12942#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012943 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012944#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012945#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012947#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012948#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012950#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012951#ifdef O_TMPFILE
12952 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12953#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012954#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012955 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012956#endif
12957#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012958 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012959#endif
12960#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012961 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012962#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012963#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012964 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012965#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012966#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012967 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012968#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012969
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012970
Jesus Cea94363612012-06-22 18:32:07 +020012971#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012972 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012973#endif
12974#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012975 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012976#endif
12977
Tim Peters5aa91602002-01-30 05:46:57 +000012978/* MS Windows */
12979#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012980 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012981 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012982#endif
12983#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012984 /* Optimize for short life (keep in memory). */
12985 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012986 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012987#endif
12988#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012991#endif
12992#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012993 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012994 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012995#endif
12996#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012998 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012999#endif
13000
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013001/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013002#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013003 /* Send a SIGIO signal whenever input or output
13004 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013005 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013006#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013007#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013008 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013009 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013010#endif
13011#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013012 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013013 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013014#endif
13015#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013016 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013017 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013018#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013019#ifdef O_NOLINKS
13020 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013022#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013023#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013024 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013025 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013026#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013027
Victor Stinner8c62be82010-05-06 00:08:46 +000013028 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013029#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013030 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013031#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013032#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013033 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013034#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013035#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013036 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013037#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013038#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013039 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013040#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013041#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013042 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013043#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013044#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013046#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013047#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013048 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013049#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013050#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013051 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013052#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013053#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013054 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013055#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013056#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013057 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013058#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013059#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013060 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013061#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013062#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013063 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013064#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013065#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013066 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013067#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013068#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013069 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013070#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013071#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013072 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013073#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013074#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013075 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013076#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013077#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013078 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013079#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013080
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013081 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013082#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013083 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013084#endif /* ST_RDONLY */
13085#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013086 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013087#endif /* ST_NOSUID */
13088
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013089 /* GNU extensions */
13090#ifdef ST_NODEV
13091 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13092#endif /* ST_NODEV */
13093#ifdef ST_NOEXEC
13094 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13095#endif /* ST_NOEXEC */
13096#ifdef ST_SYNCHRONOUS
13097 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13098#endif /* ST_SYNCHRONOUS */
13099#ifdef ST_MANDLOCK
13100 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13101#endif /* ST_MANDLOCK */
13102#ifdef ST_WRITE
13103 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13104#endif /* ST_WRITE */
13105#ifdef ST_APPEND
13106 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13107#endif /* ST_APPEND */
13108#ifdef ST_NOATIME
13109 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13110#endif /* ST_NOATIME */
13111#ifdef ST_NODIRATIME
13112 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13113#endif /* ST_NODIRATIME */
13114#ifdef ST_RELATIME
13115 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13116#endif /* ST_RELATIME */
13117
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013118 /* FreeBSD sendfile() constants */
13119#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013120 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013121#endif
13122#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013123 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013124#endif
13125#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013126 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013127#endif
13128
Ross Lagerwall7807c352011-03-17 20:20:30 +020013129 /* constants for posix_fadvise */
13130#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013131 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013132#endif
13133#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013134 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013135#endif
13136#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013137 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013138#endif
13139#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013140 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013141#endif
13142#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013143 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013144#endif
13145#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013146 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013147#endif
13148
13149 /* constants for waitid */
13150#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013151 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13152 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13153 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013154#endif
13155#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013156 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013157#endif
13158#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013159 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013160#endif
13161#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013162 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013163#endif
13164#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013165 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013166#endif
13167#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013168 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013169#endif
13170#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013171 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013172#endif
13173#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013174 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013175#endif
13176
13177 /* constants for lockf */
13178#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013179 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013180#endif
13181#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013182 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013183#endif
13184#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013185 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013186#endif
13187#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013188 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013189#endif
13190
Pablo Galindo4defba32018-01-27 16:16:37 +000013191#ifdef RWF_DSYNC
13192 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13193#endif
13194#ifdef RWF_HIPRI
13195 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13196#endif
13197#ifdef RWF_SYNC
13198 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13199#endif
13200#ifdef RWF_NOWAIT
13201 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13202#endif
13203
Guido van Rossum246bc171999-02-01 23:54:31 +000013204#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013205 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13206 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13207 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13208 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13209 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013210#endif
13211
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013212#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013213#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013214 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013215#endif
13216#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013217 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013218#endif
13219#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013220 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013221#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013222#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013223 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013224#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013225#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013226 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013227#endif
13228#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013229 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013230#endif
13231#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013232 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013233#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013234#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013235 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013236#endif
13237#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013238 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013239#endif
13240#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013241 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013242#endif
13243#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013244 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013245#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013246#endif
13247
Benjamin Peterson9428d532011-09-14 11:45:52 -040013248#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013249 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13250 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13251 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013252#endif
13253
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013254#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013255 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013256#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013257#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013258 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013259#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013260#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013261 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013262#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013263#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013264 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013265#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013266#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013267 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013268#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013269#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013270 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013271#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013272#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013273 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013274#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013275#if HAVE_DECL_RTLD_MEMBER
13276 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13277#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013278
Victor Stinner9b1f4742016-09-06 16:18:52 -070013279#ifdef HAVE_GETRANDOM_SYSCALL
13280 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13281 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13282#endif
13283
Victor Stinner8c62be82010-05-06 00:08:46 +000013284 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013285}
13286
13287
Martin v. Löwis1a214512008-06-11 05:26:20 +000013288static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013289 PyModuleDef_HEAD_INIT,
13290 MODNAME,
13291 posix__doc__,
13292 -1,
13293 posix_methods,
13294 NULL,
13295 NULL,
13296 NULL,
13297 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013298};
13299
13300
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013301static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013302
13303#ifdef HAVE_FACCESSAT
13304 "HAVE_FACCESSAT",
13305#endif
13306
13307#ifdef HAVE_FCHDIR
13308 "HAVE_FCHDIR",
13309#endif
13310
13311#ifdef HAVE_FCHMOD
13312 "HAVE_FCHMOD",
13313#endif
13314
13315#ifdef HAVE_FCHMODAT
13316 "HAVE_FCHMODAT",
13317#endif
13318
13319#ifdef HAVE_FCHOWN
13320 "HAVE_FCHOWN",
13321#endif
13322
Larry Hastings00964ed2013-08-12 13:49:30 -040013323#ifdef HAVE_FCHOWNAT
13324 "HAVE_FCHOWNAT",
13325#endif
13326
Larry Hastings9cf065c2012-06-22 16:30:09 -070013327#ifdef HAVE_FEXECVE
13328 "HAVE_FEXECVE",
13329#endif
13330
13331#ifdef HAVE_FDOPENDIR
13332 "HAVE_FDOPENDIR",
13333#endif
13334
Georg Brandl306336b2012-06-24 12:55:33 +020013335#ifdef HAVE_FPATHCONF
13336 "HAVE_FPATHCONF",
13337#endif
13338
Larry Hastings9cf065c2012-06-22 16:30:09 -070013339#ifdef HAVE_FSTATAT
13340 "HAVE_FSTATAT",
13341#endif
13342
13343#ifdef HAVE_FSTATVFS
13344 "HAVE_FSTATVFS",
13345#endif
13346
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013347#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013348 "HAVE_FTRUNCATE",
13349#endif
13350
Larry Hastings9cf065c2012-06-22 16:30:09 -070013351#ifdef HAVE_FUTIMENS
13352 "HAVE_FUTIMENS",
13353#endif
13354
13355#ifdef HAVE_FUTIMES
13356 "HAVE_FUTIMES",
13357#endif
13358
13359#ifdef HAVE_FUTIMESAT
13360 "HAVE_FUTIMESAT",
13361#endif
13362
13363#ifdef HAVE_LINKAT
13364 "HAVE_LINKAT",
13365#endif
13366
13367#ifdef HAVE_LCHFLAGS
13368 "HAVE_LCHFLAGS",
13369#endif
13370
13371#ifdef HAVE_LCHMOD
13372 "HAVE_LCHMOD",
13373#endif
13374
13375#ifdef HAVE_LCHOWN
13376 "HAVE_LCHOWN",
13377#endif
13378
13379#ifdef HAVE_LSTAT
13380 "HAVE_LSTAT",
13381#endif
13382
13383#ifdef HAVE_LUTIMES
13384 "HAVE_LUTIMES",
13385#endif
13386
13387#ifdef HAVE_MKDIRAT
13388 "HAVE_MKDIRAT",
13389#endif
13390
13391#ifdef HAVE_MKFIFOAT
13392 "HAVE_MKFIFOAT",
13393#endif
13394
13395#ifdef HAVE_MKNODAT
13396 "HAVE_MKNODAT",
13397#endif
13398
13399#ifdef HAVE_OPENAT
13400 "HAVE_OPENAT",
13401#endif
13402
13403#ifdef HAVE_READLINKAT
13404 "HAVE_READLINKAT",
13405#endif
13406
13407#ifdef HAVE_RENAMEAT
13408 "HAVE_RENAMEAT",
13409#endif
13410
13411#ifdef HAVE_SYMLINKAT
13412 "HAVE_SYMLINKAT",
13413#endif
13414
13415#ifdef HAVE_UNLINKAT
13416 "HAVE_UNLINKAT",
13417#endif
13418
13419#ifdef HAVE_UTIMENSAT
13420 "HAVE_UTIMENSAT",
13421#endif
13422
13423#ifdef MS_WINDOWS
13424 "MS_WINDOWS",
13425#endif
13426
13427 NULL
13428};
13429
13430
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013431PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013432INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013433{
Victor Stinner8c62be82010-05-06 00:08:46 +000013434 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013435 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013436 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013437
Brian Curtin52173d42010-12-02 18:29:18 +000013438#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013439 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013440#endif
13441
Victor Stinner8c62be82010-05-06 00:08:46 +000013442 m = PyModule_Create(&posixmodule);
13443 if (m == NULL)
13444 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013445
Victor Stinner8c62be82010-05-06 00:08:46 +000013446 /* Initialize environ dictionary */
13447 v = convertenviron();
13448 Py_XINCREF(v);
13449 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13450 return NULL;
13451 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013452
Victor Stinner8c62be82010-05-06 00:08:46 +000013453 if (all_ins(m))
13454 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013455
Victor Stinner8c62be82010-05-06 00:08:46 +000013456 if (setup_confname_tables(m))
13457 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013458
Victor Stinner8c62be82010-05-06 00:08:46 +000013459 Py_INCREF(PyExc_OSError);
13460 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013461
Guido van Rossumb3d39562000-01-31 18:41:26 +000013462#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013463 if (posix_putenv_garbage == NULL)
13464 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013465#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013466
Victor Stinner8c62be82010-05-06 00:08:46 +000013467 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013468#if defined(HAVE_WAITID) && !defined(__APPLE__)
13469 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013470 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13471 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013472#endif
13473
Christian Heimes25827622013-10-12 01:27:08 +020013474 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013475 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13476 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13477 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013478 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13479 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013480 structseq_new = StatResultType.tp_new;
13481 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013482
Christian Heimes25827622013-10-12 01:27:08 +020013483 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013484 if (PyStructSequence_InitType2(&StatVFSResultType,
13485 &statvfs_result_desc) < 0)
13486 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013487#ifdef NEED_TICKS_PER_SECOND
13488# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013489 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013490# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013491 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013492# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013493 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013494# endif
13495#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013496
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013497#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013498 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013499 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13500 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013501 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013502#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013503
13504 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013505 if (PyStructSequence_InitType2(&TerminalSizeType,
13506 &TerminalSize_desc) < 0)
13507 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013508
13509 /* initialize scandir types */
13510 if (PyType_Ready(&ScandirIteratorType) < 0)
13511 return NULL;
13512 if (PyType_Ready(&DirEntryType) < 0)
13513 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013514 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013515#if defined(HAVE_WAITID) && !defined(__APPLE__)
13516 Py_INCREF((PyObject*) &WaitidResultType);
13517 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13518#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013519 Py_INCREF((PyObject*) &StatResultType);
13520 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13521 Py_INCREF((PyObject*) &StatVFSResultType);
13522 PyModule_AddObject(m, "statvfs_result",
13523 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013524
13525#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013526 Py_INCREF(&SchedParamType);
13527 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013528#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013529
Larry Hastings605a62d2012-06-24 04:33:36 -070013530 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013531 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13532 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013533 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13534
13535 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013536 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13537 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013538 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13539
Thomas Wouters477c8d52006-05-27 19:21:47 +000013540#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013541 /*
13542 * Step 2 of weak-linking support on Mac OS X.
13543 *
13544 * The code below removes functions that are not available on the
13545 * currently active platform.
13546 *
13547 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013548 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013549 * OSX 10.4.
13550 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013551#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013552 if (fstatvfs == NULL) {
13553 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13554 return NULL;
13555 }
13556 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013557#endif /* HAVE_FSTATVFS */
13558
13559#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013560 if (statvfs == NULL) {
13561 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13562 return NULL;
13563 }
13564 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013565#endif /* HAVE_STATVFS */
13566
13567# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013568 if (lchown == NULL) {
13569 if (PyObject_DelAttrString(m, "lchown") == -1) {
13570 return NULL;
13571 }
13572 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013573#endif /* HAVE_LCHOWN */
13574
13575
13576#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013577
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013578 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013579 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13580
Larry Hastings6fe20b32012-04-19 15:07:49 -070013581 billion = PyLong_FromLong(1000000000);
13582 if (!billion)
13583 return NULL;
13584
Larry Hastings9cf065c2012-06-22 16:30:09 -070013585 /* suppress "function not used" warnings */
13586 {
13587 int ignored;
13588 fd_specified("", -1);
13589 follow_symlinks_specified("", 1);
13590 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13591 dir_fd_converter(Py_None, &ignored);
13592 dir_fd_unavailable(Py_None, &ignored);
13593 }
13594
13595 /*
13596 * provide list of locally available functions
13597 * so os.py can populate support_* lists
13598 */
13599 list = PyList_New(0);
13600 if (!list)
13601 return NULL;
13602 for (trace = have_functions; *trace; trace++) {
13603 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13604 if (!unicode)
13605 return NULL;
13606 if (PyList_Append(list, unicode))
13607 return NULL;
13608 Py_DECREF(unicode);
13609 }
13610 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013611
13612 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013613 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013614
13615 initialized = 1;
13616
Victor Stinner8c62be82010-05-06 00:08:46 +000013617 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013618}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013619
13620#ifdef __cplusplus
13621}
13622#endif