blob: bbbff1eca8ffbf7935826b1ebb9e518a2eb88978 [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
396#ifdef HAVE_FORK
397static void
398run_at_forkers(PyObject *lst, int reverse)
399{
400 Py_ssize_t i;
401 PyObject *cpy;
402
403 if (lst != NULL) {
404 assert(PyList_CheckExact(lst));
405
406 /* Use a list copy in case register_at_fork() is called from
407 * one of the callbacks.
408 */
409 cpy = PyList_GetSlice(lst, 0, PyList_GET_SIZE(lst));
410 if (cpy == NULL)
411 PyErr_WriteUnraisable(lst);
412 else {
413 if (reverse)
414 PyList_Reverse(cpy);
415 for (i = 0; i < PyList_GET_SIZE(cpy); i++) {
416 PyObject *func, *res;
417 func = PyList_GET_ITEM(cpy, i);
418 res = PyObject_CallObject(func, NULL);
419 if (res == NULL)
420 PyErr_WriteUnraisable(func);
421 else
422 Py_DECREF(res);
423 }
424 Py_DECREF(cpy);
425 }
426 }
427}
428
429void
430PyOS_BeforeFork(void)
431{
432 run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
433
434 _PyImport_AcquireLock();
435}
436
437void
438PyOS_AfterFork_Parent(void)
439{
440 if (_PyImport_ReleaseLock() <= 0)
441 Py_FatalError("failed releasing import lock after fork");
442
443 run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
444}
445
446void
447PyOS_AfterFork_Child(void)
448{
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200449 _PyGILState_Reinit();
450 PyEval_ReInitThreads();
451 _PyImport_ReInitLock();
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200452 _PySignal_AfterFork();
453
454 run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
455}
456
457static int
458register_at_forker(PyObject **lst, PyObject *func)
459{
Gregory P. Smith163468a2017-05-29 10:03:41 -0700460 if (func == NULL) /* nothing to register? do nothing. */
461 return 0;
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200462 if (*lst == NULL) {
463 *lst = PyList_New(0);
464 if (*lst == NULL)
465 return -1;
466 }
467 return PyList_Append(*lst, func);
468}
469#endif
470
471/* Legacy wrapper */
472void
473PyOS_AfterFork(void)
474{
475#ifdef HAVE_FORK
476 PyOS_AfterFork_Child();
477#endif
478}
479
480
Victor Stinner6036e442015-03-08 01:58:04 +0100481#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200482/* defined in fileutils.c */
483PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
484PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
485 ULONG, struct _Py_stat_struct *);
486#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700487
488#ifdef MS_WINDOWS
489static int
490win32_warn_bytes_api()
491{
492 return PyErr_WarnEx(PyExc_DeprecationWarning,
493 "The Windows bytes API has been deprecated, "
494 "use Unicode filenames instead",
495 1);
496}
497#endif
498
499
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200500#ifndef MS_WINDOWS
501PyObject *
502_PyLong_FromUid(uid_t uid)
503{
504 if (uid == (uid_t)-1)
505 return PyLong_FromLong(-1);
506 return PyLong_FromUnsignedLong(uid);
507}
508
509PyObject *
510_PyLong_FromGid(gid_t gid)
511{
512 if (gid == (gid_t)-1)
513 return PyLong_FromLong(-1);
514 return PyLong_FromUnsignedLong(gid);
515}
516
517int
518_Py_Uid_Converter(PyObject *obj, void *p)
519{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 uid_t uid;
521 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200522 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200523 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524 unsigned long uresult;
525
526 index = PyNumber_Index(obj);
527 if (index == NULL) {
528 PyErr_Format(PyExc_TypeError,
529 "uid should be integer, not %.200s",
530 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200531 return 0;
532 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533
534 /*
535 * Handling uid_t is complicated for two reasons:
536 * * Although uid_t is (always?) unsigned, it still
537 * accepts -1.
538 * * We don't know its size in advance--it may be
539 * bigger than an int, or it may be smaller than
540 * a long.
541 *
542 * So a bit of defensive programming is in order.
543 * Start with interpreting the value passed
544 * in as a signed long and see if it works.
545 */
546
547 result = PyLong_AsLongAndOverflow(index, &overflow);
548
549 if (!overflow) {
550 uid = (uid_t)result;
551
552 if (result == -1) {
553 if (PyErr_Occurred())
554 goto fail;
555 /* It's a legitimate -1, we're done. */
556 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200557 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700558
559 /* Any other negative number is disallowed. */
560 if (result < 0)
561 goto underflow;
562
563 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200564 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700565 (long)uid != result)
566 goto underflow;
567 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569
570 if (overflow < 0)
571 goto underflow;
572
573 /*
574 * Okay, the value overflowed a signed long. If it
575 * fits in an *unsigned* long, it may still be okay,
576 * as uid_t may be unsigned long on this platform.
577 */
578 uresult = PyLong_AsUnsignedLong(index);
579 if (PyErr_Occurred()) {
580 if (PyErr_ExceptionMatches(PyExc_OverflowError))
581 goto overflow;
582 goto fail;
583 }
584
585 uid = (uid_t)uresult;
586
587 /*
588 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
589 * but this value would get interpreted as (uid_t)-1 by chown
590 * and its siblings. That's not what the user meant! So we
591 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100592 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700593 */
594 if (uid == (uid_t)-1)
595 goto overflow;
596
597 /* Ensure the value wasn't truncated. */
598 if (sizeof(uid_t) < sizeof(long) &&
599 (unsigned long)uid != uresult)
600 goto overflow;
601 /* fallthrough */
602
603success:
604 Py_DECREF(index);
605 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200606 return 1;
607
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700608underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200609 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700610 "uid is less than minimum");
611 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200612
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700613overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200614 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700615 "uid is greater than maximum");
616 /* fallthrough */
617
618fail:
619 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 return 0;
621}
622
623int
624_Py_Gid_Converter(PyObject *obj, void *p)
625{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700626 gid_t gid;
627 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200628 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200629 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700630 unsigned long uresult;
631
632 index = PyNumber_Index(obj);
633 if (index == NULL) {
634 PyErr_Format(PyExc_TypeError,
635 "gid should be integer, not %.200s",
636 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200637 return 0;
638 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700639
640 /*
641 * Handling gid_t is complicated for two reasons:
642 * * Although gid_t is (always?) unsigned, it still
643 * accepts -1.
644 * * We don't know its size in advance--it may be
645 * bigger than an int, or it may be smaller than
646 * a long.
647 *
648 * So a bit of defensive programming is in order.
649 * Start with interpreting the value passed
650 * in as a signed long and see if it works.
651 */
652
653 result = PyLong_AsLongAndOverflow(index, &overflow);
654
655 if (!overflow) {
656 gid = (gid_t)result;
657
658 if (result == -1) {
659 if (PyErr_Occurred())
660 goto fail;
661 /* It's a legitimate -1, we're done. */
662 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200663 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700664
665 /* Any other negative number is disallowed. */
666 if (result < 0) {
667 goto underflow;
668 }
669
670 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700672 (long)gid != result)
673 goto underflow;
674 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200675 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700676
677 if (overflow < 0)
678 goto underflow;
679
680 /*
681 * Okay, the value overflowed a signed long. If it
682 * fits in an *unsigned* long, it may still be okay,
683 * as gid_t may be unsigned long on this platform.
684 */
685 uresult = PyLong_AsUnsignedLong(index);
686 if (PyErr_Occurred()) {
687 if (PyErr_ExceptionMatches(PyExc_OverflowError))
688 goto overflow;
689 goto fail;
690 }
691
692 gid = (gid_t)uresult;
693
694 /*
695 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
696 * but this value would get interpreted as (gid_t)-1 by chown
697 * and its siblings. That's not what the user meant! So we
698 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100699 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700700 */
701 if (gid == (gid_t)-1)
702 goto overflow;
703
704 /* Ensure the value wasn't truncated. */
705 if (sizeof(gid_t) < sizeof(long) &&
706 (unsigned long)gid != uresult)
707 goto overflow;
708 /* fallthrough */
709
710success:
711 Py_DECREF(index);
712 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200713 return 1;
714
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700715underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200716 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700717 "gid is less than minimum");
718 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200719
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700720overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200721 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700722 "gid is greater than maximum");
723 /* fallthrough */
724
725fail:
726 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200727 return 0;
728}
729#endif /* MS_WINDOWS */
730
731
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700732#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800733
734
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200735#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
736static int
737_Py_Dev_Converter(PyObject *obj, void *p)
738{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200739 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200740 if (PyErr_Occurred())
741 return 0;
742 return 1;
743}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800744#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200745
746
Larry Hastings9cf065c2012-06-22 16:30:09 -0700747#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400748/*
749 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
750 * without the int cast, the value gets interpreted as uint (4291925331),
751 * which doesn't play nicely with all the initializer lines in this file that
752 * look like this:
753 * int dir_fd = DEFAULT_DIR_FD;
754 */
755#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700756#else
757#define DEFAULT_DIR_FD (-100)
758#endif
759
760static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300761_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200762{
763 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700764 long long_value;
765
766 PyObject *index = PyNumber_Index(o);
767 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700768 return 0;
769 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700770
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300771 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700772 long_value = PyLong_AsLongAndOverflow(index, &overflow);
773 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300774 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200775 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700776 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700777 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700778 return 0;
779 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200780 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700782 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783 return 0;
784 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700785
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 *p = (int)long_value;
787 return 1;
788}
789
790static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200791dir_fd_converter(PyObject *o, void *p)
792{
793 if (o == Py_None) {
794 *(int *)p = DEFAULT_DIR_FD;
795 return 1;
796 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300797 else if (PyIndex_Check(o)) {
798 return _fd_converter(o, (int *)p);
799 }
800 else {
801 PyErr_Format(PyExc_TypeError,
802 "argument should be integer or None, not %.200s",
803 Py_TYPE(o)->tp_name);
804 return 0;
805 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700806}
807
808
Larry Hastings9cf065c2012-06-22 16:30:09 -0700809/*
810 * A PyArg_ParseTuple "converter" function
811 * that handles filesystem paths in the manner
812 * preferred by the os module.
813 *
814 * path_converter accepts (Unicode) strings and their
815 * subclasses, and bytes and their subclasses. What
816 * it does with the argument depends on the platform:
817 *
818 * * On Windows, if we get a (Unicode) string we
819 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700820 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700821 *
822 * * On all other platforms, strings are encoded
823 * to bytes using PyUnicode_FSConverter, then we
824 * extract the char * from the bytes object and
825 * return that.
826 *
827 * path_converter also optionally accepts signed
828 * integers (representing open file descriptors) instead
829 * of path strings.
830 *
831 * Input fields:
832 * path.nullable
833 * If nonzero, the path is permitted to be None.
834 * path.allow_fd
835 * If nonzero, the path is permitted to be a file handle
836 * (a signed int) instead of a string.
837 * path.function_name
838 * If non-NULL, path_converter will use that as the name
839 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700840 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700841 * path.argument_name
842 * If non-NULL, path_converter will use that as the name
843 * of the parameter in error messages.
844 * (If path.argument_name is NULL it uses "path".)
845 *
846 * Output fields:
847 * path.wide
848 * Points to the path if it was expressed as Unicode
849 * and was not encoded. (Only used on Windows.)
850 * path.narrow
851 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700852 * or it was Unicode and was encoded to bytes. (On Windows,
Martin Panterb1321fb2016-10-10 00:38:21 +0000853 * is a non-zero integer if the path was expressed as bytes.
Steve Dowercc16be82016-09-08 10:35:16 -0700854 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700855 * path.fd
856 * Contains a file descriptor if path.accept_fd was true
857 * and the caller provided a signed integer instead of any
858 * sort of string.
859 *
860 * WARNING: if your "path" parameter is optional, and is
861 * unspecified, path_converter will never get called.
862 * So if you set allow_fd, you *MUST* initialize path.fd = -1
863 * yourself!
864 * path.length
865 * The length of the path in characters, if specified as
866 * a string.
867 * path.object
Xiang Zhang04316c42017-01-08 23:26:57 +0800868 * The original object passed in (if get a PathLike object,
869 * the result of PyOS_FSPath() is treated as the original object).
870 * Own a reference to the object.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 * path.cleanup
872 * For internal use only. May point to a temporary object.
873 * (Pay no attention to the man behind the curtain.)
874 *
875 * At most one of path.wide or path.narrow will be non-NULL.
876 * If path was None and path.nullable was set,
877 * or if path was an integer and path.allow_fd was set,
878 * both path.wide and path.narrow will be NULL
879 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200880 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881 * path_converter takes care to not write to the path_t
882 * unless it's successful. However it must reset the
883 * "cleanup" field each time it's called.
884 *
885 * Use as follows:
886 * path_t path;
887 * memset(&path, 0, sizeof(path));
888 * PyArg_ParseTuple(args, "O&", path_converter, &path);
889 * // ... use values from path ...
890 * path_cleanup(&path);
891 *
892 * (Note that if PyArg_Parse fails you don't need to call
893 * path_cleanup(). However it is safe to do so.)
894 */
895typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100896 const char *function_name;
897 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700898 int nullable;
899 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300900 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700901#ifdef MS_WINDOWS
902 BOOL narrow;
903#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300904 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700905#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700906 int fd;
907 Py_ssize_t length;
908 PyObject *object;
909 PyObject *cleanup;
910} path_t;
911
Steve Dowercc16be82016-09-08 10:35:16 -0700912#ifdef MS_WINDOWS
913#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
914 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
915#else
Larry Hastings2f936352014-08-05 14:04:04 +1000916#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
917 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700918#endif
Larry Hastings31826802013-10-19 00:09:25 -0700919
Larry Hastings9cf065c2012-06-22 16:30:09 -0700920static void
Xiang Zhang04316c42017-01-08 23:26:57 +0800921path_cleanup(path_t *path)
922{
923 Py_CLEAR(path->object);
924 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925}
926
927static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300928path_converter(PyObject *o, void *p)
929{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 path_t *path = (path_t *)p;
Xiang Zhang04316c42017-01-08 23:26:57 +0800931 PyObject *bytes = NULL;
932 Py_ssize_t length = 0;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700933 int is_index, is_buffer, is_bytes, is_unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300934 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700935#ifdef MS_WINDOWS
Xiang Zhang04316c42017-01-08 23:26:57 +0800936 PyObject *wo = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700937 const wchar_t *wide;
938#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700939
940#define FORMAT_EXCEPTION(exc, fmt) \
941 PyErr_Format(exc, "%s%s" fmt, \
942 path->function_name ? path->function_name : "", \
943 path->function_name ? ": " : "", \
944 path->argument_name ? path->argument_name : "path")
945
946 /* Py_CLEANUP_SUPPORTED support */
947 if (o == NULL) {
948 path_cleanup(path);
949 return 1;
950 }
951
Brett Cannon3f9183b2016-08-26 14:44:48 -0700952 /* Ensure it's always safe to call path_cleanup(). */
Xiang Zhang04316c42017-01-08 23:26:57 +0800953 path->object = path->cleanup = NULL;
954 /* path->object owns a reference to the original object */
955 Py_INCREF(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700956
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300957 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700959#ifdef MS_WINDOWS
960 path->narrow = FALSE;
961#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700963#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +0800965 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 }
967
Brett Cannon3f9183b2016-08-26 14:44:48 -0700968 /* Only call this here so that we don't treat the return value of
969 os.fspath() as an fd or buffer. */
970 is_index = path->allow_fd && PyIndex_Check(o);
971 is_buffer = PyObject_CheckBuffer(o);
972 is_bytes = PyBytes_Check(o);
973 is_unicode = PyUnicode_Check(o);
974
975 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
976 /* Inline PyOS_FSPath() for better error messages. */
977 _Py_IDENTIFIER(__fspath__);
978 PyObject *func = NULL;
979
980 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
981 if (NULL == func) {
Xiang Zhang04316c42017-01-08 23:26:57 +0800982 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700983 }
Xiang Zhang04316c42017-01-08 23:26:57 +0800984 /* still owns a reference to the original object */
985 Py_DECREF(o);
986 o = _PyObject_CallNoArg(func);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 Py_DECREF(func);
988 if (NULL == o) {
989 goto error_exit;
990 }
991 else if (PyUnicode_Check(o)) {
992 is_unicode = 1;
993 }
994 else if (PyBytes_Check(o)) {
995 is_bytes = 1;
996 }
997 else {
Xiang Zhang04316c42017-01-08 23:26:57 +0800998 goto error_format;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700999 }
1000 }
1001
1002 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003#ifdef MS_WINDOWS
Victor Stinner26c03bd2016-09-19 11:55:44 +02001004 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +01001005 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001006 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 }
Victor Stinner59799a82013-11-13 14:17:30 +01001008 if (length > 32767) {
1009 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001010 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001012 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001013 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001014 goto error_exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001015 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001016
1017 path->wide = wide;
Xiang Zhang04316c42017-01-08 23:26:57 +08001018 path->narrow = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001019 path->fd = -1;
Xiang Zhang04316c42017-01-08 23:26:57 +08001020 goto success_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001022 if (!PyUnicode_FSConverter(o, &bytes)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001023 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001024 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025#endif
1026 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001027 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001028 bytes = o;
1029 Py_INCREF(bytes);
1030 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001031 else if (is_buffer) {
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03001032 /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
Ville Skyttä49b27342017-08-03 09:00:59 +03001033 after removing support of non-bytes buffer objects. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001034 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
1035 "%s%s%s should be %s, not %.200s",
1036 path->function_name ? path->function_name : "",
1037 path->function_name ? ": " : "",
1038 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001039 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1040 "integer or None" :
1041 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1042 path->nullable ? "string, bytes, os.PathLike or None" :
1043 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001044 Py_TYPE(o)->tp_name)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001045 goto error_exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001046 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001047 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001048 if (!bytes) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001049 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 }
1051 }
Steve Dowercc16be82016-09-08 10:35:16 -07001052 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001053 if (!_fd_converter(o, &path->fd)) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001054 goto error_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001055 }
1056 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001057#ifdef MS_WINDOWS
1058 path->narrow = FALSE;
1059#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001060 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07001061#endif
Xiang Zhang04316c42017-01-08 23:26:57 +08001062 goto success_exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001063 }
1064 else {
Xiang Zhang04316c42017-01-08 23:26:57 +08001065 error_format:
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001066 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
1067 path->function_name ? path->function_name : "",
1068 path->function_name ? ": " : "",
1069 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -07001070 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
1071 "integer or None" :
1072 path->allow_fd ? "string, bytes, os.PathLike or integer" :
1073 path->nullable ? "string, bytes, os.PathLike or None" :
1074 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +03001075 Py_TYPE(o)->tp_name);
Xiang Zhang04316c42017-01-08 23:26:57 +08001076 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001077 }
1078
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001080 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001081 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001082 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001083 goto error_exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 }
1085
Steve Dowercc16be82016-09-08 10:35:16 -07001086#ifdef MS_WINDOWS
1087 wo = PyUnicode_DecodeFSDefaultAndSize(
1088 narrow,
1089 length
1090 );
1091 if (!wo) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001092 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001093 }
1094
Xiang Zhang04316c42017-01-08 23:26:57 +08001095 wide = PyUnicode_AsUnicodeAndSize(wo, &length);
Steve Dowercc16be82016-09-08 10:35:16 -07001096 if (!wide) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001097 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001098 }
1099 if (length > 32767) {
1100 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Xiang Zhang04316c42017-01-08 23:26:57 +08001101 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001102 }
1103 if (wcslen(wide) != length) {
1104 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Xiang Zhang04316c42017-01-08 23:26:57 +08001105 goto error_exit;
Steve Dowercc16be82016-09-08 10:35:16 -07001106 }
1107 path->wide = wide;
1108 path->narrow = TRUE;
Xiang Zhang04316c42017-01-08 23:26:57 +08001109 path->cleanup = wo;
1110 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07001111#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001112 path->wide = NULL;
1113 path->narrow = narrow;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001114 if (bytes == o) {
Xiang Zhang04316c42017-01-08 23:26:57 +08001115 /* Still a reference owned by path->object, don't have to
1116 worry about path->narrow is used after free. */
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001117 Py_DECREF(bytes);
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001118 }
1119 else {
1120 path->cleanup = bytes;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001121 }
Xiang Zhang04316c42017-01-08 23:26:57 +08001122#endif
1123 path->fd = -1;
1124
1125 success_exit:
1126 path->length = length;
1127 path->object = o;
1128 return Py_CLEANUP_SUPPORTED;
1129
1130 error_exit:
1131 Py_XDECREF(o);
1132 Py_XDECREF(bytes);
1133#ifdef MS_WINDOWS
1134 Py_XDECREF(wo);
1135#endif
1136 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001137}
1138
1139static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001140argument_unavailable_error(const char *function_name, const char *argument_name)
1141{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001142 PyErr_Format(PyExc_NotImplementedError,
1143 "%s%s%s unavailable on this platform",
1144 (function_name != NULL) ? function_name : "",
1145 (function_name != NULL) ? ": ": "",
1146 argument_name);
1147}
1148
1149static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001150dir_fd_unavailable(PyObject *o, void *p)
1151{
1152 int dir_fd;
1153 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001154 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001155 if (dir_fd != DEFAULT_DIR_FD) {
1156 argument_unavailable_error(NULL, "dir_fd");
1157 return 0;
1158 }
1159 *(int *)p = dir_fd;
1160 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161}
1162
1163static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001164fd_specified(const char *function_name, int fd)
1165{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001166 if (fd == -1)
1167 return 0;
1168
1169 argument_unavailable_error(function_name, "fd");
1170 return 1;
1171}
1172
1173static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001174follow_symlinks_specified(const char *function_name, int follow_symlinks)
1175{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001176 if (follow_symlinks)
1177 return 0;
1178
1179 argument_unavailable_error(function_name, "follow_symlinks");
1180 return 1;
1181}
1182
1183static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001184path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1185{
Steve Dowercc16be82016-09-08 10:35:16 -07001186 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1187#ifndef MS_WINDOWS
1188 && !path->narrow
1189#endif
1190 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001191 PyErr_Format(PyExc_ValueError,
1192 "%s: can't specify dir_fd without matching path",
1193 function_name);
1194 return 1;
1195 }
1196 return 0;
1197}
1198
1199static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001200dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1201{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001202 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1203 PyErr_Format(PyExc_ValueError,
1204 "%s: can't specify both dir_fd and fd",
1205 function_name);
1206 return 1;
1207 }
1208 return 0;
1209}
1210
1211static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001212fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1213 int follow_symlinks)
1214{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001215 if ((fd > 0) && (!follow_symlinks)) {
1216 PyErr_Format(PyExc_ValueError,
1217 "%s: cannot use fd and follow_symlinks together",
1218 function_name);
1219 return 1;
1220 }
1221 return 0;
1222}
1223
1224static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001225dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1226 int follow_symlinks)
1227{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001228 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1229 PyErr_Format(PyExc_ValueError,
1230 "%s: cannot use dir_fd and follow_symlinks together",
1231 function_name);
1232 return 1;
1233 }
1234 return 0;
1235}
1236
Larry Hastings2f936352014-08-05 14:04:04 +10001237#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001238 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001239#else
Larry Hastings2f936352014-08-05 14:04:04 +10001240 typedef off_t Py_off_t;
1241#endif
1242
1243static int
1244Py_off_t_converter(PyObject *arg, void *addr)
1245{
1246#ifdef HAVE_LARGEFILE_SUPPORT
1247 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1248#else
1249 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001250#endif
1251 if (PyErr_Occurred())
1252 return 0;
1253 return 1;
1254}
Larry Hastings2f936352014-08-05 14:04:04 +10001255
1256static PyObject *
1257PyLong_FromPy_off_t(Py_off_t offset)
1258{
1259#ifdef HAVE_LARGEFILE_SUPPORT
1260 return PyLong_FromLongLong(offset);
1261#else
1262 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001263#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001264}
1265
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001266#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001267
1268static int
Brian Curtind25aef52011-06-13 15:16:04 -05001269win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001270{
Martin Panter70214ad2016-08-04 02:38:59 +00001271 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1272 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274
1275 if (0 == DeviceIoControl(
1276 reparse_point_handle,
1277 FSCTL_GET_REPARSE_POINT,
1278 NULL, 0, /* in buffer */
1279 target_buffer, sizeof(target_buffer),
1280 &n_bytes_returned,
1281 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001282 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001283
1284 if (reparse_tag)
1285 *reparse_tag = rdb->ReparseTag;
1286
Brian Curtind25aef52011-06-13 15:16:04 -05001287 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001288}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001289
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001290#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001291
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001293#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001294/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001295** environ directly, we must obtain it with _NSGetEnviron(). See also
1296** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001297*/
1298#include <crt_externs.h>
1299static char **environ;
1300#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001302#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303
Barry Warsaw53699e91996-12-10 23:23:01 +00001304static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001305convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
Victor Stinner8c62be82010-05-06 00:08:46 +00001307 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001308#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001310#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001312#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001313
Victor Stinner8c62be82010-05-06 00:08:46 +00001314 d = PyDict_New();
1315 if (d == NULL)
1316 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001317#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 if (environ == NULL)
1319 environ = *_NSGetEnviron();
1320#endif
1321#ifdef MS_WINDOWS
1322 /* _wenviron must be initialized in this way if the program is started
1323 through main() instead of wmain(). */
1324 _wgetenv(L"");
1325 if (_wenviron == NULL)
1326 return d;
1327 /* This part ignores errors */
1328 for (e = _wenviron; *e != NULL; e++) {
1329 PyObject *k;
1330 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001331 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 if (p == NULL)
1333 continue;
1334 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1335 if (k == NULL) {
1336 PyErr_Clear();
1337 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001338 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001339 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1340 if (v == NULL) {
1341 PyErr_Clear();
1342 Py_DECREF(k);
1343 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001344 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 if (PyDict_GetItem(d, k) == NULL) {
1346 if (PyDict_SetItem(d, k, v) != 0)
1347 PyErr_Clear();
1348 }
1349 Py_DECREF(k);
1350 Py_DECREF(v);
1351 }
1352#else
1353 if (environ == NULL)
1354 return d;
1355 /* This part ignores errors */
1356 for (e = environ; *e != NULL; e++) {
1357 PyObject *k;
1358 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001359 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 if (p == NULL)
1361 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001362 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 if (k == NULL) {
1364 PyErr_Clear();
1365 continue;
1366 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001367 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 if (v == NULL) {
1369 PyErr_Clear();
1370 Py_DECREF(k);
1371 continue;
1372 }
1373 if (PyDict_GetItem(d, k) == NULL) {
1374 if (PyDict_SetItem(d, k, v) != 0)
1375 PyErr_Clear();
1376 }
1377 Py_DECREF(k);
1378 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001379 }
1380#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001382}
1383
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001384/* Set a POSIX-specific error from errno, and return NULL */
1385
Barry Warsawd58d7641998-07-23 16:14:40 +00001386static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001387posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001388{
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390}
Mark Hammondef8b6542001-05-13 08:04:26 +00001391
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001392#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001393static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001394win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001395{
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 /* XXX We should pass the function name along in the future.
1397 (winreg.c also wants to pass the function name.)
1398 This would however require an additional param to the
1399 Windows error object, which is non-trivial.
1400 */
1401 errno = GetLastError();
1402 if (filename)
1403 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1404 else
1405 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001406}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001407
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001408static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001409win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001410{
1411 /* XXX - see win32_error for comments on 'function' */
1412 errno = GetLastError();
1413 if (filename)
1414 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001415 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001416 errno,
1417 filename);
1418 else
1419 return PyErr_SetFromWindowsErr(errno);
1420}
1421
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001422#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423
Larry Hastings9cf065c2012-06-22 16:30:09 -07001424static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001425path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001426{
1427#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001428 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1429 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001430#else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001431 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432#endif
1433}
1434
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001435static PyObject *
1436path_object_error2(PyObject *path, PyObject *path2)
1437{
1438#ifdef MS_WINDOWS
1439 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1440 PyExc_OSError, 0, path, path2);
1441#else
1442 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1443#endif
1444}
1445
1446static PyObject *
1447path_error(path_t *path)
1448{
1449 return path_object_error(path->object);
1450}
Larry Hastings31826802013-10-19 00:09:25 -07001451
Larry Hastingsb0827312014-02-09 22:05:19 -08001452static PyObject *
1453path_error2(path_t *path, path_t *path2)
1454{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001455 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001456}
1457
1458
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001459/* POSIX generic methods */
1460
Larry Hastings2f936352014-08-05 14:04:04 +10001461static int
1462fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001463{
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001465 int *pointer = (int *)p;
1466 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001467 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001468 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001469 *pointer = fd;
1470 return 1;
1471}
1472
1473static PyObject *
1474posix_fildes_fd(int fd, int (*func)(int))
1475{
1476 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001477 int async_err = 0;
1478
1479 do {
1480 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001481 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001482 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001483 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001484 Py_END_ALLOW_THREADS
1485 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1486 if (res != 0)
1487 return (!async_err) ? posix_error() : NULL;
1488 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001489}
Guido van Rossum21142a01999-01-08 21:05:37 +00001490
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001491
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001492#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001493/* This is a reimplementation of the C library's chdir function,
1494 but one that produces Win32 errors instead of DOS error codes.
1495 chdir is essentially a wrapper around SetCurrentDirectory; however,
1496 it also needs to set "magic" environment variables indicating
1497 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001498static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499win32_wchdir(LPCWSTR path)
1500{
Victor Stinnered537822015-12-13 21:40:26 +01001501 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001502 int result;
1503 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001504
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 if(!SetCurrentDirectoryW(path))
1506 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001507 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 if (!result)
1509 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001510 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001511 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001512 if (!new_path) {
1513 SetLastError(ERROR_OUTOFMEMORY);
1514 return FALSE;
1515 }
1516 result = GetCurrentDirectoryW(result, new_path);
1517 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001518 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 return FALSE;
1520 }
1521 }
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001522 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1523 wcsncmp(new_path, L"//", 2) == 0);
1524 if (!is_unc_like_path) {
1525 env[1] = new_path[0];
1526 result = SetEnvironmentVariableW(env, new_path);
1527 }
Victor Stinnered537822015-12-13 21:40:26 +01001528 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001529 PyMem_RawFree(new_path);
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001530 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531}
1532#endif
1533
Martin v. Löwis14694662006-02-03 12:54:16 +00001534#ifdef MS_WINDOWS
1535/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1536 - time stamps are restricted to second resolution
1537 - file modification times suffer from forth-and-back conversions between
1538 UTC and local time
1539 Therefore, we implement our own stat, based on the Win32 API directly.
1540*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001541#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001542#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001543
Victor Stinner6036e442015-03-08 01:58:04 +01001544static void
Steve Dowercc16be82016-09-08 10:35:16 -07001545find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1546 BY_HANDLE_FILE_INFORMATION *info,
1547 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001548{
1549 memset(info, 0, sizeof(*info));
1550 info->dwFileAttributes = pFileData->dwFileAttributes;
1551 info->ftCreationTime = pFileData->ftCreationTime;
1552 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1553 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1554 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1555 info->nFileSizeLow = pFileData->nFileSizeLow;
1556/* info->nNumberOfLinks = 1; */
1557 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1558 *reparse_tag = pFileData->dwReserved0;
1559 else
1560 *reparse_tag = 0;
1561}
1562
Guido van Rossumd8faa362007-04-27 19:54:29 +00001563static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001564attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001565{
Victor Stinner8c62be82010-05-06 00:08:46 +00001566 HANDLE hFindFile;
1567 WIN32_FIND_DATAW FileData;
1568 hFindFile = FindFirstFileW(pszFile, &FileData);
1569 if (hFindFile == INVALID_HANDLE_VALUE)
1570 return FALSE;
1571 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001572 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001573 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001574}
1575
Brian Curtind25aef52011-06-13 15:16:04 -05001576static BOOL
1577get_target_path(HANDLE hdl, wchar_t **target_path)
1578{
1579 int buf_size, result_length;
1580 wchar_t *buf;
1581
1582 /* We have a good handle to the target, use it to determine
1583 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001584 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1585 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001586 if(!buf_size)
1587 return FALSE;
1588
Victor Stinnerc36674a2016-03-16 14:30:16 +01001589 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001590 if (!buf) {
1591 SetLastError(ERROR_OUTOFMEMORY);
1592 return FALSE;
1593 }
1594
Steve Dower2ea51c92015-03-20 21:49:12 -07001595 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001596 buf, buf_size, VOLUME_NAME_DOS);
1597
1598 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001599 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001600 return FALSE;
1601 }
1602
1603 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001604 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001605 return FALSE;
1606 }
1607
1608 buf[result_length] = 0;
1609
1610 *target_path = buf;
1611 return TRUE;
1612}
1613
1614static int
Steve Dowercc16be82016-09-08 10:35:16 -07001615win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001616 BOOL traverse)
1617{
Victor Stinner26de69d2011-06-17 15:15:38 +02001618 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001619 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001620 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001621 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001622 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001623 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624
Steve Dowercc16be82016-09-08 10:35:16 -07001625 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001627 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001628 0, /* share mode */
1629 NULL, /* security attributes */
1630 OPEN_EXISTING,
1631 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001632 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1633 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001634 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001635 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1636 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001637 NULL);
1638
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001639 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001640 /* Either the target doesn't exist, or we don't have access to
1641 get a handle to it. If the former, we need to return an error.
1642 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001643 DWORD lastError = GetLastError();
1644 if (lastError != ERROR_ACCESS_DENIED &&
1645 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001646 return -1;
1647 /* Could not get attributes on open file. Fall back to
1648 reading the directory. */
1649 if (!attributes_from_dir(path, &info, &reparse_tag))
1650 /* Very strange. This should not fail now */
1651 return -1;
1652 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1653 if (traverse) {
1654 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001655 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001656 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001658 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001659 } else {
1660 if (!GetFileInformationByHandle(hFile, &info)) {
1661 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001662 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001663 }
1664 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001665 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1666 return -1;
1667
1668 /* Close the outer open file handle now that we're about to
1669 reopen it with different flags. */
1670 if (!CloseHandle(hFile))
1671 return -1;
1672
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001673 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001674 /* In order to call GetFinalPathNameByHandle we need to open
1675 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001676 hFile2 = CreateFileW(
1677 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1678 NULL, OPEN_EXISTING,
1679 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1680 NULL);
1681 if (hFile2 == INVALID_HANDLE_VALUE)
1682 return -1;
1683
1684 if (!get_target_path(hFile2, &target_path))
1685 return -1;
1686
Steve Dowercc16be82016-09-08 10:35:16 -07001687 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001688 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001689 return code;
1690 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001691 } else
1692 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001694 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001695
1696 /* Set S_IEXEC if it is an .exe, .bat, ... */
1697 dot = wcsrchr(path, '.');
1698 if (dot) {
1699 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1700 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1701 result->st_mode |= 0111;
1702 }
1703 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001704}
1705
1706static int
Steve Dowercc16be82016-09-08 10:35:16 -07001707win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001708{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 /* Protocol violation: we explicitly clear errno, instead of
1710 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001711 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001712 errno = 0;
1713 return code;
1714}
Brian Curtind25aef52011-06-13 15:16:04 -05001715/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001716
1717 In Posix, stat automatically traverses symlinks and returns the stat
1718 structure for the target. In Windows, the equivalent GetFileAttributes by
1719 default does not traverse symlinks and instead returns attributes for
1720 the symlink.
1721
1722 Therefore, win32_lstat will get the attributes traditionally, and
1723 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001724 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001725
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001726static int
Steve Dowercc16be82016-09-08 10:35:16 -07001727win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001728{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001729 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001730}
1731
Victor Stinner8c62be82010-05-06 00:08:46 +00001732static int
Steve Dowercc16be82016-09-08 10:35:16 -07001733win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001734{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001735 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001736}
1737
Martin v. Löwis14694662006-02-03 12:54:16 +00001738#endif /* MS_WINDOWS */
1739
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001740PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001741"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001742This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001743 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001744or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1745\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001746Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1747or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001748\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001749See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750
1751static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001752 {"st_mode", "protection bits"},
1753 {"st_ino", "inode"},
1754 {"st_dev", "device"},
1755 {"st_nlink", "number of hard links"},
1756 {"st_uid", "user ID of owner"},
1757 {"st_gid", "group ID of owner"},
1758 {"st_size", "total size, in bytes"},
1759 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1760 {NULL, "integer time of last access"},
1761 {NULL, "integer time of last modification"},
1762 {NULL, "integer time of last change"},
1763 {"st_atime", "time of last access"},
1764 {"st_mtime", "time of last modification"},
1765 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001766 {"st_atime_ns", "time of last access in nanoseconds"},
1767 {"st_mtime_ns", "time of last modification in nanoseconds"},
1768 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001769#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001771#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001772#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001774#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001775#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001778#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001780#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001781#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001783#endif
1784#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001786#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001787#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1788 {"st_file_attributes", "Windows file attribute bits"},
1789#endif
jcea6c51d512018-01-28 14:00:08 +01001790#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1791 {"st_fstype", "Type of filesystem"},
1792#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001794};
1795
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001796#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001797#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001798#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001799#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001800#endif
1801
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001802#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001803#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1804#else
1805#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1806#endif
1807
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001808#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001809#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1810#else
1811#define ST_RDEV_IDX ST_BLOCKS_IDX
1812#endif
1813
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001814#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1815#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1816#else
1817#define ST_FLAGS_IDX ST_RDEV_IDX
1818#endif
1819
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001820#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001821#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001822#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001823#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001824#endif
1825
1826#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1827#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1828#else
1829#define ST_BIRTHTIME_IDX ST_GEN_IDX
1830#endif
1831
Zachary Ware63f277b2014-06-19 09:46:37 -05001832#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1833#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1834#else
1835#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1836#endif
1837
jcea6c51d512018-01-28 14:00:08 +01001838#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1839#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1840#else
1841#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1842#endif
1843
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001844static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001845 "stat_result", /* name */
1846 stat_result__doc__, /* doc */
1847 stat_result_fields,
1848 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849};
1850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001852"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1853This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001854 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001855or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001858
1859static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001860 {"f_bsize", },
1861 {"f_frsize", },
1862 {"f_blocks", },
1863 {"f_bfree", },
1864 {"f_bavail", },
1865 {"f_files", },
1866 {"f_ffree", },
1867 {"f_favail", },
1868 {"f_flag", },
1869 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001870 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001872};
1873
1874static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001875 "statvfs_result", /* name */
1876 statvfs_result__doc__, /* doc */
1877 statvfs_result_fields,
1878 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879};
1880
Ross Lagerwall7807c352011-03-17 20:20:30 +02001881#if defined(HAVE_WAITID) && !defined(__APPLE__)
1882PyDoc_STRVAR(waitid_result__doc__,
1883"waitid_result: Result from waitid.\n\n\
1884This object may be accessed either as a tuple of\n\
1885 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1886or via the attributes si_pid, si_uid, and so on.\n\
1887\n\
1888See os.waitid for more information.");
1889
1890static PyStructSequence_Field waitid_result_fields[] = {
1891 {"si_pid", },
1892 {"si_uid", },
1893 {"si_signo", },
1894 {"si_status", },
1895 {"si_code", },
1896 {0}
1897};
1898
1899static PyStructSequence_Desc waitid_result_desc = {
1900 "waitid_result", /* name */
1901 waitid_result__doc__, /* doc */
1902 waitid_result_fields,
1903 5
1904};
1905static PyTypeObject WaitidResultType;
1906#endif
1907
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001908static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001909static PyTypeObject StatResultType;
1910static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001911#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001912static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001913#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001914static newfunc structseq_new;
1915
1916static PyObject *
1917statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1918{
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 PyStructSequence *result;
1920 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001921
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 result = (PyStructSequence*)structseq_new(type, args, kwds);
1923 if (!result)
1924 return NULL;
1925 /* If we have been initialized from a tuple,
1926 st_?time might be set to None. Initialize it
1927 from the int slots. */
1928 for (i = 7; i <= 9; i++) {
1929 if (result->ob_item[i+3] == Py_None) {
1930 Py_DECREF(Py_None);
1931 Py_INCREF(result->ob_item[i]);
1932 result->ob_item[i+3] = result->ob_item[i];
1933 }
1934 }
1935 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001936}
1937
1938
Larry Hastings6fe20b32012-04-19 15:07:49 -07001939static PyObject *billion = NULL;
1940
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001941static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001942fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001943{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001944 PyObject *s = _PyLong_FromTime_t(sec);
1945 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1946 PyObject *s_in_ns = NULL;
1947 PyObject *ns_total = NULL;
1948 PyObject *float_s = NULL;
1949
1950 if (!(s && ns_fractional))
1951 goto exit;
1952
1953 s_in_ns = PyNumber_Multiply(s, billion);
1954 if (!s_in_ns)
1955 goto exit;
1956
1957 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1958 if (!ns_total)
1959 goto exit;
1960
Victor Stinner01b5aab2017-10-24 02:02:00 -07001961 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1962 if (!float_s) {
1963 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001964 }
1965
1966 PyStructSequence_SET_ITEM(v, index, s);
1967 PyStructSequence_SET_ITEM(v, index+3, float_s);
1968 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1969 s = NULL;
1970 float_s = NULL;
1971 ns_total = NULL;
1972exit:
1973 Py_XDECREF(s);
1974 Py_XDECREF(ns_fractional);
1975 Py_XDECREF(s_in_ns);
1976 Py_XDECREF(ns_total);
1977 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001978}
1979
Tim Peters5aa91602002-01-30 05:46:57 +00001980/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001981 (used by posix_stat() and posix_fstat()) */
1982static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001983_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001984{
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 unsigned long ansec, mnsec, cnsec;
1986 PyObject *v = PyStructSequence_New(&StatResultType);
1987 if (v == NULL)
1988 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001989
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01001991 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02001992 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001993#ifdef MS_WINDOWS
1994 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001995#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001996 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001997#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001998 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001999#if defined(MS_WINDOWS)
2000 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2001 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2002#else
2003 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2004 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2005#endif
xdegaye50e86032017-05-22 11:15:08 +02002006 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2007 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002008
Martin v. Löwis14694662006-02-03 12:54:16 +00002009#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 ansec = st->st_atim.tv_nsec;
2011 mnsec = st->st_mtim.tv_nsec;
2012 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002013#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 ansec = st->st_atimespec.tv_nsec;
2015 mnsec = st->st_mtimespec.tv_nsec;
2016 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002017#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002018 ansec = st->st_atime_nsec;
2019 mnsec = st->st_mtime_nsec;
2020 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002024 fill_time(v, 7, st->st_atime, ansec);
2025 fill_time(v, 8, st->st_mtime, mnsec);
2026 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002027
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002028#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2030 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002031#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002032#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2034 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002036#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2038 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002039#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002040#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2042 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002043#endif
2044#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002046 PyObject *val;
2047 unsigned long bsec,bnsec;
2048 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002049#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002050 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002051#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002052 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002053#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002054 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002055 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2056 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002058#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002059#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2061 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002062#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002063#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2064 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2065 PyLong_FromUnsignedLong(st->st_file_attributes));
2066#endif
jcea6c51d512018-01-28 14:00:08 +01002067#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2068 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2069 PyUnicode_FromString(st->st_fstype));
2070#endif
Fred Drake699f3522000-06-29 21:12:41 +00002071
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 if (PyErr_Occurred()) {
2073 Py_DECREF(v);
2074 return NULL;
2075 }
Fred Drake699f3522000-06-29 21:12:41 +00002076
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002078}
2079
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002080/* POSIX methods */
2081
Guido van Rossum94f6f721999-01-06 18:42:14 +00002082
2083static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002084posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002085 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002086{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002087 STRUCT_STAT st;
2088 int result;
2089
2090#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2091 if (follow_symlinks_specified(function_name, follow_symlinks))
2092 return NULL;
2093#endif
2094
2095 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2096 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2097 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2098 return NULL;
2099
2100 Py_BEGIN_ALLOW_THREADS
2101 if (path->fd != -1)
2102 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002103#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002104 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002105 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002106 else
Steve Dowercc16be82016-09-08 10:35:16 -07002107 result = win32_lstat(path->wide, &st);
2108#else
2109 else
2110#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002111 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2112 result = LSTAT(path->narrow, &st);
2113 else
Steve Dowercc16be82016-09-08 10:35:16 -07002114#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002115#ifdef HAVE_FSTATAT
2116 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2117 result = fstatat(dir_fd, path->narrow, &st,
2118 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2119 else
Steve Dowercc16be82016-09-08 10:35:16 -07002120#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002121 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002122#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002123 Py_END_ALLOW_THREADS
2124
Victor Stinner292c8352012-10-30 02:17:38 +01002125 if (result != 0) {
2126 return path_error(path);
2127 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002128
2129 return _pystat_fromstructstat(&st);
2130}
2131
Larry Hastings2f936352014-08-05 14:04:04 +10002132/*[python input]
2133
2134for s in """
2135
2136FACCESSAT
2137FCHMODAT
2138FCHOWNAT
2139FSTATAT
2140LINKAT
2141MKDIRAT
2142MKFIFOAT
2143MKNODAT
2144OPENAT
2145READLINKAT
2146SYMLINKAT
2147UNLINKAT
2148
2149""".strip().split():
2150 s = s.strip()
2151 print("""
2152#ifdef HAVE_{s}
2153 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002154#else
Larry Hastings2f936352014-08-05 14:04:04 +10002155 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002156#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002157""".rstrip().format(s=s))
2158
2159for s in """
2160
2161FCHDIR
2162FCHMOD
2163FCHOWN
2164FDOPENDIR
2165FEXECVE
2166FPATHCONF
2167FSTATVFS
2168FTRUNCATE
2169
2170""".strip().split():
2171 s = s.strip()
2172 print("""
2173#ifdef HAVE_{s}
2174 #define PATH_HAVE_{s} 1
2175#else
2176 #define PATH_HAVE_{s} 0
2177#endif
2178
2179""".rstrip().format(s=s))
2180[python start generated code]*/
2181
2182#ifdef HAVE_FACCESSAT
2183 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2184#else
2185 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2186#endif
2187
2188#ifdef HAVE_FCHMODAT
2189 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2190#else
2191 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2192#endif
2193
2194#ifdef HAVE_FCHOWNAT
2195 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_FSTATAT
2201 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_LINKAT
2207 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2208#else
2209 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2210#endif
2211
2212#ifdef HAVE_MKDIRAT
2213 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_MKFIFOAT
2219 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_MKNODAT
2225 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_OPENAT
2231 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_READLINKAT
2237 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_SYMLINKAT
2243 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_UNLINKAT
2249 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_FCHDIR
2255 #define PATH_HAVE_FCHDIR 1
2256#else
2257 #define PATH_HAVE_FCHDIR 0
2258#endif
2259
2260#ifdef HAVE_FCHMOD
2261 #define PATH_HAVE_FCHMOD 1
2262#else
2263 #define PATH_HAVE_FCHMOD 0
2264#endif
2265
2266#ifdef HAVE_FCHOWN
2267 #define PATH_HAVE_FCHOWN 1
2268#else
2269 #define PATH_HAVE_FCHOWN 0
2270#endif
2271
2272#ifdef HAVE_FDOPENDIR
2273 #define PATH_HAVE_FDOPENDIR 1
2274#else
2275 #define PATH_HAVE_FDOPENDIR 0
2276#endif
2277
2278#ifdef HAVE_FEXECVE
2279 #define PATH_HAVE_FEXECVE 1
2280#else
2281 #define PATH_HAVE_FEXECVE 0
2282#endif
2283
2284#ifdef HAVE_FPATHCONF
2285 #define PATH_HAVE_FPATHCONF 1
2286#else
2287 #define PATH_HAVE_FPATHCONF 0
2288#endif
2289
2290#ifdef HAVE_FSTATVFS
2291 #define PATH_HAVE_FSTATVFS 1
2292#else
2293 #define PATH_HAVE_FSTATVFS 0
2294#endif
2295
2296#ifdef HAVE_FTRUNCATE
2297 #define PATH_HAVE_FTRUNCATE 1
2298#else
2299 #define PATH_HAVE_FTRUNCATE 0
2300#endif
2301/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002302
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002303#ifdef MS_WINDOWS
2304 #undef PATH_HAVE_FTRUNCATE
2305 #define PATH_HAVE_FTRUNCATE 1
2306#endif
Larry Hastings31826802013-10-19 00:09:25 -07002307
Larry Hastings61272b72014-01-07 12:41:53 -08002308/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002309
2310class path_t_converter(CConverter):
2311
2312 type = "path_t"
2313 impl_by_reference = True
2314 parse_by_reference = True
2315
2316 converter = 'path_converter'
2317
2318 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002319 # right now path_t doesn't support default values.
2320 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002321 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002322 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002323
Larry Hastings2f936352014-08-05 14:04:04 +10002324 if self.c_default not in (None, 'Py_None'):
2325 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002326
2327 self.nullable = nullable
2328 self.allow_fd = allow_fd
2329
Larry Hastings7726ac92014-01-31 22:03:12 -08002330 def pre_render(self):
2331 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002332 if isinstance(value, str):
2333 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002334 return str(int(bool(value)))
2335
2336 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002337 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002338 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002339 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002340 strify(self.nullable),
2341 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002342 )
2343
2344 def cleanup(self):
2345 return "path_cleanup(&" + self.name + ");\n"
2346
2347
2348class dir_fd_converter(CConverter):
2349 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002350
Larry Hastings2f936352014-08-05 14:04:04 +10002351 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002352 if self.default in (unspecified, None):
2353 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002354 if isinstance(requires, str):
2355 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2356 else:
2357 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002358
Larry Hastings2f936352014-08-05 14:04:04 +10002359class fildes_converter(CConverter):
2360 type = 'int'
2361 converter = 'fildes_converter'
2362
2363class uid_t_converter(CConverter):
2364 type = "uid_t"
2365 converter = '_Py_Uid_Converter'
2366
2367class gid_t_converter(CConverter):
2368 type = "gid_t"
2369 converter = '_Py_Gid_Converter'
2370
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002371class dev_t_converter(CConverter):
2372 type = 'dev_t'
2373 converter = '_Py_Dev_Converter'
2374
2375class dev_t_return_converter(unsigned_long_return_converter):
2376 type = 'dev_t'
2377 conversion_fn = '_PyLong_FromDev'
2378 unsigned_cast = '(dev_t)'
2379
Larry Hastings2f936352014-08-05 14:04:04 +10002380class FSConverter_converter(CConverter):
2381 type = 'PyObject *'
2382 converter = 'PyUnicode_FSConverter'
2383 def converter_init(self):
2384 if self.default is not unspecified:
2385 fail("FSConverter_converter does not support default values")
2386 self.c_default = 'NULL'
2387
2388 def cleanup(self):
2389 return "Py_XDECREF(" + self.name + ");\n"
2390
2391class pid_t_converter(CConverter):
2392 type = 'pid_t'
2393 format_unit = '" _Py_PARSE_PID "'
2394
2395class idtype_t_converter(int_converter):
2396 type = 'idtype_t'
2397
2398class id_t_converter(CConverter):
2399 type = 'id_t'
2400 format_unit = '" _Py_PARSE_PID "'
2401
Benjamin Petersonca470632016-09-06 13:47:26 -07002402class intptr_t_converter(CConverter):
2403 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002404 format_unit = '" _Py_PARSE_INTPTR "'
2405
2406class Py_off_t_converter(CConverter):
2407 type = 'Py_off_t'
2408 converter = 'Py_off_t_converter'
2409
2410class Py_off_t_return_converter(long_return_converter):
2411 type = 'Py_off_t'
2412 conversion_fn = 'PyLong_FromPy_off_t'
2413
2414class path_confname_converter(CConverter):
2415 type="int"
2416 converter="conv_path_confname"
2417
2418class confstr_confname_converter(path_confname_converter):
2419 converter='conv_confstr_confname'
2420
2421class sysconf_confname_converter(path_confname_converter):
2422 converter="conv_sysconf_confname"
2423
2424class sched_param_converter(CConverter):
2425 type = 'struct sched_param'
2426 converter = 'convert_sched_param'
2427 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002428
Larry Hastings61272b72014-01-07 12:41:53 -08002429[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002430/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002431
Larry Hastings61272b72014-01-07 12:41:53 -08002432/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002433
Larry Hastings2a727912014-01-16 11:32:01 -08002434os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002435
2436 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002437 Path to be examined; can be string, bytes, path-like object or
2438 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002439
2440 *
2441
Larry Hastings2f936352014-08-05 14:04:04 +10002442 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002443 If not None, it should be a file descriptor open to a directory,
2444 and path should be a relative string; path will then be relative to
2445 that directory.
2446
2447 follow_symlinks: bool = True
2448 If False, and the last element of the path is a symbolic link,
2449 stat will examine the symbolic link itself instead of the file
2450 the link points to.
2451
2452Perform a stat system call on the given path.
2453
2454dir_fd and follow_symlinks may not be implemented
2455 on your platform. If they are unavailable, using them will raise a
2456 NotImplementedError.
2457
2458It's an error to use dir_fd or follow_symlinks when specifying path as
2459 an open file descriptor.
2460
Larry Hastings61272b72014-01-07 12:41:53 -08002461[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002462
Larry Hastings31826802013-10-19 00:09:25 -07002463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002464os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002465/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002466{
2467 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2468}
2469
Larry Hastings2f936352014-08-05 14:04:04 +10002470
2471/*[clinic input]
2472os.lstat
2473
2474 path : path_t
2475
2476 *
2477
2478 dir_fd : dir_fd(requires='fstatat') = None
2479
2480Perform a stat system call on the given path, without following symbolic links.
2481
2482Like stat(), but do not follow symbolic links.
2483Equivalent to stat(path, follow_symlinks=False).
2484[clinic start generated code]*/
2485
Larry Hastings2f936352014-08-05 14:04:04 +10002486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002487os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2488/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002489{
2490 int follow_symlinks = 0;
2491 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2492}
Larry Hastings31826802013-10-19 00:09:25 -07002493
Larry Hastings2f936352014-08-05 14:04:04 +10002494
Larry Hastings61272b72014-01-07 12:41:53 -08002495/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002496os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002497
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002498 path: path_t
2499 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002500
2501 mode: int
2502 Operating-system mode bitfield. Can be F_OK to test existence,
2503 or the inclusive-OR of R_OK, W_OK, and X_OK.
2504
2505 *
2506
Larry Hastings2f936352014-08-05 14:04:04 +10002507 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002508 If not None, it should be a file descriptor open to a directory,
2509 and path should be relative; path will then be relative to that
2510 directory.
2511
2512 effective_ids: bool = False
2513 If True, access will use the effective uid/gid instead of
2514 the real uid/gid.
2515
2516 follow_symlinks: bool = True
2517 If False, and the last element of the path is a symbolic link,
2518 access will examine the symbolic link itself instead of the file
2519 the link points to.
2520
2521Use the real uid/gid to test for access to a path.
2522
2523{parameters}
2524dir_fd, effective_ids, and follow_symlinks may not be implemented
2525 on your platform. If they are unavailable, using them will raise a
2526 NotImplementedError.
2527
2528Note that most operations will use the effective uid/gid, therefore this
2529 routine can be used in a suid/sgid environment to test if the invoking user
2530 has the specified access to the path.
2531
Larry Hastings61272b72014-01-07 12:41:53 -08002532[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002533
Larry Hastings2f936352014-08-05 14:04:04 +10002534static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002535os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002536 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002537/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002538{
Larry Hastings2f936352014-08-05 14:04:04 +10002539 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002540
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002541#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002542 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002543#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002545#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002546
Larry Hastings9cf065c2012-06-22 16:30:09 -07002547#ifndef HAVE_FACCESSAT
2548 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002549 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002550
2551 if (effective_ids) {
2552 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002553 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002554 }
2555#endif
2556
2557#ifdef MS_WINDOWS
2558 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002559 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560 Py_END_ALLOW_THREADS
2561
2562 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002563 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002564 * * we didn't get a -1, and
2565 * * write access wasn't requested,
2566 * * or the file isn't read-only,
2567 * * or it's a directory.
2568 * (Directories cannot be read-only on Windows.)
2569 */
Larry Hastings2f936352014-08-05 14:04:04 +10002570 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002571 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002573 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002574#else
2575
2576 Py_BEGIN_ALLOW_THREADS
2577#ifdef HAVE_FACCESSAT
2578 if ((dir_fd != DEFAULT_DIR_FD) ||
2579 effective_ids ||
2580 !follow_symlinks) {
2581 int flags = 0;
2582 if (!follow_symlinks)
2583 flags |= AT_SYMLINK_NOFOLLOW;
2584 if (effective_ids)
2585 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002586 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002587 }
2588 else
2589#endif
Larry Hastings31826802013-10-19 00:09:25 -07002590 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002592 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593#endif
2594
Larry Hastings9cf065c2012-06-22 16:30:09 -07002595 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002596}
2597
Guido van Rossumd371ff11999-01-25 16:12:23 +00002598#ifndef F_OK
2599#define F_OK 0
2600#endif
2601#ifndef R_OK
2602#define R_OK 4
2603#endif
2604#ifndef W_OK
2605#define W_OK 2
2606#endif
2607#ifndef X_OK
2608#define X_OK 1
2609#endif
2610
Larry Hastings31826802013-10-19 00:09:25 -07002611
Guido van Rossumd371ff11999-01-25 16:12:23 +00002612#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002613/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002614os.ttyname -> DecodeFSDefault
2615
2616 fd: int
2617 Integer file descriptor handle.
2618
2619 /
2620
2621Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002622[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002623
Larry Hastings31826802013-10-19 00:09:25 -07002624static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002625os_ttyname_impl(PyObject *module, int fd)
2626/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002627{
2628 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002629
Larry Hastings31826802013-10-19 00:09:25 -07002630 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002631 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002632 posix_error();
2633 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002634}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002635#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002636
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002637#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002638/*[clinic input]
2639os.ctermid
2640
2641Return the name of the controlling terminal for this process.
2642[clinic start generated code]*/
2643
Larry Hastings2f936352014-08-05 14:04:04 +10002644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002645os_ctermid_impl(PyObject *module)
2646/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002647{
Victor Stinner8c62be82010-05-06 00:08:46 +00002648 char *ret;
2649 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002650
Greg Wardb48bc172000-03-01 21:51:56 +00002651#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002653#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002654 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002655#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002656 if (ret == NULL)
2657 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002658 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659}
Larry Hastings2f936352014-08-05 14:04:04 +10002660#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002661
Larry Hastings2f936352014-08-05 14:04:04 +10002662
2663/*[clinic input]
2664os.chdir
2665
2666 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2667
2668Change the current working directory to the specified path.
2669
2670path may always be specified as a string.
2671On some platforms, path may also be specified as an open file descriptor.
2672 If this functionality is unavailable, using it raises an exception.
2673[clinic start generated code]*/
2674
Larry Hastings2f936352014-08-05 14:04:04 +10002675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002676os_chdir_impl(PyObject *module, path_t *path)
2677/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002678{
2679 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002680
2681 Py_BEGIN_ALLOW_THREADS
2682#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002683 /* on unix, success = 0, on windows, success = !0 */
2684 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002685#else
2686#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002687 if (path->fd != -1)
2688 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689 else
2690#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002691 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692#endif
2693 Py_END_ALLOW_THREADS
2694
2695 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002696 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697 }
2698
Larry Hastings2f936352014-08-05 14:04:04 +10002699 Py_RETURN_NONE;
2700}
2701
2702
2703#ifdef HAVE_FCHDIR
2704/*[clinic input]
2705os.fchdir
2706
2707 fd: fildes
2708
2709Change to the directory of the given file descriptor.
2710
2711fd must be opened on a directory, not a file.
2712Equivalent to os.chdir(fd).
2713
2714[clinic start generated code]*/
2715
Fred Drake4d1e64b2002-04-15 19:40:07 +00002716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002717os_fchdir_impl(PyObject *module, int fd)
2718/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002719{
Larry Hastings2f936352014-08-05 14:04:04 +10002720 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002721}
2722#endif /* HAVE_FCHDIR */
2723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002724
Larry Hastings2f936352014-08-05 14:04:04 +10002725/*[clinic input]
2726os.chmod
2727
2728 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2729 Path to be modified. May always be specified as a str or bytes.
2730 On some platforms, path may also be specified as an open file descriptor.
2731 If this functionality is unavailable, using it raises an exception.
2732
2733 mode: int
2734 Operating-system mode bitfield.
2735
2736 *
2737
2738 dir_fd : dir_fd(requires='fchmodat') = None
2739 If not None, it should be a file descriptor open to a directory,
2740 and path should be relative; path will then be relative to that
2741 directory.
2742
2743 follow_symlinks: bool = True
2744 If False, and the last element of the path is a symbolic link,
2745 chmod will modify the symbolic link itself instead of the file
2746 the link points to.
2747
2748Change the access permissions of a file.
2749
2750It is an error to use dir_fd or follow_symlinks when specifying path as
2751 an open file descriptor.
2752dir_fd and follow_symlinks may not be implemented on your platform.
2753 If they are unavailable, using them will raise a NotImplementedError.
2754
2755[clinic start generated code]*/
2756
Larry Hastings2f936352014-08-05 14:04:04 +10002757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002758os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002759 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002760/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002761{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002762 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002764#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002765 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002766#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002767
Larry Hastings9cf065c2012-06-22 16:30:09 -07002768#ifdef HAVE_FCHMODAT
2769 int fchmodat_nofollow_unsupported = 0;
2770#endif
2771
Larry Hastings9cf065c2012-06-22 16:30:09 -07002772#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2773 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002774 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002775#endif
2776
2777#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002778 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002779 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002780 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 result = 0;
2782 else {
2783 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 attr &= ~FILE_ATTRIBUTE_READONLY;
2785 else
2786 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002787 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788 }
2789 Py_END_ALLOW_THREADS
2790
2791 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002792 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 }
2794#else /* MS_WINDOWS */
2795 Py_BEGIN_ALLOW_THREADS
2796#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002797 if (path->fd != -1)
2798 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799 else
2800#endif
2801#ifdef HAVE_LCHMOD
2802 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002803 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804 else
2805#endif
2806#ifdef HAVE_FCHMODAT
2807 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2808 /*
2809 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2810 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002811 * and then says it isn't implemented yet.
2812 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813 *
2814 * Once it is supported, os.chmod will automatically
2815 * support dir_fd and follow_symlinks=False. (Hopefully.)
2816 * Until then, we need to be careful what exception we raise.
2817 */
Larry Hastings2f936352014-08-05 14:04:04 +10002818 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2820 /*
2821 * But wait! We can't throw the exception without allowing threads,
2822 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2823 */
2824 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002825 result &&
2826 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2827 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 }
2829 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002830#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002831 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832 Py_END_ALLOW_THREADS
2833
2834 if (result) {
2835#ifdef HAVE_FCHMODAT
2836 if (fchmodat_nofollow_unsupported) {
2837 if (dir_fd != DEFAULT_DIR_FD)
2838 dir_fd_and_follow_symlinks_invalid("chmod",
2839 dir_fd, follow_symlinks);
2840 else
2841 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002842 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002843 }
2844 else
2845#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002846 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002847 }
2848#endif
2849
Larry Hastings2f936352014-08-05 14:04:04 +10002850 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002851}
2852
Larry Hastings9cf065c2012-06-22 16:30:09 -07002853
Christian Heimes4e30a842007-11-30 22:12:06 +00002854#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002855/*[clinic input]
2856os.fchmod
2857
2858 fd: int
2859 mode: int
2860
2861Change the access permissions of the file given by file descriptor fd.
2862
2863Equivalent to os.chmod(fd, mode).
2864[clinic start generated code]*/
2865
Larry Hastings2f936352014-08-05 14:04:04 +10002866static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002867os_fchmod_impl(PyObject *module, int fd, int mode)
2868/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002869{
2870 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002871 int async_err = 0;
2872
2873 do {
2874 Py_BEGIN_ALLOW_THREADS
2875 res = fchmod(fd, mode);
2876 Py_END_ALLOW_THREADS
2877 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2878 if (res != 0)
2879 return (!async_err) ? posix_error() : NULL;
2880
Victor Stinner8c62be82010-05-06 00:08:46 +00002881 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002882}
2883#endif /* HAVE_FCHMOD */
2884
Larry Hastings2f936352014-08-05 14:04:04 +10002885
Christian Heimes4e30a842007-11-30 22:12:06 +00002886#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002887/*[clinic input]
2888os.lchmod
2889
2890 path: path_t
2891 mode: int
2892
2893Change the access permissions of a file, without following symbolic links.
2894
2895If path is a symlink, this affects the link itself rather than the target.
2896Equivalent to chmod(path, mode, follow_symlinks=False)."
2897[clinic start generated code]*/
2898
Larry Hastings2f936352014-08-05 14:04:04 +10002899static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002900os_lchmod_impl(PyObject *module, path_t *path, int mode)
2901/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002902{
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002905 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002907 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002908 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002909 return NULL;
2910 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002911 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002912}
2913#endif /* HAVE_LCHMOD */
2914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002915
Thomas Wouterscf297e42007-02-23 15:07:44 +00002916#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002917/*[clinic input]
2918os.chflags
2919
2920 path: path_t
2921 flags: unsigned_long(bitwise=True)
2922 follow_symlinks: bool=True
2923
2924Set file flags.
2925
2926If follow_symlinks is False, and the last element of the path is a symbolic
2927 link, chflags will change flags on the symbolic link itself instead of the
2928 file the link points to.
2929follow_symlinks may not be implemented on your platform. If it is
2930unavailable, using it will raise a NotImplementedError.
2931
2932[clinic start generated code]*/
2933
Larry Hastings2f936352014-08-05 14:04:04 +10002934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002935os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002936 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002937/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002938{
2939 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940
2941#ifndef HAVE_LCHFLAGS
2942 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002943 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002944#endif
2945
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002947#ifdef HAVE_LCHFLAGS
2948 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002949 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002950 else
2951#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002952 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002953 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002954
Larry Hastings2f936352014-08-05 14:04:04 +10002955 if (result)
2956 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957
Larry Hastings2f936352014-08-05 14:04:04 +10002958 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002959}
2960#endif /* HAVE_CHFLAGS */
2961
Larry Hastings2f936352014-08-05 14:04:04 +10002962
Thomas Wouterscf297e42007-02-23 15:07:44 +00002963#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002964/*[clinic input]
2965os.lchflags
2966
2967 path: path_t
2968 flags: unsigned_long(bitwise=True)
2969
2970Set file flags.
2971
2972This function will not follow symbolic links.
2973Equivalent to chflags(path, flags, follow_symlinks=False).
2974[clinic start generated code]*/
2975
Larry Hastings2f936352014-08-05 14:04:04 +10002976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002977os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2978/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002979{
Victor Stinner8c62be82010-05-06 00:08:46 +00002980 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002981 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002982 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002984 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002985 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002986 }
Victor Stinner292c8352012-10-30 02:17:38 +01002987 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002988}
2989#endif /* HAVE_LCHFLAGS */
2990
Larry Hastings2f936352014-08-05 14:04:04 +10002991
Martin v. Löwis244edc82001-10-04 22:44:26 +00002992#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002993/*[clinic input]
2994os.chroot
2995 path: path_t
2996
2997Change root directory to path.
2998
2999[clinic start generated code]*/
3000
Larry Hastings2f936352014-08-05 14:04:04 +10003001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003002os_chroot_impl(PyObject *module, path_t *path)
3003/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003004{
3005 int res;
3006 Py_BEGIN_ALLOW_THREADS
3007 res = chroot(path->narrow);
3008 Py_END_ALLOW_THREADS
3009 if (res < 0)
3010 return path_error(path);
3011 Py_RETURN_NONE;
3012}
3013#endif /* HAVE_CHROOT */
3014
Martin v. Löwis244edc82001-10-04 22:44:26 +00003015
Guido van Rossum21142a01999-01-08 21:05:37 +00003016#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003017/*[clinic input]
3018os.fsync
3019
3020 fd: fildes
3021
3022Force write of fd to disk.
3023[clinic start generated code]*/
3024
Larry Hastings2f936352014-08-05 14:04:04 +10003025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003026os_fsync_impl(PyObject *module, int fd)
3027/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003028{
3029 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003030}
3031#endif /* HAVE_FSYNC */
3032
Larry Hastings2f936352014-08-05 14:04:04 +10003033
Ross Lagerwall7807c352011-03-17 20:20:30 +02003034#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003035/*[clinic input]
3036os.sync
3037
3038Force write of everything to disk.
3039[clinic start generated code]*/
3040
Larry Hastings2f936352014-08-05 14:04:04 +10003041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003042os_sync_impl(PyObject *module)
3043/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003044{
3045 Py_BEGIN_ALLOW_THREADS
3046 sync();
3047 Py_END_ALLOW_THREADS
3048 Py_RETURN_NONE;
3049}
Larry Hastings2f936352014-08-05 14:04:04 +10003050#endif /* HAVE_SYNC */
3051
Ross Lagerwall7807c352011-03-17 20:20:30 +02003052
Guido van Rossum21142a01999-01-08 21:05:37 +00003053#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003054#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003055extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3056#endif
3057
Larry Hastings2f936352014-08-05 14:04:04 +10003058/*[clinic input]
3059os.fdatasync
3060
3061 fd: fildes
3062
3063Force write of fd to disk without forcing update of metadata.
3064[clinic start generated code]*/
3065
Larry Hastings2f936352014-08-05 14:04:04 +10003066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003067os_fdatasync_impl(PyObject *module, int fd)
3068/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003069{
3070 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003071}
3072#endif /* HAVE_FDATASYNC */
3073
3074
Fredrik Lundh10723342000-07-10 16:38:09 +00003075#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003076/*[clinic input]
3077os.chown
3078
3079 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3080 Path to be examined; can be string, bytes, or open-file-descriptor int.
3081
3082 uid: uid_t
3083
3084 gid: gid_t
3085
3086 *
3087
3088 dir_fd : dir_fd(requires='fchownat') = None
3089 If not None, it should be a file descriptor open to a directory,
3090 and path should be relative; path will then be relative to that
3091 directory.
3092
3093 follow_symlinks: bool = True
3094 If False, and the last element of the path is a symbolic link,
3095 stat will examine the symbolic link itself instead of the file
3096 the link points to.
3097
3098Change the owner and group id of path to the numeric uid and gid.\
3099
3100path may always be specified as a string.
3101On some platforms, path may also be specified as an open file descriptor.
3102 If this functionality is unavailable, using it raises an exception.
3103If dir_fd is not None, it should be a file descriptor open to a directory,
3104 and path should be relative; path will then be relative to that directory.
3105If follow_symlinks is False, and the last element of the path is a symbolic
3106 link, chown will modify the symbolic link itself instead of the file the
3107 link points to.
3108It is an error to use dir_fd or follow_symlinks when specifying path as
3109 an open file descriptor.
3110dir_fd and follow_symlinks may not be implemented on your platform.
3111 If they are unavailable, using them will raise a NotImplementedError.
3112
3113[clinic start generated code]*/
3114
Larry Hastings2f936352014-08-05 14:04:04 +10003115static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003116os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003117 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003118/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003119{
3120 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003121
3122#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3123 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003124 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003125#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003126 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3127 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3128 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003129
3130#ifdef __APPLE__
3131 /*
3132 * This is for Mac OS X 10.3, which doesn't have lchown.
3133 * (But we still have an lchown symbol because of weak-linking.)
3134 * It doesn't have fchownat either. So there's no possibility
3135 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003136 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137 if ((!follow_symlinks) && (lchown == NULL)) {
3138 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003139 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003140 }
3141#endif
3142
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003144#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003145 if (path->fd != -1)
3146 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003147 else
3148#endif
3149#ifdef HAVE_LCHOWN
3150 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003151 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152 else
3153#endif
3154#ifdef HAVE_FCHOWNAT
3155 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003156 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3158 else
3159#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003160 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162
Larry Hastings2f936352014-08-05 14:04:04 +10003163 if (result)
3164 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003165
Larry Hastings2f936352014-08-05 14:04:04 +10003166 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003167}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003168#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003169
Larry Hastings2f936352014-08-05 14:04:04 +10003170
Christian Heimes4e30a842007-11-30 22:12:06 +00003171#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003172/*[clinic input]
3173os.fchown
3174
3175 fd: int
3176 uid: uid_t
3177 gid: gid_t
3178
3179Change the owner and group id of the file specified by file descriptor.
3180
3181Equivalent to os.chown(fd, uid, gid).
3182
3183[clinic start generated code]*/
3184
Larry Hastings2f936352014-08-05 14:04:04 +10003185static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003186os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3187/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003188{
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003190 int async_err = 0;
3191
3192 do {
3193 Py_BEGIN_ALLOW_THREADS
3194 res = fchown(fd, uid, gid);
3195 Py_END_ALLOW_THREADS
3196 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3197 if (res != 0)
3198 return (!async_err) ? posix_error() : NULL;
3199
Victor Stinner8c62be82010-05-06 00:08:46 +00003200 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003201}
3202#endif /* HAVE_FCHOWN */
3203
Larry Hastings2f936352014-08-05 14:04:04 +10003204
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003205#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003206/*[clinic input]
3207os.lchown
3208
3209 path : path_t
3210 uid: uid_t
3211 gid: gid_t
3212
3213Change the owner and group id of path to the numeric uid and gid.
3214
3215This function will not follow symbolic links.
3216Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3217[clinic start generated code]*/
3218
Larry Hastings2f936352014-08-05 14:04:04 +10003219static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003220os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3221/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003222{
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003225 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003227 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003228 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003229 }
Larry Hastings2f936352014-08-05 14:04:04 +10003230 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003231}
3232#endif /* HAVE_LCHOWN */
3233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003234
Barry Warsaw53699e91996-12-10 23:23:01 +00003235static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003236posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003237{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003238 char *buf, *tmpbuf;
3239 char *cwd;
3240 const size_t chunk = 1024;
3241 size_t buflen = 0;
3242 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003243
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003244#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003245 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003246 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003247 wchar_t *wbuf2 = wbuf;
3248 PyObject *resobj;
3249 DWORD len;
3250 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003251 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 /* If the buffer is large enough, len does not include the
3253 terminating \0. If the buffer is too small, len includes
3254 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003255 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003256 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 if (wbuf2)
3258 len = GetCurrentDirectoryW(len, wbuf2);
3259 }
3260 Py_END_ALLOW_THREADS
3261 if (!wbuf2) {
3262 PyErr_NoMemory();
3263 return NULL;
3264 }
3265 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003266 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003267 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003268 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 }
3270 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003271 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003272 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003273 return resobj;
3274 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003275
3276 if (win32_warn_bytes_api())
3277 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003278#endif
3279
Victor Stinner4403d7d2015-04-25 00:16:10 +02003280 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003282 do {
3283 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003284#ifdef MS_WINDOWS
3285 if (buflen > INT_MAX) {
3286 PyErr_NoMemory();
3287 break;
3288 }
3289#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003290 tmpbuf = PyMem_RawRealloc(buf, buflen);
3291 if (tmpbuf == NULL)
3292 break;
3293
3294 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003295#ifdef MS_WINDOWS
3296 cwd = getcwd(buf, (int)buflen);
3297#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003298 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003299#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003300 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003302
3303 if (cwd == NULL) {
3304 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003306 }
3307
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003309 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3310 else
3311 obj = PyUnicode_DecodeFSDefault(buf);
3312 PyMem_RawFree(buf);
3313
3314 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003315}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003316
Larry Hastings2f936352014-08-05 14:04:04 +10003317
3318/*[clinic input]
3319os.getcwd
3320
3321Return a unicode string representing the current working directory.
3322[clinic start generated code]*/
3323
Larry Hastings2f936352014-08-05 14:04:04 +10003324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003325os_getcwd_impl(PyObject *module)
3326/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003327{
3328 return posix_getcwd(0);
3329}
3330
Larry Hastings2f936352014-08-05 14:04:04 +10003331
3332/*[clinic input]
3333os.getcwdb
3334
3335Return a bytes string representing the current working directory.
3336[clinic start generated code]*/
3337
Larry Hastings2f936352014-08-05 14:04:04 +10003338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003339os_getcwdb_impl(PyObject *module)
3340/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003341{
3342 return posix_getcwd(1);
3343}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003344
Larry Hastings2f936352014-08-05 14:04:04 +10003345
Larry Hastings9cf065c2012-06-22 16:30:09 -07003346#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3347#define HAVE_LINK 1
3348#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003349
Guido van Rossumb6775db1994-08-01 11:34:53 +00003350#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003351/*[clinic input]
3352
3353os.link
3354
3355 src : path_t
3356 dst : path_t
3357 *
3358 src_dir_fd : dir_fd = None
3359 dst_dir_fd : dir_fd = None
3360 follow_symlinks: bool = True
3361
3362Create a hard link to a file.
3363
3364If either src_dir_fd or dst_dir_fd is not None, it should be a file
3365 descriptor open to a directory, and the respective path string (src or dst)
3366 should be relative; the path will then be relative to that directory.
3367If follow_symlinks is False, and the last element of src is a symbolic
3368 link, link will create a link to the symbolic link itself instead of the
3369 file the link points to.
3370src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3371 platform. If they are unavailable, using them will raise a
3372 NotImplementedError.
3373[clinic start generated code]*/
3374
Larry Hastings2f936352014-08-05 14:04:04 +10003375static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003376os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003377 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003378/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003379{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003380#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003381 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382#else
3383 int result;
3384#endif
3385
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386#ifndef HAVE_LINKAT
3387 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3388 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003389 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003390 }
3391#endif
3392
Steve Dowercc16be82016-09-08 10:35:16 -07003393#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003394 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395 PyErr_SetString(PyExc_NotImplementedError,
3396 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003397 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 }
Steve Dowercc16be82016-09-08 10:35:16 -07003399#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003400
Brian Curtin1b9df392010-11-24 20:24:31 +00003401#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003403 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003405
Larry Hastings2f936352014-08-05 14:04:04 +10003406 if (!result)
3407 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408#else
3409 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003410#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3412 (dst_dir_fd != DEFAULT_DIR_FD) ||
3413 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003414 result = linkat(src_dir_fd, src->narrow,
3415 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3417 else
Steve Dowercc16be82016-09-08 10:35:16 -07003418#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003419 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003421
Larry Hastings2f936352014-08-05 14:04:04 +10003422 if (result)
3423 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003424#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425
Larry Hastings2f936352014-08-05 14:04:04 +10003426 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003427}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428#endif
3429
Brian Curtin1b9df392010-11-24 20:24:31 +00003430
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003431#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003432static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003433_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003434{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435 PyObject *v;
3436 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3437 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003438 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003440 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442
Steve Dowercc16be82016-09-08 10:35:16 -07003443 WIN32_FIND_DATAW wFileData;
3444 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003445
Steve Dowercc16be82016-09-08 10:35:16 -07003446 if (!path->wide) { /* Default arg: "." */
3447 po_wchars = L".";
3448 len = 1;
3449 } else {
3450 po_wchars = path->wide;
3451 len = wcslen(path->wide);
3452 }
3453 /* The +5 is so we can append "\\*.*\0" */
3454 wnamebuf = PyMem_New(wchar_t, len + 5);
3455 if (!wnamebuf) {
3456 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 }
Steve Dowercc16be82016-09-08 10:35:16 -07003459 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003461 wchar_t wch = wnamebuf[len-1];
3462 if (wch != SEP && wch != ALTSEP && wch != L':')
3463 wnamebuf[len++] = SEP;
3464 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003465 }
Steve Dowercc16be82016-09-08 10:35:16 -07003466 if ((list = PyList_New(0)) == NULL) {
3467 goto exit;
3468 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003469 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003470 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003471 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 if (hFindFile == INVALID_HANDLE_VALUE) {
3473 int error = GetLastError();
3474 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 goto exit;
3476 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003477 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003479 }
3480 do {
3481 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003482 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3483 wcscmp(wFileData.cFileName, L"..") != 0) {
3484 v = PyUnicode_FromWideChar(wFileData.cFileName,
3485 wcslen(wFileData.cFileName));
3486 if (path->narrow && v) {
3487 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3488 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003489 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 Py_DECREF(list);
3491 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 break;
3493 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 Py_DECREF(list);
3497 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 break;
3499 }
3500 Py_DECREF(v);
3501 }
3502 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003503 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 Py_END_ALLOW_THREADS
3505 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3506 it got to the end of the directory. */
3507 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003509 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 }
3512 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003513
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514exit:
3515 if (hFindFile != INVALID_HANDLE_VALUE) {
3516 if (FindClose(hFindFile) == FALSE) {
3517 if (list != NULL) {
3518 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003519 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 }
3521 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003523 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003524
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003526} /* end of _listdir_windows_no_opendir */
3527
3528#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3529
3530static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003532{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003533 PyObject *v;
3534 DIR *dirp = NULL;
3535 struct dirent *ep;
3536 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003537#ifdef HAVE_FDOPENDIR
3538 int fd = -1;
3539#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003540
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003543 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003545 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003546 if (fd == -1)
3547 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548
Larry Hastingsfdaea062012-06-25 04:42:23 -07003549 return_str = 1;
3550
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 Py_BEGIN_ALLOW_THREADS
3552 dirp = fdopendir(fd);
3553 Py_END_ALLOW_THREADS
3554 }
3555 else
3556#endif
3557 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003558 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003559 if (path->narrow) {
3560 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003561 /* only return bytes if they specified a bytes-like object */
3562 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003563 }
3564 else {
3565 name = ".";
3566 return_str = 1;
3567 }
3568
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 Py_BEGIN_ALLOW_THREADS
3570 dirp = opendir(name);
3571 Py_END_ALLOW_THREADS
3572 }
3573
3574 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003575 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003576#ifdef HAVE_FDOPENDIR
3577 if (fd != -1) {
3578 Py_BEGIN_ALLOW_THREADS
3579 close(fd);
3580 Py_END_ALLOW_THREADS
3581 }
3582#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583 goto exit;
3584 }
3585 if ((list = PyList_New(0)) == NULL) {
3586 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 }
3588 for (;;) {
3589 errno = 0;
3590 Py_BEGIN_ALLOW_THREADS
3591 ep = readdir(dirp);
3592 Py_END_ALLOW_THREADS
3593 if (ep == NULL) {
3594 if (errno == 0) {
3595 break;
3596 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003598 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 }
3601 }
3602 if (ep->d_name[0] == '.' &&
3603 (NAMLEN(ep) == 1 ||
3604 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3605 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003606 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003607 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3608 else
3609 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 break;
3613 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003615 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 break;
3618 }
3619 Py_DECREF(v);
3620 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003621
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622exit:
3623 if (dirp != NULL) {
3624 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003625#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 if (fd > -1)
3627 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003628#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 closedir(dirp);
3630 Py_END_ALLOW_THREADS
3631 }
3632
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003634} /* end of _posix_listdir */
3635#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003636
Larry Hastings2f936352014-08-05 14:04:04 +10003637
3638/*[clinic input]
3639os.listdir
3640
3641 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3642
3643Return a list containing the names of the files in the directory.
3644
3645path can be specified as either str or bytes. If path is bytes,
3646 the filenames returned will also be bytes; in all other circumstances
3647 the filenames returned will be str.
3648If path is None, uses the path='.'.
3649On some platforms, path may also be specified as an open file descriptor;\
3650 the file descriptor must refer to a directory.
3651 If this functionality is unavailable, using it raises NotImplementedError.
3652
3653The list is in arbitrary order. It does not include the special
3654entries '.' and '..' even if they are present in the directory.
3655
3656
3657[clinic start generated code]*/
3658
Larry Hastings2f936352014-08-05 14:04:04 +10003659static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003660os_listdir_impl(PyObject *module, path_t *path)
3661/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003662{
3663#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3664 return _listdir_windows_no_opendir(path, NULL);
3665#else
3666 return _posix_listdir(path, NULL);
3667#endif
3668}
3669
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003670#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003671/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003672/*[clinic input]
3673os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003674
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003675 path: path_t
3676 /
3677
3678[clinic start generated code]*/
3679
3680static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003681os__getfullpathname_impl(PyObject *module, path_t *path)
3682/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003683{
Steve Dowercc16be82016-09-08 10:35:16 -07003684 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3685 wchar_t *wtemp;
3686 DWORD result;
3687 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003688
Steve Dowercc16be82016-09-08 10:35:16 -07003689 result = GetFullPathNameW(path->wide,
3690 Py_ARRAY_LENGTH(woutbuf),
3691 woutbuf, &wtemp);
3692 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3693 woutbufp = PyMem_New(wchar_t, result);
3694 if (!woutbufp)
3695 return PyErr_NoMemory();
3696 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003697 }
Steve Dowercc16be82016-09-08 10:35:16 -07003698 if (result) {
3699 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3700 if (path->narrow)
3701 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3702 } else
3703 v = win32_error_object("GetFullPathNameW", path->object);
3704 if (woutbufp != woutbuf)
3705 PyMem_Free(woutbufp);
3706 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003707}
Brian Curtind40e6f72010-07-08 21:39:08 +00003708
Brian Curtind25aef52011-06-13 15:16:04 -05003709
Larry Hastings2f936352014-08-05 14:04:04 +10003710/*[clinic input]
3711os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003712
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003713 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003714 /
3715
3716A helper function for samepath on windows.
3717[clinic start generated code]*/
3718
Larry Hastings2f936352014-08-05 14:04:04 +10003719static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003720os__getfinalpathname_impl(PyObject *module, path_t *path)
3721/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003722{
3723 HANDLE hFile;
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003724 wchar_t buf[MAXPATHLEN], *target_path = buf;
3725 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003726 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003727 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003728
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003729 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003730 hFile = CreateFileW(
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003731 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003732 0, /* desired access */
3733 0, /* share mode */
3734 NULL, /* security attributes */
3735 OPEN_EXISTING,
3736 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3737 FILE_FLAG_BACKUP_SEMANTICS,
3738 NULL);
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003739 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003740
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003741 if (hFile == INVALID_HANDLE_VALUE) {
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003742 return win32_error_object("CreateFileW", path->object);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003743 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003744
3745 /* We have a good handle to the target, use it to determine the
3746 target path name. */
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003747 while (1) {
3748 Py_BEGIN_ALLOW_THREADS
3749 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3750 buf_size, VOLUME_NAME_DOS);
3751 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003752
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003753 if (!result_length) {
3754 result = win32_error_object("GetFinalPathNameByHandleW",
3755 path->object);
3756 goto cleanup;
3757 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003758
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003759 if (result_length < buf_size) {
3760 break;
3761 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003762
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003763 wchar_t *tmp;
3764 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3765 result_length * sizeof(*tmp));
3766 if (!tmp) {
3767 result = PyErr_NoMemory();
3768 goto cleanup;
3769 }
3770
3771 buf_size = result_length;
3772 target_path = tmp;
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003773 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003774
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003775 result = PyUnicode_FromWideChar(target_path, result_length);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003776 if (path->narrow)
3777 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003778
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003779cleanup:
3780 if (target_path != buf) {
3781 PyMem_Free(target_path);
3782 }
3783 CloseHandle(hFile);
3784 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003785}
Brian Curtin62857742010-09-06 17:07:27 +00003786
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003787/*[clinic input]
3788os._isdir
3789
3790 path: path_t
3791 /
3792
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003793Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003794[clinic start generated code]*/
3795
Brian Curtin9c669cc2011-06-08 18:17:18 -05003796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003797os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003798/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003799{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003800 DWORD attributes;
3801
Steve Dowerb22a6772016-07-17 20:49:38 -07003802 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003803 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003804 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003805
Brian Curtin9c669cc2011-06-08 18:17:18 -05003806 if (attributes == INVALID_FILE_ATTRIBUTES)
3807 Py_RETURN_FALSE;
3808
Brian Curtin9c669cc2011-06-08 18:17:18 -05003809 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3810 Py_RETURN_TRUE;
3811 else
3812 Py_RETURN_FALSE;
3813}
Tim Golden6b528062013-08-01 12:44:00 +01003814
Tim Golden6b528062013-08-01 12:44:00 +01003815
Larry Hastings2f936352014-08-05 14:04:04 +10003816/*[clinic input]
3817os._getvolumepathname
3818
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003819 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003820
3821A helper function for ismount on Win32.
3822[clinic start generated code]*/
3823
Larry Hastings2f936352014-08-05 14:04:04 +10003824static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003825os__getvolumepathname_impl(PyObject *module, path_t *path)
3826/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003827{
3828 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003829 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003830 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003831 BOOL ret;
3832
Tim Golden6b528062013-08-01 12:44:00 +01003833 /* Volume path should be shorter than entire path */
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003834 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003835
Victor Stinner850a18e2017-10-24 16:53:32 -07003836 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003837 PyErr_SetString(PyExc_OverflowError, "path too long");
3838 return NULL;
3839 }
3840
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003841 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003842 if (mountpath == NULL)
3843 return PyErr_NoMemory();
3844
3845 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003846 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003847 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003848 Py_END_ALLOW_THREADS
3849
3850 if (!ret) {
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003851 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003852 goto exit;
3853 }
3854 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003855 if (path->narrow)
3856 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003857
3858exit:
3859 PyMem_Free(mountpath);
3860 return result;
3861}
Tim Golden6b528062013-08-01 12:44:00 +01003862
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003863#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003864
Larry Hastings2f936352014-08-05 14:04:04 +10003865
3866/*[clinic input]
3867os.mkdir
3868
3869 path : path_t
3870
3871 mode: int = 0o777
3872
3873 *
3874
3875 dir_fd : dir_fd(requires='mkdirat') = None
3876
3877# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3878
3879Create a directory.
3880
3881If dir_fd is not None, it should be a file descriptor open to a directory,
3882 and path should be relative; path will then be relative to that directory.
3883dir_fd may not be implemented on your platform.
3884 If it is unavailable, using it will raise a NotImplementedError.
3885
3886The mode argument is ignored on Windows.
3887[clinic start generated code]*/
3888
Larry Hastings2f936352014-08-05 14:04:04 +10003889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003890os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3891/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003892{
3893 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003894
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003895#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003897 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003899
Larry Hastings2f936352014-08-05 14:04:04 +10003900 if (!result)
3901 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003904#if HAVE_MKDIRAT
3905 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003906 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003907 else
3908#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003909#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003910 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003911#else
Larry Hastings2f936352014-08-05 14:04:04 +10003912 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003913#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003914 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003915 if (result < 0)
3916 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003917#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003918 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003919}
3920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003921
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003922/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3923#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003924#include <sys/resource.h>
3925#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003926
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003927
3928#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003929/*[clinic input]
3930os.nice
3931
3932 increment: int
3933 /
3934
3935Add increment to the priority of process and return the new priority.
3936[clinic start generated code]*/
3937
Larry Hastings2f936352014-08-05 14:04:04 +10003938static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003939os_nice_impl(PyObject *module, int increment)
3940/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003941{
3942 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003943
Victor Stinner8c62be82010-05-06 00:08:46 +00003944 /* There are two flavours of 'nice': one that returns the new
3945 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003946 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003947 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003948
Victor Stinner8c62be82010-05-06 00:08:46 +00003949 If we are of the nice family that returns the new priority, we
3950 need to clear errno before the call, and check if errno is filled
3951 before calling posix_error() on a returnvalue of -1, because the
3952 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003953
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 errno = 0;
3955 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003956#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003957 if (value == 0)
3958 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003959#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003960 if (value == -1 && errno != 0)
3961 /* either nice() or getpriority() returned an error */
3962 return posix_error();
3963 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003964}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003965#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003966
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003967
3968#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003969/*[clinic input]
3970os.getpriority
3971
3972 which: int
3973 who: int
3974
3975Return program scheduling priority.
3976[clinic start generated code]*/
3977
Larry Hastings2f936352014-08-05 14:04:04 +10003978static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003979os_getpriority_impl(PyObject *module, int which, int who)
3980/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003981{
3982 int retval;
3983
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003984 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003985 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003986 if (errno != 0)
3987 return posix_error();
3988 return PyLong_FromLong((long)retval);
3989}
3990#endif /* HAVE_GETPRIORITY */
3991
3992
3993#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003994/*[clinic input]
3995os.setpriority
3996
3997 which: int
3998 who: int
3999 priority: int
4000
4001Set program scheduling priority.
4002[clinic start generated code]*/
4003
Larry Hastings2f936352014-08-05 14:04:04 +10004004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004005os_setpriority_impl(PyObject *module, int which, int who, int priority)
4006/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004007{
4008 int retval;
4009
4010 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004011 if (retval == -1)
4012 return posix_error();
4013 Py_RETURN_NONE;
4014}
4015#endif /* HAVE_SETPRIORITY */
4016
4017
Barry Warsaw53699e91996-12-10 23:23:01 +00004018static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004019internal_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 +00004020{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004021 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004022 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004023
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004024#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004025 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004026 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004027#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004028 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004029#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004030
Larry Hastings9cf065c2012-06-22 16:30:09 -07004031 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4032 (dst_dir_fd != DEFAULT_DIR_FD);
4033#ifndef HAVE_RENAMEAT
4034 if (dir_fd_specified) {
4035 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004036 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004037 }
4038#endif
4039
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040#ifdef MS_WINDOWS
4041 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004042 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004043 Py_END_ALLOW_THREADS
4044
Larry Hastings2f936352014-08-05 14:04:04 +10004045 if (!result)
4046 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047
4048#else
Steve Dowercc16be82016-09-08 10:35:16 -07004049 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4050 PyErr_Format(PyExc_ValueError,
4051 "%s: src and dst must be the same type", function_name);
4052 return NULL;
4053 }
4054
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055 Py_BEGIN_ALLOW_THREADS
4056#ifdef HAVE_RENAMEAT
4057 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004058 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059 else
4060#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004061 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004062 Py_END_ALLOW_THREADS
4063
Larry Hastings2f936352014-08-05 14:04:04 +10004064 if (result)
4065 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004066#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004067 Py_RETURN_NONE;
4068}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004069
Larry Hastings2f936352014-08-05 14:04:04 +10004070
4071/*[clinic input]
4072os.rename
4073
4074 src : path_t
4075 dst : path_t
4076 *
4077 src_dir_fd : dir_fd = None
4078 dst_dir_fd : dir_fd = None
4079
4080Rename a file or directory.
4081
4082If either src_dir_fd or dst_dir_fd is not None, it should be a file
4083 descriptor open to a directory, and the respective path string (src or dst)
4084 should be relative; the path will then be relative to that directory.
4085src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4086 If they are unavailable, using them will raise a NotImplementedError.
4087[clinic start generated code]*/
4088
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004089static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004090os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004091 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004092/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004093{
Larry Hastings2f936352014-08-05 14:04:04 +10004094 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004095}
4096
Larry Hastings2f936352014-08-05 14:04:04 +10004097
4098/*[clinic input]
4099os.replace = os.rename
4100
4101Rename a file or directory, overwriting the destination.
4102
4103If either src_dir_fd or dst_dir_fd is not None, it should be a file
4104 descriptor open to a directory, and the respective path string (src or dst)
4105 should be relative; the path will then be relative to that directory.
4106src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4107 If they are unavailable, using them will raise a NotImplementedError."
4108[clinic start generated code]*/
4109
Larry Hastings2f936352014-08-05 14:04:04 +10004110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004111os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4112 int dst_dir_fd)
4113/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004114{
4115 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4116}
4117
4118
4119/*[clinic input]
4120os.rmdir
4121
4122 path: path_t
4123 *
4124 dir_fd: dir_fd(requires='unlinkat') = None
4125
4126Remove a directory.
4127
4128If dir_fd is not None, it should be a file descriptor open to a directory,
4129 and path should be relative; path will then be relative to that directory.
4130dir_fd may not be implemented on your platform.
4131 If it is unavailable, using it will raise a NotImplementedError.
4132[clinic start generated code]*/
4133
Larry Hastings2f936352014-08-05 14:04:04 +10004134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004135os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4136/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004137{
4138 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004139
4140 Py_BEGIN_ALLOW_THREADS
4141#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004142 /* Windows, success=1, UNIX, success=0 */
4143 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004144#else
4145#ifdef HAVE_UNLINKAT
4146 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004147 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004148 else
4149#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004150 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004151#endif
4152 Py_END_ALLOW_THREADS
4153
Larry Hastings2f936352014-08-05 14:04:04 +10004154 if (result)
4155 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004156
Larry Hastings2f936352014-08-05 14:04:04 +10004157 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004158}
4159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004160
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004161#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004162#ifdef MS_WINDOWS
4163/*[clinic input]
4164os.system -> long
4165
4166 command: Py_UNICODE
4167
4168Execute the command in a subshell.
4169[clinic start generated code]*/
4170
Larry Hastings2f936352014-08-05 14:04:04 +10004171static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004172os_system_impl(PyObject *module, Py_UNICODE *command)
4173/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004174{
4175 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004176 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004177 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004178 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004179 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004181 return result;
4182}
4183#else /* MS_WINDOWS */
4184/*[clinic input]
4185os.system -> long
4186
4187 command: FSConverter
4188
4189Execute the command in a subshell.
4190[clinic start generated code]*/
4191
Larry Hastings2f936352014-08-05 14:04:04 +10004192static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004193os_system_impl(PyObject *module, PyObject *command)
4194/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004195{
4196 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004197 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004198 Py_BEGIN_ALLOW_THREADS
4199 result = system(bytes);
4200 Py_END_ALLOW_THREADS
4201 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004202}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004203#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004204#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004206
Larry Hastings2f936352014-08-05 14:04:04 +10004207/*[clinic input]
4208os.umask
4209
4210 mask: int
4211 /
4212
4213Set the current numeric umask and return the previous umask.
4214[clinic start generated code]*/
4215
Larry Hastings2f936352014-08-05 14:04:04 +10004216static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004217os_umask_impl(PyObject *module, int mask)
4218/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004219{
4220 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004221 if (i < 0)
4222 return posix_error();
4223 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004224}
4225
Brian Curtind40e6f72010-07-08 21:39:08 +00004226#ifdef MS_WINDOWS
4227
4228/* override the default DeleteFileW behavior so that directory
4229symlinks can be removed with this function, the same as with
4230Unix symlinks */
4231BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4232{
4233 WIN32_FILE_ATTRIBUTE_DATA info;
4234 WIN32_FIND_DATAW find_data;
4235 HANDLE find_data_handle;
4236 int is_directory = 0;
4237 int is_link = 0;
4238
4239 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4240 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004241
Brian Curtind40e6f72010-07-08 21:39:08 +00004242 /* Get WIN32_FIND_DATA structure for the path to determine if
4243 it is a symlink */
4244 if(is_directory &&
4245 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4246 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4247
4248 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004249 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4250 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4251 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4252 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004253 FindClose(find_data_handle);
4254 }
4255 }
4256 }
4257
4258 if (is_directory && is_link)
4259 return RemoveDirectoryW(lpFileName);
4260
4261 return DeleteFileW(lpFileName);
4262}
4263#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004265
Larry Hastings2f936352014-08-05 14:04:04 +10004266/*[clinic input]
4267os.unlink
4268
4269 path: path_t
4270 *
4271 dir_fd: dir_fd(requires='unlinkat')=None
4272
4273Remove a file (same as remove()).
4274
4275If dir_fd is not None, it should be a file descriptor open to a directory,
4276 and path should be relative; path will then be relative to that directory.
4277dir_fd may not be implemented on your platform.
4278 If it is unavailable, using it will raise a NotImplementedError.
4279
4280[clinic start generated code]*/
4281
Larry Hastings2f936352014-08-05 14:04:04 +10004282static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004283os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4284/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004285{
4286 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004287
4288 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004289 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004290#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004291 /* Windows, success=1, UNIX, success=0 */
4292 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004293#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004294#ifdef HAVE_UNLINKAT
4295 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004296 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004297 else
4298#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004299 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004300#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004301 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004302 Py_END_ALLOW_THREADS
4303
Larry Hastings2f936352014-08-05 14:04:04 +10004304 if (result)
4305 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306
Larry Hastings2f936352014-08-05 14:04:04 +10004307 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004308}
4309
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004310
Larry Hastings2f936352014-08-05 14:04:04 +10004311/*[clinic input]
4312os.remove = os.unlink
4313
4314Remove a file (same as unlink()).
4315
4316If dir_fd is not None, it should be a file descriptor open to a directory,
4317 and path should be relative; path will then be relative to that directory.
4318dir_fd may not be implemented on your platform.
4319 If it is unavailable, using it will raise a NotImplementedError.
4320[clinic start generated code]*/
4321
Larry Hastings2f936352014-08-05 14:04:04 +10004322static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004323os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4324/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004325{
4326 return os_unlink_impl(module, path, dir_fd);
4327}
4328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Larry Hastings605a62d2012-06-24 04:33:36 -07004330static PyStructSequence_Field uname_result_fields[] = {
4331 {"sysname", "operating system name"},
4332 {"nodename", "name of machine on network (implementation-defined)"},
4333 {"release", "operating system release"},
4334 {"version", "operating system version"},
4335 {"machine", "hardware identifier"},
4336 {NULL}
4337};
4338
4339PyDoc_STRVAR(uname_result__doc__,
4340"uname_result: Result from os.uname().\n\n\
4341This object may be accessed either as a tuple of\n\
4342 (sysname, nodename, release, version, machine),\n\
4343or via the attributes sysname, nodename, release, version, and machine.\n\
4344\n\
4345See os.uname for more information.");
4346
4347static PyStructSequence_Desc uname_result_desc = {
4348 "uname_result", /* name */
4349 uname_result__doc__, /* doc */
4350 uname_result_fields,
4351 5
4352};
4353
4354static PyTypeObject UnameResultType;
4355
4356
4357#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004358/*[clinic input]
4359os.uname
4360
4361Return an object identifying the current operating system.
4362
4363The object behaves like a named tuple with the following fields:
4364 (sysname, nodename, release, version, machine)
4365
4366[clinic start generated code]*/
4367
Larry Hastings2f936352014-08-05 14:04:04 +10004368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004369os_uname_impl(PyObject *module)
4370/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004371{
Victor Stinner8c62be82010-05-06 00:08:46 +00004372 struct utsname u;
4373 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004374 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004375
Victor Stinner8c62be82010-05-06 00:08:46 +00004376 Py_BEGIN_ALLOW_THREADS
4377 res = uname(&u);
4378 Py_END_ALLOW_THREADS
4379 if (res < 0)
4380 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004381
4382 value = PyStructSequence_New(&UnameResultType);
4383 if (value == NULL)
4384 return NULL;
4385
4386#define SET(i, field) \
4387 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004388 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004389 if (!o) { \
4390 Py_DECREF(value); \
4391 return NULL; \
4392 } \
4393 PyStructSequence_SET_ITEM(value, i, o); \
4394 } \
4395
4396 SET(0, u.sysname);
4397 SET(1, u.nodename);
4398 SET(2, u.release);
4399 SET(3, u.version);
4400 SET(4, u.machine);
4401
4402#undef SET
4403
4404 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004405}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004406#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004407
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004408
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409
4410typedef struct {
4411 int now;
4412 time_t atime_s;
4413 long atime_ns;
4414 time_t mtime_s;
4415 long mtime_ns;
4416} utime_t;
4417
4418/*
Victor Stinner484df002014-10-09 13:52:31 +02004419 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004420 * they also intentionally leak the declaration of a pointer named "time"
4421 */
4422#define UTIME_TO_TIMESPEC \
4423 struct timespec ts[2]; \
4424 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004425 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004426 time = NULL; \
4427 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004428 ts[0].tv_sec = ut->atime_s; \
4429 ts[0].tv_nsec = ut->atime_ns; \
4430 ts[1].tv_sec = ut->mtime_s; \
4431 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432 time = ts; \
4433 } \
4434
4435#define UTIME_TO_TIMEVAL \
4436 struct timeval tv[2]; \
4437 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004438 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 time = NULL; \
4440 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004441 tv[0].tv_sec = ut->atime_s; \
4442 tv[0].tv_usec = ut->atime_ns / 1000; \
4443 tv[1].tv_sec = ut->mtime_s; \
4444 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004445 time = tv; \
4446 } \
4447
4448#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004449 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004451 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004452 time = NULL; \
4453 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004454 u.actime = ut->atime_s; \
4455 u.modtime = ut->mtime_s; \
4456 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457 }
4458
4459#define UTIME_TO_TIME_T \
4460 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004461 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004462 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463 time = NULL; \
4464 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004465 timet[0] = ut->atime_s; \
4466 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004467 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468 } \
4469
4470
Victor Stinner528a9ab2015-09-03 21:30:26 +02004471#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004472
4473static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004474utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475{
4476#ifdef HAVE_UTIMENSAT
4477 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4478 UTIME_TO_TIMESPEC;
4479 return utimensat(dir_fd, path, time, flags);
4480#elif defined(HAVE_FUTIMESAT)
4481 UTIME_TO_TIMEVAL;
4482 /*
4483 * follow_symlinks will never be false here;
4484 * we only allow !follow_symlinks and dir_fd together
4485 * if we have utimensat()
4486 */
4487 assert(follow_symlinks);
4488 return futimesat(dir_fd, path, time);
4489#endif
4490}
4491
Larry Hastings2f936352014-08-05 14:04:04 +10004492 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4493#else
4494 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004495#endif
4496
Victor Stinner528a9ab2015-09-03 21:30:26 +02004497#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004498
4499static int
Victor Stinner484df002014-10-09 13:52:31 +02004500utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004501{
4502#ifdef HAVE_FUTIMENS
4503 UTIME_TO_TIMESPEC;
4504 return futimens(fd, time);
4505#else
4506 UTIME_TO_TIMEVAL;
4507 return futimes(fd, time);
4508#endif
4509}
4510
Larry Hastings2f936352014-08-05 14:04:04 +10004511 #define PATH_UTIME_HAVE_FD 1
4512#else
4513 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004514#endif
4515
Victor Stinner5ebae872015-09-22 01:29:33 +02004516#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4517# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4518#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519
Victor Stinner4552ced2015-09-21 22:37:15 +02004520#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004521
4522static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004523utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524{
4525#ifdef HAVE_UTIMENSAT
4526 UTIME_TO_TIMESPEC;
4527 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4528#else
4529 UTIME_TO_TIMEVAL;
4530 return lutimes(path, time);
4531#endif
4532}
4533
4534#endif
4535
4536#ifndef MS_WINDOWS
4537
4538static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004539utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540{
4541#ifdef HAVE_UTIMENSAT
4542 UTIME_TO_TIMESPEC;
4543 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4544#elif defined(HAVE_UTIMES)
4545 UTIME_TO_TIMEVAL;
4546 return utimes(path, time);
4547#elif defined(HAVE_UTIME_H)
4548 UTIME_TO_UTIMBUF;
4549 return utime(path, time);
4550#else
4551 UTIME_TO_TIME_T;
4552 return utime(path, time);
4553#endif
4554}
4555
4556#endif
4557
Larry Hastings76ad59b2012-05-03 00:30:07 -07004558static int
4559split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4560{
4561 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004562 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004563 divmod = PyNumber_Divmod(py_long, billion);
4564 if (!divmod)
4565 goto exit;
Miss Islington (bot)329ea4e2018-09-12 12:46:30 -07004566 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4567 PyErr_Format(PyExc_TypeError,
4568 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4569 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4570 goto exit;
4571 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004572 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4573 if ((*s == -1) && PyErr_Occurred())
4574 goto exit;
4575 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004576 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004577 goto exit;
4578
4579 result = 1;
4580exit:
4581 Py_XDECREF(divmod);
4582 return result;
4583}
4584
Larry Hastings2f936352014-08-05 14:04:04 +10004585
4586/*[clinic input]
4587os.utime
4588
4589 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4590 times: object = NULL
4591 *
4592 ns: object = NULL
4593 dir_fd: dir_fd(requires='futimensat') = None
4594 follow_symlinks: bool=True
4595
Martin Panter0ff89092015-09-09 01:56:53 +00004596# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004597
4598Set the access and modified time of path.
4599
4600path may always be specified as a string.
4601On some platforms, path may also be specified as an open file descriptor.
4602 If this functionality is unavailable, using it raises an exception.
4603
4604If times is not None, it must be a tuple (atime, mtime);
4605 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004606If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004607 atime_ns and mtime_ns should be expressed as integer nanoseconds
4608 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004609If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004610Specifying tuples for both times and ns is an error.
4611
4612If dir_fd is not None, it should be a file descriptor open to a directory,
4613 and path should be relative; path will then be relative to that directory.
4614If follow_symlinks is False, and the last element of the path is a symbolic
4615 link, utime will modify the symbolic link itself instead of the file the
4616 link points to.
4617It is an error to use dir_fd or follow_symlinks when specifying path
4618 as an open file descriptor.
4619dir_fd and follow_symlinks may not be available on your platform.
4620 If they are unavailable, using them will raise a NotImplementedError.
4621
4622[clinic start generated code]*/
4623
Larry Hastings2f936352014-08-05 14:04:04 +10004624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004625os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4626 int dir_fd, int follow_symlinks)
4627/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004628{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629#ifdef MS_WINDOWS
4630 HANDLE hFile;
4631 FILETIME atime, mtime;
4632#else
4633 int result;
4634#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004635
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004637 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004638
Christian Heimesb3c87242013-08-01 00:08:16 +02004639 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004640
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 if (times && (times != Py_None) && ns) {
4642 PyErr_SetString(PyExc_ValueError,
4643 "utime: you may specify either 'times'"
4644 " or 'ns' but not both");
4645 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004646 }
4647
4648 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004649 time_t a_sec, m_sec;
4650 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004651 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 PyErr_SetString(PyExc_TypeError,
4653 "utime: 'times' must be either"
4654 " a tuple of two ints or None");
4655 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004656 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004657 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004658 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004659 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004660 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004661 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004662 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004663 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004664 utime.atime_s = a_sec;
4665 utime.atime_ns = a_nsec;
4666 utime.mtime_s = m_sec;
4667 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004670 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 PyErr_SetString(PyExc_TypeError,
4672 "utime: 'ns' must be a tuple of two ints");
4673 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004674 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004676 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004677 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004678 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004679 &utime.mtime_s, &utime.mtime_ns)) {
4680 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004681 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 }
4683 else {
4684 /* times and ns are both None/unspecified. use "now". */
4685 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004686 }
4687
Victor Stinner4552ced2015-09-21 22:37:15 +02004688#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689 if (follow_symlinks_specified("utime", follow_symlinks))
4690 goto exit;
4691#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004692
Larry Hastings2f936352014-08-05 14:04:04 +10004693 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4694 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4695 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004696 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004697
Larry Hastings9cf065c2012-06-22 16:30:09 -07004698#if !defined(HAVE_UTIMENSAT)
4699 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004700 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701 "utime: cannot use dir_fd and follow_symlinks "
4702 "together on this platform");
4703 goto exit;
4704 }
4705#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004706
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004707#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004709 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4710 NULL, OPEN_EXISTING,
4711 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 Py_END_ALLOW_THREADS
4713 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004714 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004716 }
4717
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004719 GetSystemTimeAsFileTime(&mtime);
4720 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004721 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004722 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004723 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4724 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004725 }
4726 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4727 /* Avoid putting the file name into the error here,
4728 as that may confuse the user into believing that
4729 something is wrong with the file, when it also
4730 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004731 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004734#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004736
Victor Stinner4552ced2015-09-21 22:37:15 +02004737#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004739 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004741#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742
Victor Stinner528a9ab2015-09-03 21:30:26 +02004743#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004745 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 else
4747#endif
4748
Victor Stinner528a9ab2015-09-03 21:30:26 +02004749#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004750 if (path->fd != -1)
4751 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 else
4753#endif
4754
Larry Hastings2f936352014-08-05 14:04:04 +10004755 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756
4757 Py_END_ALLOW_THREADS
4758
4759 if (result < 0) {
4760 /* see previous comment about not putting filename in error here */
4761 return_value = posix_error();
4762 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004763 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004764
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004765#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766
4767 Py_INCREF(Py_None);
4768 return_value = Py_None;
4769
4770exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771#ifdef MS_WINDOWS
4772 if (hFile != INVALID_HANDLE_VALUE)
4773 CloseHandle(hFile);
4774#endif
4775 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004776}
4777
Guido van Rossum3b066191991-06-04 19:40:25 +00004778/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004779
Larry Hastings2f936352014-08-05 14:04:04 +10004780
4781/*[clinic input]
4782os._exit
4783
4784 status: int
4785
4786Exit to the system with specified status, without normal exit processing.
4787[clinic start generated code]*/
4788
Larry Hastings2f936352014-08-05 14:04:04 +10004789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004790os__exit_impl(PyObject *module, int status)
4791/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004792{
4793 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004794 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004795}
4796
Steve Dowercc16be82016-09-08 10:35:16 -07004797#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4798#define EXECV_CHAR wchar_t
4799#else
4800#define EXECV_CHAR char
4801#endif
4802
Martin v. Löwis114619e2002-10-07 06:44:21 +00004803#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4804static void
Steve Dowercc16be82016-09-08 10:35:16 -07004805free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004806{
Victor Stinner8c62be82010-05-06 00:08:46 +00004807 Py_ssize_t i;
4808 for (i = 0; i < count; i++)
4809 PyMem_Free(array[i]);
4810 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004811}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004812
Berker Peksag81816462016-09-15 20:19:47 +03004813static int
4814fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004815{
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004817 PyObject *ub;
4818 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004819#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004820 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004821 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004822 *out = PyUnicode_AsWideCharString(ub, &size);
4823 if (*out)
4824 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004825#else
Berker Peksag81816462016-09-15 20:19:47 +03004826 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004827 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004828 size = PyBytes_GET_SIZE(ub);
4829 *out = PyMem_Malloc(size + 1);
4830 if (*out) {
4831 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4832 result = 1;
4833 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004834 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004835#endif
Berker Peksag81816462016-09-15 20:19:47 +03004836 Py_DECREF(ub);
4837 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004838}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004839#endif
4840
Ross Lagerwall7807c352011-03-17 20:20:30 +02004841#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004842static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004843parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4844{
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 Py_ssize_t i, pos, envc;
4846 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004847 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004848 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004849
Victor Stinner8c62be82010-05-06 00:08:46 +00004850 i = PyMapping_Size(env);
4851 if (i < 0)
4852 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004853 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 if (envlist == NULL) {
4855 PyErr_NoMemory();
4856 return NULL;
4857 }
4858 envc = 0;
4859 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004860 if (!keys)
4861 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004863 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004864 goto error;
4865 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4866 PyErr_Format(PyExc_TypeError,
4867 "env.keys() or env.values() is not a list");
4868 goto error;
4869 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004870
Victor Stinner8c62be82010-05-06 00:08:46 +00004871 for (pos = 0; pos < i; pos++) {
4872 key = PyList_GetItem(keys, pos);
4873 val = PyList_GetItem(vals, pos);
4874 if (!key || !val)
4875 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004876
Berker Peksag81816462016-09-15 20:19:47 +03004877#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4878 if (!PyUnicode_FSDecoder(key, &key2))
4879 goto error;
4880 if (!PyUnicode_FSDecoder(val, &val2)) {
4881 Py_DECREF(key2);
4882 goto error;
4883 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004884 /* Search from index 1 because on Windows starting '=' is allowed for
4885 defining hidden environment variables. */
4886 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4887 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4888 {
4889 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004890 Py_DECREF(key2);
4891 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004892 goto error;
4893 }
Berker Peksag81816462016-09-15 20:19:47 +03004894 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4895#else
4896 if (!PyUnicode_FSConverter(key, &key2))
4897 goto error;
4898 if (!PyUnicode_FSConverter(val, &val2)) {
4899 Py_DECREF(key2);
4900 goto error;
4901 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004902 if (PyBytes_GET_SIZE(key2) == 0 ||
4903 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4904 {
4905 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004906 Py_DECREF(key2);
4907 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004908 goto error;
4909 }
Berker Peksag81816462016-09-15 20:19:47 +03004910 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4911 PyBytes_AS_STRING(val2));
4912#endif
4913 Py_DECREF(key2);
4914 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004915 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004917
4918 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4919 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 goto error;
4921 }
Berker Peksag81816462016-09-15 20:19:47 +03004922
Steve Dowercc16be82016-09-08 10:35:16 -07004923 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 }
4925 Py_DECREF(vals);
4926 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 envlist[envc] = 0;
4929 *envc_ptr = envc;
4930 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004931
4932error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 Py_XDECREF(keys);
4934 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004935 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004937}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004938
Steve Dowercc16be82016-09-08 10:35:16 -07004939static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004940parse_arglist(PyObject* argv, Py_ssize_t *argc)
4941{
4942 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004943 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004944 if (argvlist == NULL) {
4945 PyErr_NoMemory();
4946 return NULL;
4947 }
4948 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004949 PyObject* item = PySequence_ITEM(argv, i);
4950 if (item == NULL)
4951 goto fail;
4952 if (!fsconvert_strdup(item, &argvlist[i])) {
4953 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004954 goto fail;
4955 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004956 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004957 }
4958 argvlist[*argc] = NULL;
4959 return argvlist;
4960fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004961 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 free_string_array(argvlist, *argc);
4963 return NULL;
4964}
Steve Dowercc16be82016-09-08 10:35:16 -07004965
Ross Lagerwall7807c352011-03-17 20:20:30 +02004966#endif
4967
Larry Hastings2f936352014-08-05 14:04:04 +10004968
Ross Lagerwall7807c352011-03-17 20:20:30 +02004969#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004970/*[clinic input]
4971os.execv
4972
Steve Dowercc16be82016-09-08 10:35:16 -07004973 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004974 Path of executable file.
4975 argv: object
4976 Tuple or list of strings.
4977 /
4978
4979Execute an executable path with arguments, replacing current process.
4980[clinic start generated code]*/
4981
Larry Hastings2f936352014-08-05 14:04:04 +10004982static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004983os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4984/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004985{
Steve Dowercc16be82016-09-08 10:35:16 -07004986 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004987 Py_ssize_t argc;
4988
4989 /* execv has two arguments: (path, argv), where
4990 argv is a list or tuple of strings. */
4991
Ross Lagerwall7807c352011-03-17 20:20:30 +02004992 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4993 PyErr_SetString(PyExc_TypeError,
4994 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004995 return NULL;
4996 }
4997 argc = PySequence_Size(argv);
4998 if (argc < 1) {
4999 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005000 return NULL;
5001 }
5002
5003 argvlist = parse_arglist(argv, &argc);
5004 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005 return NULL;
5006 }
Steve Dowerbce26262016-11-19 19:17:26 -08005007 if (!argvlist[0][0]) {
5008 PyErr_SetString(PyExc_ValueError,
5009 "execv() arg 2 first element cannot be empty");
5010 free_string_array(argvlist, argc);
5011 return NULL;
5012 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013
Steve Dowerbce26262016-11-19 19:17:26 -08005014 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005015#ifdef HAVE_WEXECV
5016 _wexecv(path->wide, argvlist);
5017#else
5018 execv(path->narrow, argvlist);
5019#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005020 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005021
5022 /* If we get here it's definitely an error */
5023
5024 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005025 return posix_error();
5026}
5027
Larry Hastings2f936352014-08-05 14:04:04 +10005028
5029/*[clinic input]
5030os.execve
5031
5032 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5033 Path of executable file.
5034 argv: object
5035 Tuple or list of strings.
5036 env: object
5037 Dictionary of strings mapping to strings.
5038
5039Execute an executable path with arguments, replacing current process.
5040[clinic start generated code]*/
5041
Larry Hastings2f936352014-08-05 14:04:04 +10005042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005043os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5044/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005045{
Steve Dowercc16be82016-09-08 10:35:16 -07005046 EXECV_CHAR **argvlist = NULL;
5047 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005049
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 /* execve has three arguments: (path, argv, env), where
5051 argv is a list or tuple of strings and env is a dictionary
5052 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005053
Ross Lagerwall7807c352011-03-17 20:20:30 +02005054 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005056 "execve: argv must be a tuple or list");
5057 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005060 if (argc < 1) {
5061 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5062 return NULL;
5063 }
5064
Victor Stinner8c62be82010-05-06 00:08:46 +00005065 if (!PyMapping_Check(env)) {
5066 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005067 "execve: environment must be a mapping object");
5068 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005070
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005073 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 }
Steve Dowerbce26262016-11-19 19:17:26 -08005075 if (!argvlist[0][0]) {
5076 PyErr_SetString(PyExc_ValueError,
5077 "execve: argv first element cannot be empty");
5078 goto fail;
5079 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005080
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 envlist = parse_envlist(env, &envc);
5082 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005083 goto fail;
5084
Steve Dowerbce26262016-11-19 19:17:26 -08005085 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005086#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005087 if (path->fd > -1)
5088 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005089 else
5090#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005091#ifdef HAVE_WEXECV
5092 _wexecve(path->wide, argvlist, envlist);
5093#else
Larry Hastings2f936352014-08-05 14:04:04 +10005094 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005095#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005096 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097
5098 /* If we get here it's definitely an error */
5099
Larry Hastings2f936352014-08-05 14:04:04 +10005100 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005101
Steve Dowercc16be82016-09-08 10:35:16 -07005102 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005103 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005104 if (argvlist)
5105 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005106 return NULL;
5107}
Steve Dowercc16be82016-09-08 10:35:16 -07005108
Larry Hastings9cf065c2012-06-22 16:30:09 -07005109#endif /* HAVE_EXECV */
5110
Steve Dowercc16be82016-09-08 10:35:16 -07005111#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005112/*[clinic input]
5113os.spawnv
5114
5115 mode: int
5116 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005117 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005118 Path of executable file.
5119 argv: object
5120 Tuple or list of strings.
5121 /
5122
5123Execute the program specified by path in a new process.
5124[clinic start generated code]*/
5125
Larry Hastings2f936352014-08-05 14:04:04 +10005126static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005127os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5128/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005129{
Steve Dowercc16be82016-09-08 10:35:16 -07005130 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005131 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005133 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005135
Victor Stinner8c62be82010-05-06 00:08:46 +00005136 /* spawnv has three arguments: (mode, path, argv), where
5137 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005138
Victor Stinner8c62be82010-05-06 00:08:46 +00005139 if (PyList_Check(argv)) {
5140 argc = PyList_Size(argv);
5141 getitem = PyList_GetItem;
5142 }
5143 else if (PyTuple_Check(argv)) {
5144 argc = PyTuple_Size(argv);
5145 getitem = PyTuple_GetItem;
5146 }
5147 else {
5148 PyErr_SetString(PyExc_TypeError,
5149 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 return NULL;
5151 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005152 if (argc == 0) {
5153 PyErr_SetString(PyExc_ValueError,
5154 "spawnv() arg 2 cannot be empty");
5155 return NULL;
5156 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005157
Steve Dowercc16be82016-09-08 10:35:16 -07005158 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005160 return PyErr_NoMemory();
5161 }
5162 for (i = 0; i < argc; i++) {
5163 if (!fsconvert_strdup((*getitem)(argv, i),
5164 &argvlist[i])) {
5165 free_string_array(argvlist, i);
5166 PyErr_SetString(
5167 PyExc_TypeError,
5168 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 return NULL;
5170 }
Steve Dower93ff8722016-11-19 19:03:54 -08005171 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005172 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005173 PyErr_SetString(
5174 PyExc_ValueError,
5175 "spawnv() arg 2 first element cannot be empty");
5176 return NULL;
5177 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 }
5179 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005180
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 if (mode == _OLD_P_OVERLAY)
5182 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005183
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005185 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005186#ifdef HAVE_WSPAWNV
5187 spawnval = _wspawnv(mode, path->wide, argvlist);
5188#else
5189 spawnval = _spawnv(mode, path->narrow, argvlist);
5190#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005191 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005193
Victor Stinner8c62be82010-05-06 00:08:46 +00005194 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 if (spawnval == -1)
5197 return posix_error();
5198 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005199 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005200}
5201
Larry Hastings2f936352014-08-05 14:04:04 +10005202/*[clinic input]
5203os.spawnve
5204
5205 mode: int
5206 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005207 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005208 Path of executable file.
5209 argv: object
5210 Tuple or list of strings.
5211 env: object
5212 Dictionary of strings mapping to strings.
5213 /
5214
5215Execute the program specified by path in a new process.
5216[clinic start generated code]*/
5217
Larry Hastings2f936352014-08-05 14:04:04 +10005218static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005219os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005220 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005221/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005222{
Steve Dowercc16be82016-09-08 10:35:16 -07005223 EXECV_CHAR **argvlist;
5224 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005226 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005227 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005229 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005230
Victor Stinner8c62be82010-05-06 00:08:46 +00005231 /* spawnve has four arguments: (mode, path, argv, env), where
5232 argv is a list or tuple of strings and env is a dictionary
5233 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005234
Victor Stinner8c62be82010-05-06 00:08:46 +00005235 if (PyList_Check(argv)) {
5236 argc = PyList_Size(argv);
5237 getitem = PyList_GetItem;
5238 }
5239 else if (PyTuple_Check(argv)) {
5240 argc = PyTuple_Size(argv);
5241 getitem = PyTuple_GetItem;
5242 }
5243 else {
5244 PyErr_SetString(PyExc_TypeError,
5245 "spawnve() arg 2 must be a tuple or list");
5246 goto fail_0;
5247 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005248 if (argc == 0) {
5249 PyErr_SetString(PyExc_ValueError,
5250 "spawnve() arg 2 cannot be empty");
5251 goto fail_0;
5252 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 if (!PyMapping_Check(env)) {
5254 PyErr_SetString(PyExc_TypeError,
5255 "spawnve() arg 3 must be a mapping object");
5256 goto fail_0;
5257 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005258
Steve Dowercc16be82016-09-08 10:35:16 -07005259 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 if (argvlist == NULL) {
5261 PyErr_NoMemory();
5262 goto fail_0;
5263 }
5264 for (i = 0; i < argc; i++) {
5265 if (!fsconvert_strdup((*getitem)(argv, i),
5266 &argvlist[i]))
5267 {
5268 lastarg = i;
5269 goto fail_1;
5270 }
Steve Dowerbce26262016-11-19 19:17:26 -08005271 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005272 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005273 PyErr_SetString(
5274 PyExc_ValueError,
5275 "spawnv() arg 2 first element cannot be empty");
5276 goto fail_1;
5277 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 }
5279 lastarg = argc;
5280 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005281
Victor Stinner8c62be82010-05-06 00:08:46 +00005282 envlist = parse_envlist(env, &envc);
5283 if (envlist == NULL)
5284 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005285
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 if (mode == _OLD_P_OVERLAY)
5287 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005288
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005290 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005291#ifdef HAVE_WSPAWNV
5292 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5293#else
5294 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5295#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005296 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 if (spawnval == -1)
5300 (void) posix_error();
5301 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005302 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 while (--envc >= 0)
5305 PyMem_DEL(envlist[envc]);
5306 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005307 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005308 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005309 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005311}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005312
Guido van Rossuma1065681999-01-25 23:20:23 +00005313#endif /* HAVE_SPAWNV */
5314
5315
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005316#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005317
5318/* Helper function to validate arguments.
5319 Returns 0 on success. non-zero on failure with a TypeError raised.
5320 If obj is non-NULL it must be callable. */
5321static int
5322check_null_or_callable(PyObject *obj, const char* obj_name)
5323{
5324 if (obj && !PyCallable_Check(obj)) {
5325 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5326 obj_name, Py_TYPE(obj)->tp_name);
5327 return -1;
5328 }
5329 return 0;
5330}
5331
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005332/*[clinic input]
5333os.register_at_fork
5334
Gregory P. Smith163468a2017-05-29 10:03:41 -07005335 *
5336 before: object=NULL
5337 A callable to be called in the parent before the fork() syscall.
5338 after_in_child: object=NULL
5339 A callable to be called in the child after fork().
5340 after_in_parent: object=NULL
5341 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005342
Gregory P. Smith163468a2017-05-29 10:03:41 -07005343Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005344
Gregory P. Smith163468a2017-05-29 10:03:41 -07005345'before' callbacks are called in reverse order.
5346'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005347
5348[clinic start generated code]*/
5349
5350static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005351os_register_at_fork_impl(PyObject *module, PyObject *before,
5352 PyObject *after_in_child, PyObject *after_in_parent)
5353/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005354{
5355 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005356
Gregory P. Smith163468a2017-05-29 10:03:41 -07005357 if (!before && !after_in_child && !after_in_parent) {
5358 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5359 return NULL;
5360 }
5361 if (check_null_or_callable(before, "before") ||
5362 check_null_or_callable(after_in_child, "after_in_child") ||
5363 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005364 return NULL;
5365 }
5366 interp = PyThreadState_Get()->interp;
5367
Gregory P. Smith163468a2017-05-29 10:03:41 -07005368 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005369 return NULL;
5370 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005371 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005372 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005373 }
5374 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5375 return NULL;
5376 }
5377 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005378}
5379#endif /* HAVE_FORK */
5380
5381
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005382#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005383/*[clinic input]
5384os.fork1
5385
5386Fork a child process with a single multiplexed (i.e., not bound) thread.
5387
5388Return 0 to child process and PID of child to parent process.
5389[clinic start generated code]*/
5390
Larry Hastings2f936352014-08-05 14:04:04 +10005391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005392os_fork1_impl(PyObject *module)
5393/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005394{
Victor Stinner8c62be82010-05-06 00:08:46 +00005395 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005396
5397 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 pid = fork1();
5399 if (pid == 0) {
5400 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005401 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 } else {
5403 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005404 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 }
5406 if (pid == -1)
5407 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005409}
Larry Hastings2f936352014-08-05 14:04:04 +10005410#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005411
5412
Guido van Rossumad0ee831995-03-01 10:34:45 +00005413#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005414/*[clinic input]
5415os.fork
5416
5417Fork a child process.
5418
5419Return 0 to child process and PID of child to parent process.
5420[clinic start generated code]*/
5421
Larry Hastings2f936352014-08-05 14:04:04 +10005422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005423os_fork_impl(PyObject *module)
5424/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005425{
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005427
5428 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005429 pid = fork();
5430 if (pid == 0) {
5431 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005432 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005433 } else {
5434 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005435 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 }
5437 if (pid == -1)
5438 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005439 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005440}
Larry Hastings2f936352014-08-05 14:04:04 +10005441#endif /* HAVE_FORK */
5442
Guido van Rossum85e3b011991-06-03 12:42:10 +00005443
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005444#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005445#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005446/*[clinic input]
5447os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005448
Larry Hastings2f936352014-08-05 14:04:04 +10005449 policy: int
5450
5451Get the maximum scheduling priority for policy.
5452[clinic start generated code]*/
5453
Larry Hastings2f936352014-08-05 14:04:04 +10005454static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005455os_sched_get_priority_max_impl(PyObject *module, int policy)
5456/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005457{
5458 int max;
5459
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005460 max = sched_get_priority_max(policy);
5461 if (max < 0)
5462 return posix_error();
5463 return PyLong_FromLong(max);
5464}
5465
Larry Hastings2f936352014-08-05 14:04:04 +10005466
5467/*[clinic input]
5468os.sched_get_priority_min
5469
5470 policy: int
5471
5472Get the minimum scheduling priority for policy.
5473[clinic start generated code]*/
5474
Larry Hastings2f936352014-08-05 14:04:04 +10005475static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005476os_sched_get_priority_min_impl(PyObject *module, int policy)
5477/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005478{
5479 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005480 if (min < 0)
5481 return posix_error();
5482 return PyLong_FromLong(min);
5483}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005484#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5485
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005486
Larry Hastings2f936352014-08-05 14:04:04 +10005487#ifdef HAVE_SCHED_SETSCHEDULER
5488/*[clinic input]
5489os.sched_getscheduler
5490 pid: pid_t
5491 /
5492
5493Get the scheduling policy for the process identifiedy by pid.
5494
5495Passing 0 for pid returns the scheduling policy for the calling process.
5496[clinic start generated code]*/
5497
Larry Hastings2f936352014-08-05 14:04:04 +10005498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005499os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5500/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005501{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005502 int policy;
5503
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005504 policy = sched_getscheduler(pid);
5505 if (policy < 0)
5506 return posix_error();
5507 return PyLong_FromLong(policy);
5508}
Larry Hastings2f936352014-08-05 14:04:04 +10005509#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005510
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005511
5512#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005513/*[clinic input]
5514class os.sched_param "PyObject *" "&SchedParamType"
5515
5516@classmethod
5517os.sched_param.__new__
5518
5519 sched_priority: object
5520 A scheduling parameter.
5521
5522Current has only one field: sched_priority");
5523[clinic start generated code]*/
5524
Larry Hastings2f936352014-08-05 14:04:04 +10005525static PyObject *
5526os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005527/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005528{
5529 PyObject *res;
5530
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005531 res = PyStructSequence_New(type);
5532 if (!res)
5533 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005534 Py_INCREF(sched_priority);
5535 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005536 return res;
5537}
5538
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005539
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005540PyDoc_VAR(os_sched_param__doc__);
5541
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005542static PyStructSequence_Field sched_param_fields[] = {
5543 {"sched_priority", "the scheduling priority"},
5544 {0}
5545};
5546
5547static PyStructSequence_Desc sched_param_desc = {
5548 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005549 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005550 sched_param_fields,
5551 1
5552};
5553
5554static int
5555convert_sched_param(PyObject *param, struct sched_param *res)
5556{
5557 long priority;
5558
5559 if (Py_TYPE(param) != &SchedParamType) {
5560 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5561 return 0;
5562 }
5563 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5564 if (priority == -1 && PyErr_Occurred())
5565 return 0;
5566 if (priority > INT_MAX || priority < INT_MIN) {
5567 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5568 return 0;
5569 }
5570 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5571 return 1;
5572}
Larry Hastings2f936352014-08-05 14:04:04 +10005573#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005574
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005575
5576#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005577/*[clinic input]
5578os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005579
Larry Hastings2f936352014-08-05 14:04:04 +10005580 pid: pid_t
5581 policy: int
5582 param: sched_param
5583 /
5584
5585Set the scheduling policy for the process identified by pid.
5586
5587If pid is 0, the calling process is changed.
5588param is an instance of sched_param.
5589[clinic start generated code]*/
5590
Larry Hastings2f936352014-08-05 14:04:04 +10005591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005592os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005593 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005594/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005595{
Jesus Cea9c822272011-09-10 01:40:52 +02005596 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005597 ** sched_setscheduler() returns 0 in Linux, but the previous
5598 ** scheduling policy under Solaris/Illumos, and others.
5599 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005600 */
Larry Hastings2f936352014-08-05 14:04:04 +10005601 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005602 return posix_error();
5603 Py_RETURN_NONE;
5604}
Larry Hastings2f936352014-08-05 14:04:04 +10005605#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005606
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005607
5608#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005609/*[clinic input]
5610os.sched_getparam
5611 pid: pid_t
5612 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005613
Larry Hastings2f936352014-08-05 14:04:04 +10005614Returns scheduling parameters for the process identified by pid.
5615
5616If pid is 0, returns parameters for the calling process.
5617Return value is an instance of sched_param.
5618[clinic start generated code]*/
5619
Larry Hastings2f936352014-08-05 14:04:04 +10005620static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005621os_sched_getparam_impl(PyObject *module, pid_t pid)
5622/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005623{
5624 struct sched_param param;
5625 PyObject *result;
5626 PyObject *priority;
5627
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005628 if (sched_getparam(pid, &param))
5629 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005630 result = PyStructSequence_New(&SchedParamType);
5631 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005632 return NULL;
5633 priority = PyLong_FromLong(param.sched_priority);
5634 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005635 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005636 return NULL;
5637 }
Larry Hastings2f936352014-08-05 14:04:04 +10005638 PyStructSequence_SET_ITEM(result, 0, priority);
5639 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005640}
5641
Larry Hastings2f936352014-08-05 14:04:04 +10005642
5643/*[clinic input]
5644os.sched_setparam
5645 pid: pid_t
5646 param: sched_param
5647 /
5648
5649Set scheduling parameters for the process identified by pid.
5650
5651If pid is 0, sets parameters for the calling process.
5652param should be an instance of sched_param.
5653[clinic start generated code]*/
5654
Larry Hastings2f936352014-08-05 14:04:04 +10005655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005656os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005657 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005658/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005659{
5660 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005661 return posix_error();
5662 Py_RETURN_NONE;
5663}
Larry Hastings2f936352014-08-05 14:04:04 +10005664#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005665
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005666
5667#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005668/*[clinic input]
5669os.sched_rr_get_interval -> double
5670 pid: pid_t
5671 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005672
Larry Hastings2f936352014-08-05 14:04:04 +10005673Return the round-robin quantum for the process identified by pid, in seconds.
5674
5675Value returned is a float.
5676[clinic start generated code]*/
5677
Larry Hastings2f936352014-08-05 14:04:04 +10005678static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005679os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5680/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005681{
5682 struct timespec interval;
5683 if (sched_rr_get_interval(pid, &interval)) {
5684 posix_error();
5685 return -1.0;
5686 }
5687 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5688}
5689#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005690
Larry Hastings2f936352014-08-05 14:04:04 +10005691
5692/*[clinic input]
5693os.sched_yield
5694
5695Voluntarily relinquish the CPU.
5696[clinic start generated code]*/
5697
Larry Hastings2f936352014-08-05 14:04:04 +10005698static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005699os_sched_yield_impl(PyObject *module)
5700/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005701{
5702 if (sched_yield())
5703 return posix_error();
5704 Py_RETURN_NONE;
5705}
5706
Benjamin Peterson2740af82011-08-02 17:41:34 -05005707#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005708/* The minimum number of CPUs allocated in a cpu_set_t */
5709static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005710
Larry Hastings2f936352014-08-05 14:04:04 +10005711/*[clinic input]
5712os.sched_setaffinity
5713 pid: pid_t
5714 mask : object
5715 /
5716
5717Set the CPU affinity of the process identified by pid to mask.
5718
5719mask should be an iterable of integers identifying CPUs.
5720[clinic start generated code]*/
5721
Larry Hastings2f936352014-08-05 14:04:04 +10005722static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005723os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5724/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005725{
Antoine Pitrou84869872012-08-04 16:16:35 +02005726 int ncpus;
5727 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005728 cpu_set_t *cpu_set = NULL;
5729 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005730
Larry Hastings2f936352014-08-05 14:04:04 +10005731 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005732 if (iterator == NULL)
5733 return NULL;
5734
5735 ncpus = NCPUS_START;
5736 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005737 cpu_set = CPU_ALLOC(ncpus);
5738 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005739 PyErr_NoMemory();
5740 goto error;
5741 }
Larry Hastings2f936352014-08-05 14:04:04 +10005742 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005743
5744 while ((item = PyIter_Next(iterator))) {
5745 long cpu;
5746 if (!PyLong_Check(item)) {
5747 PyErr_Format(PyExc_TypeError,
5748 "expected an iterator of ints, "
5749 "but iterator yielded %R",
5750 Py_TYPE(item));
5751 Py_DECREF(item);
5752 goto error;
5753 }
5754 cpu = PyLong_AsLong(item);
5755 Py_DECREF(item);
5756 if (cpu < 0) {
5757 if (!PyErr_Occurred())
5758 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5759 goto error;
5760 }
5761 if (cpu > INT_MAX - 1) {
5762 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5763 goto error;
5764 }
5765 if (cpu >= ncpus) {
5766 /* Grow CPU mask to fit the CPU number */
5767 int newncpus = ncpus;
5768 cpu_set_t *newmask;
5769 size_t newsetsize;
5770 while (newncpus <= cpu) {
5771 if (newncpus > INT_MAX / 2)
5772 newncpus = cpu + 1;
5773 else
5774 newncpus = newncpus * 2;
5775 }
5776 newmask = CPU_ALLOC(newncpus);
5777 if (newmask == NULL) {
5778 PyErr_NoMemory();
5779 goto error;
5780 }
5781 newsetsize = CPU_ALLOC_SIZE(newncpus);
5782 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005783 memcpy(newmask, cpu_set, setsize);
5784 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005785 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005786 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005787 ncpus = newncpus;
5788 }
Larry Hastings2f936352014-08-05 14:04:04 +10005789 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005790 }
5791 Py_CLEAR(iterator);
5792
Larry Hastings2f936352014-08-05 14:04:04 +10005793 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005794 posix_error();
5795 goto error;
5796 }
Larry Hastings2f936352014-08-05 14:04:04 +10005797 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005798 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005799
5800error:
Larry Hastings2f936352014-08-05 14:04:04 +10005801 if (cpu_set)
5802 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005803 Py_XDECREF(iterator);
5804 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005805}
5806
Larry Hastings2f936352014-08-05 14:04:04 +10005807
5808/*[clinic input]
5809os.sched_getaffinity
5810 pid: pid_t
5811 /
5812
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005813Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005814
5815The affinity is returned as a set of CPU identifiers.
5816[clinic start generated code]*/
5817
Larry Hastings2f936352014-08-05 14:04:04 +10005818static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005819os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005820/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005821{
Antoine Pitrou84869872012-08-04 16:16:35 +02005822 int cpu, ncpus, count;
5823 size_t setsize;
5824 cpu_set_t *mask = NULL;
5825 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005826
Antoine Pitrou84869872012-08-04 16:16:35 +02005827 ncpus = NCPUS_START;
5828 while (1) {
5829 setsize = CPU_ALLOC_SIZE(ncpus);
5830 mask = CPU_ALLOC(ncpus);
5831 if (mask == NULL)
5832 return PyErr_NoMemory();
5833 if (sched_getaffinity(pid, setsize, mask) == 0)
5834 break;
5835 CPU_FREE(mask);
5836 if (errno != EINVAL)
5837 return posix_error();
5838 if (ncpus > INT_MAX / 2) {
5839 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5840 "a large enough CPU set");
5841 return NULL;
5842 }
5843 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005844 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005845
5846 res = PySet_New(NULL);
5847 if (res == NULL)
5848 goto error;
5849 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5850 if (CPU_ISSET_S(cpu, setsize, mask)) {
5851 PyObject *cpu_num = PyLong_FromLong(cpu);
5852 --count;
5853 if (cpu_num == NULL)
5854 goto error;
5855 if (PySet_Add(res, cpu_num)) {
5856 Py_DECREF(cpu_num);
5857 goto error;
5858 }
5859 Py_DECREF(cpu_num);
5860 }
5861 }
5862 CPU_FREE(mask);
5863 return res;
5864
5865error:
5866 if (mask)
5867 CPU_FREE(mask);
5868 Py_XDECREF(res);
5869 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005870}
5871
Benjamin Peterson2740af82011-08-02 17:41:34 -05005872#endif /* HAVE_SCHED_SETAFFINITY */
5873
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005874#endif /* HAVE_SCHED_H */
5875
Larry Hastings2f936352014-08-05 14:04:04 +10005876
Neal Norwitzb59798b2003-03-21 01:43:31 +00005877/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005878/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5879#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005880#define DEV_PTY_FILE "/dev/ptc"
5881#define HAVE_DEV_PTMX
5882#else
5883#define DEV_PTY_FILE "/dev/ptmx"
5884#endif
5885
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005886#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005887#ifdef HAVE_PTY_H
5888#include <pty.h>
5889#else
5890#ifdef HAVE_LIBUTIL_H
5891#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005892#else
5893#ifdef HAVE_UTIL_H
5894#include <util.h>
5895#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005896#endif /* HAVE_LIBUTIL_H */
5897#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005898#ifdef HAVE_STROPTS_H
5899#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005900#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005901#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005902
Larry Hastings2f936352014-08-05 14:04:04 +10005903
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005904#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005905/*[clinic input]
5906os.openpty
5907
5908Open a pseudo-terminal.
5909
5910Return a tuple of (master_fd, slave_fd) containing open file descriptors
5911for both the master and slave ends.
5912[clinic start generated code]*/
5913
Larry Hastings2f936352014-08-05 14:04:04 +10005914static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005915os_openpty_impl(PyObject *module)
5916/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005917{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005918 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005919#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005921#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005922#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005924#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005926#endif
5927#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005928
Thomas Wouters70c21a12000-07-14 14:28:33 +00005929#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005931 goto posix_error;
5932
5933 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5934 goto error;
5935 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5936 goto error;
5937
Neal Norwitzb59798b2003-03-21 01:43:31 +00005938#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005939 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5940 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005941 goto posix_error;
5942 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5943 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005944
Victor Stinnerdaf45552013-08-28 00:53:59 +02005945 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005947 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005948
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005949#else
Victor Stinner000de532013-11-25 23:19:58 +01005950 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005952 goto posix_error;
5953
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005955
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 /* change permission of slave */
5957 if (grantpt(master_fd) < 0) {
5958 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005959 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005961
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 /* unlock slave */
5963 if (unlockpt(master_fd) < 0) {
5964 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005965 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005967
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005969
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 slave_name = ptsname(master_fd); /* get name of slave */
5971 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005972 goto posix_error;
5973
5974 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005975 if (slave_fd == -1)
5976 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005977
5978 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5979 goto posix_error;
5980
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005981#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5983 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005984#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005986#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005987#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005988#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005989
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005991
Victor Stinnerdaf45552013-08-28 00:53:59 +02005992posix_error:
5993 posix_error();
5994error:
5995 if (master_fd != -1)
5996 close(master_fd);
5997 if (slave_fd != -1)
5998 close(slave_fd);
5999 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006000}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006001#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006002
Larry Hastings2f936352014-08-05 14:04:04 +10006003
Fred Drake8cef4cf2000-06-28 16:40:38 +00006004#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006005/*[clinic input]
6006os.forkpty
6007
6008Fork a new process with a new pseudo-terminal as controlling tty.
6009
6010Returns a tuple of (pid, master_fd).
6011Like fork(), return pid of 0 to the child process,
6012and pid of child to the parent process.
6013To both, return fd of newly opened pseudo-terminal.
6014[clinic start generated code]*/
6015
Larry Hastings2f936352014-08-05 14:04:04 +10006016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006017os_forkpty_impl(PyObject *module)
6018/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006019{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006020 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006022
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006023 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 pid = forkpty(&master_fd, NULL, NULL, NULL);
6025 if (pid == 0) {
6026 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006027 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 } else {
6029 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006030 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 }
6032 if (pid == -1)
6033 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006035}
Larry Hastings2f936352014-08-05 14:04:04 +10006036#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006037
Ross Lagerwall7807c352011-03-17 20:20:30 +02006038
Guido van Rossumad0ee831995-03-01 10:34:45 +00006039#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006040/*[clinic input]
6041os.getegid
6042
6043Return the current process's effective group id.
6044[clinic start generated code]*/
6045
Larry Hastings2f936352014-08-05 14:04:04 +10006046static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006047os_getegid_impl(PyObject *module)
6048/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006049{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006050 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006051}
Larry Hastings2f936352014-08-05 14:04:04 +10006052#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006054
Guido van Rossumad0ee831995-03-01 10:34:45 +00006055#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006056/*[clinic input]
6057os.geteuid
6058
6059Return the current process's effective user id.
6060[clinic start generated code]*/
6061
Larry Hastings2f936352014-08-05 14:04:04 +10006062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006063os_geteuid_impl(PyObject *module)
6064/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006065{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006066 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006067}
Larry Hastings2f936352014-08-05 14:04:04 +10006068#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006070
Guido van Rossumad0ee831995-03-01 10:34:45 +00006071#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006072/*[clinic input]
6073os.getgid
6074
6075Return the current process's group id.
6076[clinic start generated code]*/
6077
Larry Hastings2f936352014-08-05 14:04:04 +10006078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006079os_getgid_impl(PyObject *module)
6080/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006081{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006082 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006083}
Larry Hastings2f936352014-08-05 14:04:04 +10006084#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006086
Berker Peksag39404992016-09-15 20:45:16 +03006087#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006088/*[clinic input]
6089os.getpid
6090
6091Return the current process id.
6092[clinic start generated code]*/
6093
Larry Hastings2f936352014-08-05 14:04:04 +10006094static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006095os_getpid_impl(PyObject *module)
6096/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006097{
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006099}
Berker Peksag39404992016-09-15 20:45:16 +03006100#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006101
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006102#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006103
6104/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006105PyDoc_STRVAR(posix_getgrouplist__doc__,
6106"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6107Returns a list of groups to which a user belongs.\n\n\
6108 user: username to lookup\n\
6109 group: base group id of the user");
6110
6111static PyObject *
6112posix_getgrouplist(PyObject *self, PyObject *args)
6113{
6114#ifdef NGROUPS_MAX
6115#define MAX_GROUPS NGROUPS_MAX
6116#else
6117 /* defined to be 16 on Solaris7, so this should be a small number */
6118#define MAX_GROUPS 64
6119#endif
6120
6121 const char *user;
6122 int i, ngroups;
6123 PyObject *list;
6124#ifdef __APPLE__
6125 int *groups, basegid;
6126#else
6127 gid_t *groups, basegid;
6128#endif
6129 ngroups = MAX_GROUPS;
6130
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006131#ifdef __APPLE__
6132 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006133 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006134#else
6135 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6136 _Py_Gid_Converter, &basegid))
6137 return NULL;
6138#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006139
6140#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006141 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006142#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006143 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006144#endif
6145 if (groups == NULL)
6146 return PyErr_NoMemory();
6147
6148 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6149 PyMem_Del(groups);
6150 return posix_error();
6151 }
6152
6153 list = PyList_New(ngroups);
6154 if (list == NULL) {
6155 PyMem_Del(groups);
6156 return NULL;
6157 }
6158
6159 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006160#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006161 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006162#else
6163 PyObject *o = _PyLong_FromGid(groups[i]);
6164#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006165 if (o == NULL) {
6166 Py_DECREF(list);
6167 PyMem_Del(groups);
6168 return NULL;
6169 }
6170 PyList_SET_ITEM(list, i, o);
6171 }
6172
6173 PyMem_Del(groups);
6174
6175 return list;
6176}
Larry Hastings2f936352014-08-05 14:04:04 +10006177#endif /* HAVE_GETGROUPLIST */
6178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006179
Fred Drakec9680921999-12-13 16:37:25 +00006180#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006181/*[clinic input]
6182os.getgroups
6183
6184Return list of supplemental group IDs for the process.
6185[clinic start generated code]*/
6186
Larry Hastings2f936352014-08-05 14:04:04 +10006187static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006188os_getgroups_impl(PyObject *module)
6189/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006190{
6191 PyObject *result = NULL;
6192
Fred Drakec9680921999-12-13 16:37:25 +00006193#ifdef NGROUPS_MAX
6194#define MAX_GROUPS NGROUPS_MAX
6195#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006197#define MAX_GROUPS 64
6198#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006200
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006201 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006202 * This is a helper variable to store the intermediate result when
6203 * that happens.
6204 *
6205 * To keep the code readable the OSX behaviour is unconditional,
6206 * according to the POSIX spec this should be safe on all unix-y
6207 * systems.
6208 */
6209 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006210 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006211
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006212#ifdef __APPLE__
6213 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6214 * there are more groups than can fit in grouplist. Therefore, on OS X
6215 * always first call getgroups with length 0 to get the actual number
6216 * of groups.
6217 */
6218 n = getgroups(0, NULL);
6219 if (n < 0) {
6220 return posix_error();
6221 } else if (n <= MAX_GROUPS) {
6222 /* groups will fit in existing array */
6223 alt_grouplist = grouplist;
6224 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006225 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006226 if (alt_grouplist == NULL) {
6227 errno = EINVAL;
6228 return posix_error();
6229 }
6230 }
6231
6232 n = getgroups(n, alt_grouplist);
6233 if (n == -1) {
6234 if (alt_grouplist != grouplist) {
6235 PyMem_Free(alt_grouplist);
6236 }
6237 return posix_error();
6238 }
6239#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006241 if (n < 0) {
6242 if (errno == EINVAL) {
6243 n = getgroups(0, NULL);
6244 if (n == -1) {
6245 return posix_error();
6246 }
6247 if (n == 0) {
6248 /* Avoid malloc(0) */
6249 alt_grouplist = grouplist;
6250 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006251 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006252 if (alt_grouplist == NULL) {
6253 errno = EINVAL;
6254 return posix_error();
6255 }
6256 n = getgroups(n, alt_grouplist);
6257 if (n == -1) {
6258 PyMem_Free(alt_grouplist);
6259 return posix_error();
6260 }
6261 }
6262 } else {
6263 return posix_error();
6264 }
6265 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006266#endif
6267
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006268 result = PyList_New(n);
6269 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 int i;
6271 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006272 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006274 Py_DECREF(result);
6275 result = NULL;
6276 break;
Fred Drakec9680921999-12-13 16:37:25 +00006277 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006279 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006280 }
6281
6282 if (alt_grouplist != grouplist) {
6283 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006284 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006285
Fred Drakec9680921999-12-13 16:37:25 +00006286 return result;
6287}
Larry Hastings2f936352014-08-05 14:04:04 +10006288#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006289
Antoine Pitroub7572f02009-12-02 20:46:48 +00006290#ifdef HAVE_INITGROUPS
6291PyDoc_STRVAR(posix_initgroups__doc__,
6292"initgroups(username, gid) -> None\n\n\
6293Call the system initgroups() to initialize the group access list with all of\n\
6294the groups of which the specified username is a member, plus the specified\n\
6295group id.");
6296
Larry Hastings2f936352014-08-05 14:04:04 +10006297/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006298static PyObject *
6299posix_initgroups(PyObject *self, PyObject *args)
6300{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006301 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006302 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006303 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006304#ifdef __APPLE__
6305 int gid;
6306#else
6307 gid_t gid;
6308#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006309
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006310#ifdef __APPLE__
6311 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6312 PyUnicode_FSConverter, &oname,
6313 &gid))
6314#else
6315 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6316 PyUnicode_FSConverter, &oname,
6317 _Py_Gid_Converter, &gid))
6318#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006319 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006320 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006321
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006322 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006323 Py_DECREF(oname);
6324 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006326
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006327 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006328}
Larry Hastings2f936352014-08-05 14:04:04 +10006329#endif /* HAVE_INITGROUPS */
6330
Antoine Pitroub7572f02009-12-02 20:46:48 +00006331
Martin v. Löwis606edc12002-06-13 21:09:11 +00006332#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006333/*[clinic input]
6334os.getpgid
6335
6336 pid: pid_t
6337
6338Call the system call getpgid(), and return the result.
6339[clinic start generated code]*/
6340
Larry Hastings2f936352014-08-05 14:04:04 +10006341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006342os_getpgid_impl(PyObject *module, pid_t pid)
6343/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006344{
6345 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 if (pgid < 0)
6347 return posix_error();
6348 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006349}
6350#endif /* HAVE_GETPGID */
6351
6352
Guido van Rossumb6775db1994-08-01 11:34:53 +00006353#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006354/*[clinic input]
6355os.getpgrp
6356
6357Return the current process group id.
6358[clinic start generated code]*/
6359
Larry Hastings2f936352014-08-05 14:04:04 +10006360static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006361os_getpgrp_impl(PyObject *module)
6362/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006363{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006364#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006366#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006368#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006369}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006372
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006374/*[clinic input]
6375os.setpgrp
6376
6377Make the current process the leader of its process group.
6378[clinic start generated code]*/
6379
Larry Hastings2f936352014-08-05 14:04:04 +10006380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006381os_setpgrp_impl(PyObject *module)
6382/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006383{
Guido van Rossum64933891994-10-20 21:56:42 +00006384#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006386#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006388#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006390 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006391}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006392#endif /* HAVE_SETPGRP */
6393
Guido van Rossumad0ee831995-03-01 10:34:45 +00006394#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006395
6396#ifdef MS_WINDOWS
6397#include <tlhelp32.h>
6398
6399static PyObject*
6400win32_getppid()
6401{
6402 HANDLE snapshot;
6403 pid_t mypid;
6404 PyObject* result = NULL;
6405 BOOL have_record;
6406 PROCESSENTRY32 pe;
6407
6408 mypid = getpid(); /* This function never fails */
6409
6410 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6411 if (snapshot == INVALID_HANDLE_VALUE)
6412 return PyErr_SetFromWindowsErr(GetLastError());
6413
6414 pe.dwSize = sizeof(pe);
6415 have_record = Process32First(snapshot, &pe);
6416 while (have_record) {
6417 if (mypid == (pid_t)pe.th32ProcessID) {
6418 /* We could cache the ulong value in a static variable. */
6419 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6420 break;
6421 }
6422
6423 have_record = Process32Next(snapshot, &pe);
6424 }
6425
6426 /* If our loop exits and our pid was not found (result will be NULL)
6427 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6428 * error anyway, so let's raise it. */
6429 if (!result)
6430 result = PyErr_SetFromWindowsErr(GetLastError());
6431
6432 CloseHandle(snapshot);
6433
6434 return result;
6435}
6436#endif /*MS_WINDOWS*/
6437
Larry Hastings2f936352014-08-05 14:04:04 +10006438
6439/*[clinic input]
6440os.getppid
6441
6442Return the parent's process id.
6443
6444If the parent process has already exited, Windows machines will still
6445return its id; others systems will return the id of the 'init' process (1).
6446[clinic start generated code]*/
6447
Larry Hastings2f936352014-08-05 14:04:04 +10006448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006449os_getppid_impl(PyObject *module)
6450/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006451{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006452#ifdef MS_WINDOWS
6453 return win32_getppid();
6454#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006456#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006457}
6458#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006460
Fred Drake12c6e2d1999-12-14 21:25:03 +00006461#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006462/*[clinic input]
6463os.getlogin
6464
6465Return the actual login name.
6466[clinic start generated code]*/
6467
Larry Hastings2f936352014-08-05 14:04:04 +10006468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006469os_getlogin_impl(PyObject *module)
6470/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006471{
Victor Stinner8c62be82010-05-06 00:08:46 +00006472 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006473#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006474 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006475 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006476
6477 if (GetUserNameW(user_name, &num_chars)) {
6478 /* num_chars is the number of unicode chars plus null terminator */
6479 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006480 }
6481 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006482 result = PyErr_SetFromWindowsErr(GetLastError());
6483#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 char *name;
6485 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006486
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 errno = 0;
6488 name = getlogin();
6489 if (name == NULL) {
6490 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006491 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006492 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006493 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 }
6495 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006496 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006498#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006499 return result;
6500}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006501#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006502
Larry Hastings2f936352014-08-05 14:04:04 +10006503
Guido van Rossumad0ee831995-03-01 10:34:45 +00006504#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006505/*[clinic input]
6506os.getuid
6507
6508Return the current process's user id.
6509[clinic start generated code]*/
6510
Larry Hastings2f936352014-08-05 14:04:04 +10006511static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006512os_getuid_impl(PyObject *module)
6513/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006514{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006515 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006516}
Larry Hastings2f936352014-08-05 14:04:04 +10006517#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006519
Brian Curtineb24d742010-04-12 17:16:38 +00006520#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006521#define HAVE_KILL
6522#endif /* MS_WINDOWS */
6523
6524#ifdef HAVE_KILL
6525/*[clinic input]
6526os.kill
6527
6528 pid: pid_t
6529 signal: Py_ssize_t
6530 /
6531
6532Kill a process with a signal.
6533[clinic start generated code]*/
6534
Larry Hastings2f936352014-08-05 14:04:04 +10006535static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006536os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6537/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006538#ifndef MS_WINDOWS
6539{
6540 if (kill(pid, (int)signal) == -1)
6541 return posix_error();
6542 Py_RETURN_NONE;
6543}
6544#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006545{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006546 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006547 DWORD sig = (DWORD)signal;
6548 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006550
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 /* Console processes which share a common console can be sent CTRL+C or
6552 CTRL+BREAK events, provided they handle said events. */
6553 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006554 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 err = GetLastError();
6556 PyErr_SetFromWindowsErr(err);
6557 }
6558 else
6559 Py_RETURN_NONE;
6560 }
Brian Curtineb24d742010-04-12 17:16:38 +00006561
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6563 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006564 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 if (handle == NULL) {
6566 err = GetLastError();
6567 return PyErr_SetFromWindowsErr(err);
6568 }
Brian Curtineb24d742010-04-12 17:16:38 +00006569
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 if (TerminateProcess(handle, sig) == 0) {
6571 err = GetLastError();
6572 result = PyErr_SetFromWindowsErr(err);
6573 } else {
6574 Py_INCREF(Py_None);
6575 result = Py_None;
6576 }
Brian Curtineb24d742010-04-12 17:16:38 +00006577
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 CloseHandle(handle);
6579 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006580}
Larry Hastings2f936352014-08-05 14:04:04 +10006581#endif /* !MS_WINDOWS */
6582#endif /* HAVE_KILL */
6583
6584
6585#ifdef HAVE_KILLPG
6586/*[clinic input]
6587os.killpg
6588
6589 pgid: pid_t
6590 signal: int
6591 /
6592
6593Kill a process group with a signal.
6594[clinic start generated code]*/
6595
Larry Hastings2f936352014-08-05 14:04:04 +10006596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006597os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6598/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006599{
6600 /* XXX some man pages make the `pgid` parameter an int, others
6601 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6602 take the same type. Moreover, pid_t is always at least as wide as
6603 int (else compilation of this module fails), which is safe. */
6604 if (killpg(pgid, signal) == -1)
6605 return posix_error();
6606 Py_RETURN_NONE;
6607}
6608#endif /* HAVE_KILLPG */
6609
Brian Curtineb24d742010-04-12 17:16:38 +00006610
Guido van Rossumc0125471996-06-28 18:55:32 +00006611#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006612#ifdef HAVE_SYS_LOCK_H
6613#include <sys/lock.h>
6614#endif
6615
Larry Hastings2f936352014-08-05 14:04:04 +10006616/*[clinic input]
6617os.plock
6618 op: int
6619 /
6620
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006622[clinic start generated code]*/
6623
Larry Hastings2f936352014-08-05 14:04:04 +10006624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006625os_plock_impl(PyObject *module, int op)
6626/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006627{
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 if (plock(op) == -1)
6629 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006630 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006631}
Larry Hastings2f936352014-08-05 14:04:04 +10006632#endif /* HAVE_PLOCK */
6633
Guido van Rossumc0125471996-06-28 18:55:32 +00006634
Guido van Rossumb6775db1994-08-01 11:34:53 +00006635#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006636/*[clinic input]
6637os.setuid
6638
6639 uid: uid_t
6640 /
6641
6642Set the current process's user id.
6643[clinic start generated code]*/
6644
Larry Hastings2f936352014-08-05 14:04:04 +10006645static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006646os_setuid_impl(PyObject *module, uid_t uid)
6647/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006648{
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 if (setuid(uid) < 0)
6650 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006651 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006652}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006653#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006654
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006655
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006656#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006657/*[clinic input]
6658os.seteuid
6659
6660 euid: uid_t
6661 /
6662
6663Set the current process's effective user id.
6664[clinic start generated code]*/
6665
Larry Hastings2f936352014-08-05 14:04:04 +10006666static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006667os_seteuid_impl(PyObject *module, uid_t euid)
6668/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006669{
6670 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006672 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006673}
6674#endif /* HAVE_SETEUID */
6675
Larry Hastings2f936352014-08-05 14:04:04 +10006676
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006677#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006678/*[clinic input]
6679os.setegid
6680
6681 egid: gid_t
6682 /
6683
6684Set the current process's effective group id.
6685[clinic start generated code]*/
6686
Larry Hastings2f936352014-08-05 14:04:04 +10006687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006688os_setegid_impl(PyObject *module, gid_t egid)
6689/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006690{
6691 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006693 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006694}
6695#endif /* HAVE_SETEGID */
6696
Larry Hastings2f936352014-08-05 14:04:04 +10006697
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006698#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006699/*[clinic input]
6700os.setreuid
6701
6702 ruid: uid_t
6703 euid: uid_t
6704 /
6705
6706Set the current process's real and effective user ids.
6707[clinic start generated code]*/
6708
Larry Hastings2f936352014-08-05 14:04:04 +10006709static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006710os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6711/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006712{
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 if (setreuid(ruid, euid) < 0) {
6714 return posix_error();
6715 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006716 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006718}
6719#endif /* HAVE_SETREUID */
6720
Larry Hastings2f936352014-08-05 14:04:04 +10006721
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006722#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006723/*[clinic input]
6724os.setregid
6725
6726 rgid: gid_t
6727 egid: gid_t
6728 /
6729
6730Set the current process's real and effective group ids.
6731[clinic start generated code]*/
6732
Larry Hastings2f936352014-08-05 14:04:04 +10006733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006734os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6735/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006736{
6737 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006738 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006739 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006740}
6741#endif /* HAVE_SETREGID */
6742
Larry Hastings2f936352014-08-05 14:04:04 +10006743
Guido van Rossumb6775db1994-08-01 11:34:53 +00006744#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006745/*[clinic input]
6746os.setgid
6747 gid: gid_t
6748 /
6749
6750Set the current process's group id.
6751[clinic start generated code]*/
6752
Larry Hastings2f936352014-08-05 14:04:04 +10006753static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006754os_setgid_impl(PyObject *module, gid_t gid)
6755/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006756{
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 if (setgid(gid) < 0)
6758 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006759 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006760}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006761#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006762
Larry Hastings2f936352014-08-05 14:04:04 +10006763
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006764#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006765/*[clinic input]
6766os.setgroups
6767
6768 groups: object
6769 /
6770
6771Set the groups of the current process to list.
6772[clinic start generated code]*/
6773
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006774static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006775os_setgroups(PyObject *module, PyObject *groups)
6776/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006777{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006778 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006780
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 if (!PySequence_Check(groups)) {
6782 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6783 return NULL;
6784 }
6785 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006786 if (len < 0) {
6787 return NULL;
6788 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 if (len > MAX_GROUPS) {
6790 PyErr_SetString(PyExc_ValueError, "too many groups");
6791 return NULL;
6792 }
6793 for(i = 0; i < len; i++) {
6794 PyObject *elem;
6795 elem = PySequence_GetItem(groups, i);
6796 if (!elem)
6797 return NULL;
6798 if (!PyLong_Check(elem)) {
6799 PyErr_SetString(PyExc_TypeError,
6800 "groups must be integers");
6801 Py_DECREF(elem);
6802 return NULL;
6803 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006804 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 Py_DECREF(elem);
6806 return NULL;
6807 }
6808 }
6809 Py_DECREF(elem);
6810 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006811
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 if (setgroups(len, grouplist) < 0)
6813 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006814 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006815}
6816#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006817
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6819static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006820wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006821{
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 PyObject *result;
6823 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006824 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 if (pid == -1)
6827 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006828
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 if (struct_rusage == NULL) {
6830 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6831 if (m == NULL)
6832 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006833 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 Py_DECREF(m);
6835 if (struct_rusage == NULL)
6836 return NULL;
6837 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006838
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6840 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6841 if (!result)
6842 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843
6844#ifndef doubletime
6845#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6846#endif
6847
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006849 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006851 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6854 SET_INT(result, 2, ru->ru_maxrss);
6855 SET_INT(result, 3, ru->ru_ixrss);
6856 SET_INT(result, 4, ru->ru_idrss);
6857 SET_INT(result, 5, ru->ru_isrss);
6858 SET_INT(result, 6, ru->ru_minflt);
6859 SET_INT(result, 7, ru->ru_majflt);
6860 SET_INT(result, 8, ru->ru_nswap);
6861 SET_INT(result, 9, ru->ru_inblock);
6862 SET_INT(result, 10, ru->ru_oublock);
6863 SET_INT(result, 11, ru->ru_msgsnd);
6864 SET_INT(result, 12, ru->ru_msgrcv);
6865 SET_INT(result, 13, ru->ru_nsignals);
6866 SET_INT(result, 14, ru->ru_nvcsw);
6867 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868#undef SET_INT
6869
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 if (PyErr_Occurred()) {
6871 Py_DECREF(result);
6872 return NULL;
6873 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876}
6877#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6878
Larry Hastings2f936352014-08-05 14:04:04 +10006879
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006881/*[clinic input]
6882os.wait3
6883
6884 options: int
6885Wait for completion of a child process.
6886
6887Returns a tuple of information about the child process:
6888 (pid, status, rusage)
6889[clinic start generated code]*/
6890
Larry Hastings2f936352014-08-05 14:04:04 +10006891static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006892os_wait3_impl(PyObject *module, int options)
6893/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894{
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006897 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 WAIT_TYPE status;
6899 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006901 do {
6902 Py_BEGIN_ALLOW_THREADS
6903 pid = wait3(&status, options, &ru);
6904 Py_END_ALLOW_THREADS
6905 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6906 if (pid < 0)
6907 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006908
Victor Stinner4195b5c2012-02-08 23:03:19 +01006909 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006910}
6911#endif /* HAVE_WAIT3 */
6912
Larry Hastings2f936352014-08-05 14:04:04 +10006913
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006914#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006915/*[clinic input]
6916
6917os.wait4
6918
6919 pid: pid_t
6920 options: int
6921
6922Wait for completion of a specific child process.
6923
6924Returns a tuple of information about the child process:
6925 (pid, status, rusage)
6926[clinic start generated code]*/
6927
Larry Hastings2f936352014-08-05 14:04:04 +10006928static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006929os_wait4_impl(PyObject *module, pid_t pid, int options)
6930/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006931{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006932 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006934 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 WAIT_TYPE status;
6936 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006937
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006938 do {
6939 Py_BEGIN_ALLOW_THREADS
6940 res = wait4(pid, &status, options, &ru);
6941 Py_END_ALLOW_THREADS
6942 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6943 if (res < 0)
6944 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006945
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006947}
6948#endif /* HAVE_WAIT4 */
6949
Larry Hastings2f936352014-08-05 14:04:04 +10006950
Ross Lagerwall7807c352011-03-17 20:20:30 +02006951#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006952/*[clinic input]
6953os.waitid
6954
6955 idtype: idtype_t
6956 Must be one of be P_PID, P_PGID or P_ALL.
6957 id: id_t
6958 The id to wait on.
6959 options: int
6960 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6961 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6962 /
6963
6964Returns the result of waiting for a process or processes.
6965
6966Returns either waitid_result or None if WNOHANG is specified and there are
6967no children in a waitable state.
6968[clinic start generated code]*/
6969
Larry Hastings2f936352014-08-05 14:04:04 +10006970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006971os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6972/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006973{
6974 PyObject *result;
6975 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006976 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006977 siginfo_t si;
6978 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006979
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006980 do {
6981 Py_BEGIN_ALLOW_THREADS
6982 res = waitid(idtype, id, &si, options);
6983 Py_END_ALLOW_THREADS
6984 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6985 if (res < 0)
6986 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006987
6988 if (si.si_pid == 0)
6989 Py_RETURN_NONE;
6990
6991 result = PyStructSequence_New(&WaitidResultType);
6992 if (!result)
6993 return NULL;
6994
6995 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006996 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006997 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6998 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6999 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7000 if (PyErr_Occurred()) {
7001 Py_DECREF(result);
7002 return NULL;
7003 }
7004
7005 return result;
7006}
Larry Hastings2f936352014-08-05 14:04:04 +10007007#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007008
Larry Hastings2f936352014-08-05 14:04:04 +10007009
7010#if defined(HAVE_WAITPID)
7011/*[clinic input]
7012os.waitpid
7013 pid: pid_t
7014 options: int
7015 /
7016
7017Wait for completion of a given child process.
7018
7019Returns a tuple of information regarding the child process:
7020 (pid, status)
7021
7022The options argument is ignored on Windows.
7023[clinic start generated code]*/
7024
Larry Hastings2f936352014-08-05 14:04:04 +10007025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007026os_waitpid_impl(PyObject *module, pid_t pid, int options)
7027/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007028{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007029 pid_t res;
7030 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 WAIT_TYPE status;
7032 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007033
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007034 do {
7035 Py_BEGIN_ALLOW_THREADS
7036 res = waitpid(pid, &status, options);
7037 Py_END_ALLOW_THREADS
7038 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7039 if (res < 0)
7040 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007041
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007042 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007043}
Tim Petersab034fa2002-02-01 11:27:43 +00007044#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007045/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007046/*[clinic input]
7047os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007048 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007049 options: int
7050 /
7051
7052Wait for completion of a given process.
7053
7054Returns a tuple of information regarding the process:
7055 (pid, status << 8)
7056
7057The options argument is ignored on Windows.
7058[clinic start generated code]*/
7059
Larry Hastings2f936352014-08-05 14:04:04 +10007060static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007061os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007062/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007063{
7064 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007065 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007066 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007067
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007068 do {
7069 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007070 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007071 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007072 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007073 Py_END_ALLOW_THREADS
7074 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007075 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007076 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007077
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007079 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007080}
Larry Hastings2f936352014-08-05 14:04:04 +10007081#endif
7082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007083
Guido van Rossumad0ee831995-03-01 10:34:45 +00007084#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007085/*[clinic input]
7086os.wait
7087
7088Wait for completion of a child process.
7089
7090Returns a tuple of information about the child process:
7091 (pid, status)
7092[clinic start generated code]*/
7093
Larry Hastings2f936352014-08-05 14:04:04 +10007094static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007095os_wait_impl(PyObject *module)
7096/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007097{
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007099 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 WAIT_TYPE status;
7101 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007102
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007103 do {
7104 Py_BEGIN_ALLOW_THREADS
7105 pid = wait(&status);
7106 Py_END_ALLOW_THREADS
7107 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7108 if (pid < 0)
7109 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007110
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007112}
Larry Hastings2f936352014-08-05 14:04:04 +10007113#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007115
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7117PyDoc_STRVAR(readlink__doc__,
7118"readlink(path, *, dir_fd=None) -> path\n\n\
7119Return a string representing the path to which the symbolic link points.\n\
7120\n\
7121If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7122 and path should be relative; path will then be relative to that directory.\n\
7123dir_fd may not be implemented on your platform.\n\
7124 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007125#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007126
Guido van Rossumb6775db1994-08-01 11:34:53 +00007127#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007128
Larry Hastings2f936352014-08-05 14:04:04 +10007129/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007130static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007132{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133 path_t path;
7134 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007135 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136 ssize_t length;
7137 PyObject *return_value = NULL;
7138 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007139
Larry Hastings9cf065c2012-06-22 16:30:09 -07007140 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007141 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007142 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7143 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007144 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007146
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148#ifdef HAVE_READLINKAT
7149 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007150 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007151 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007153 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154 Py_END_ALLOW_THREADS
7155
7156 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007157 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007158 goto exit;
7159 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007160 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007161
7162 if (PyUnicode_Check(path.object))
7163 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7164 else
7165 return_value = PyBytes_FromStringAndSize(buffer, length);
7166exit:
7167 path_cleanup(&path);
7168 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007169}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170
Guido van Rossumb6775db1994-08-01 11:34:53 +00007171#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007172
Larry Hastings2f936352014-08-05 14:04:04 +10007173#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7174
7175static PyObject *
7176win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7177{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007178 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007179 DWORD n_bytes_returned;
7180 DWORD io_result;
7181 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007182 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007183 HANDLE reparse_point_handle;
7184
Martin Panter70214ad2016-08-04 02:38:59 +00007185 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7186 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007187 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007188
7189 static char *keywords[] = {"path", "dir_fd", NULL};
7190
7191 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7192 &po,
7193 dir_fd_unavailable, &dir_fd
7194 ))
7195 return NULL;
7196
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007197 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007198 if (path == NULL)
7199 return NULL;
7200
7201 /* First get a handle to the reparse point */
7202 Py_BEGIN_ALLOW_THREADS
7203 reparse_point_handle = CreateFileW(
7204 path,
7205 0,
7206 0,
7207 0,
7208 OPEN_EXISTING,
7209 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7210 0);
7211 Py_END_ALLOW_THREADS
7212
7213 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7214 return win32_error_object("readlink", po);
7215
7216 Py_BEGIN_ALLOW_THREADS
7217 /* New call DeviceIoControl to read the reparse point */
7218 io_result = DeviceIoControl(
7219 reparse_point_handle,
7220 FSCTL_GET_REPARSE_POINT,
7221 0, 0, /* in buffer */
7222 target_buffer, sizeof(target_buffer),
7223 &n_bytes_returned,
7224 0 /* we're not using OVERLAPPED_IO */
7225 );
7226 CloseHandle(reparse_point_handle);
7227 Py_END_ALLOW_THREADS
7228
7229 if (io_result==0)
7230 return win32_error_object("readlink", po);
7231
7232 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7233 {
7234 PyErr_SetString(PyExc_ValueError,
7235 "not a symbolic link");
7236 return NULL;
7237 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007238 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7239 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007240
7241 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007242 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007243 return result;
7244}
7245
7246#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7247
7248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007249
Larry Hastings9cf065c2012-06-22 16:30:09 -07007250#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007251
7252#if defined(MS_WINDOWS)
7253
7254/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007255static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007256
Larry Hastings9cf065c2012-06-22 16:30:09 -07007257static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007258check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007259{
7260 HINSTANCE hKernel32;
7261 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007262 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007263 return 1;
7264 hKernel32 = GetModuleHandleW(L"KERNEL32");
7265 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7266 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007267 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007268}
7269
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007270/* Remove the last portion of the path - return 0 on success */
7271static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007272_dirnameW(WCHAR *path)
7273{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007274 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007275 size_t length = wcsnlen_s(path, MAX_PATH);
7276 if (length == MAX_PATH) {
7277 return -1;
7278 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007279
7280 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007281 for(ptr = path + length; ptr != path; ptr--) {
7282 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007283 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007284 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007285 }
7286 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007287 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007288}
7289
Victor Stinner31b3b922013-06-05 01:49:17 +02007290/* Is this path absolute? */
7291static int
7292_is_absW(const WCHAR *path)
7293{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007294 return path[0] == L'\\' || path[0] == L'/' ||
7295 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007296}
7297
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007298/* join root and rest with a backslash - return 0 on success */
7299static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007300_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7301{
Victor Stinner31b3b922013-06-05 01:49:17 +02007302 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007303 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007304 }
7305
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007306 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7307 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007309
7310 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7311 return -1;
7312 }
7313
7314 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007315}
7316
Victor Stinner31b3b922013-06-05 01:49:17 +02007317/* Return True if the path at src relative to dest is a directory */
7318static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007319_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007321 WIN32_FILE_ATTRIBUTE_DATA src_info;
7322 WCHAR dest_parent[MAX_PATH];
7323 WCHAR src_resolved[MAX_PATH] = L"";
7324
7325 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007326 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7327 _dirnameW(dest_parent)) {
7328 return 0;
7329 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007330 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007331 if (_joinW(src_resolved, dest_parent, src)) {
7332 return 0;
7333 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007334 return (
7335 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7336 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7337 );
7338}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007339#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007340
Larry Hastings2f936352014-08-05 14:04:04 +10007341
7342/*[clinic input]
7343os.symlink
7344 src: path_t
7345 dst: path_t
7346 target_is_directory: bool = False
7347 *
7348 dir_fd: dir_fd(requires='symlinkat')=None
7349
7350# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7351
7352Create a symbolic link pointing to src named dst.
7353
7354target_is_directory is required on Windows if the target is to be
7355 interpreted as a directory. (On Windows, symlink requires
7356 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7357 target_is_directory is ignored on non-Windows platforms.
7358
7359If dir_fd is not None, it should be a file descriptor open to a directory,
7360 and path should be relative; path will then be relative to that directory.
7361dir_fd may not be implemented on your platform.
7362 If it is unavailable, using it will raise a NotImplementedError.
7363
7364[clinic start generated code]*/
7365
Larry Hastings2f936352014-08-05 14:04:04 +10007366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007367os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007368 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007369/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007370{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007371#ifdef MS_WINDOWS
7372 DWORD result;
7373#else
7374 int result;
7375#endif
7376
Larry Hastings9cf065c2012-06-22 16:30:09 -07007377#ifdef MS_WINDOWS
7378 if (!check_CreateSymbolicLink()) {
7379 PyErr_SetString(PyExc_NotImplementedError,
7380 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007381 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007382 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383 if (!win32_can_symlink) {
7384 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007385 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007386 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007387#endif
7388
Larry Hastings9cf065c2012-06-22 16:30:09 -07007389#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007390
Larry Hastings9cf065c2012-06-22 16:30:09 -07007391 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007392 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007393 /* if src is a directory, ensure target_is_directory==1 */
7394 target_is_directory |= _check_dirW(src->wide, dst->wide);
7395 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7396 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007397 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007398 Py_END_ALLOW_THREADS
7399
Larry Hastings2f936352014-08-05 14:04:04 +10007400 if (!result)
7401 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402
7403#else
7404
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007405 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7406 PyErr_SetString(PyExc_ValueError,
7407 "symlink: src and dst must be the same type");
7408 return NULL;
7409 }
7410
Larry Hastings9cf065c2012-06-22 16:30:09 -07007411 Py_BEGIN_ALLOW_THREADS
7412#if HAVE_SYMLINKAT
7413 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007414 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007415 else
7416#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007417 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007418 Py_END_ALLOW_THREADS
7419
Larry Hastings2f936352014-08-05 14:04:04 +10007420 if (result)
7421 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007422#endif
7423
Larry Hastings2f936352014-08-05 14:04:04 +10007424 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007425}
7426#endif /* HAVE_SYMLINK */
7427
Larry Hastings9cf065c2012-06-22 16:30:09 -07007428
Brian Curtind40e6f72010-07-08 21:39:08 +00007429
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007430
Larry Hastings605a62d2012-06-24 04:33:36 -07007431static PyStructSequence_Field times_result_fields[] = {
7432 {"user", "user time"},
7433 {"system", "system time"},
7434 {"children_user", "user time of children"},
7435 {"children_system", "system time of children"},
7436 {"elapsed", "elapsed time since an arbitrary point in the past"},
7437 {NULL}
7438};
7439
7440PyDoc_STRVAR(times_result__doc__,
7441"times_result: Result from os.times().\n\n\
7442This object may be accessed either as a tuple of\n\
7443 (user, system, children_user, children_system, elapsed),\n\
7444or via the attributes user, system, children_user, children_system,\n\
7445and elapsed.\n\
7446\n\
7447See os.times for more information.");
7448
7449static PyStructSequence_Desc times_result_desc = {
7450 "times_result", /* name */
7451 times_result__doc__, /* doc */
7452 times_result_fields,
7453 5
7454};
7455
7456static PyTypeObject TimesResultType;
7457
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007458#ifdef MS_WINDOWS
7459#define HAVE_TIMES /* mandatory, for the method table */
7460#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007461
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007462#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007463
7464static PyObject *
7465build_times_result(double user, double system,
7466 double children_user, double children_system,
7467 double elapsed)
7468{
7469 PyObject *value = PyStructSequence_New(&TimesResultType);
7470 if (value == NULL)
7471 return NULL;
7472
7473#define SET(i, field) \
7474 { \
7475 PyObject *o = PyFloat_FromDouble(field); \
7476 if (!o) { \
7477 Py_DECREF(value); \
7478 return NULL; \
7479 } \
7480 PyStructSequence_SET_ITEM(value, i, o); \
7481 } \
7482
7483 SET(0, user);
7484 SET(1, system);
7485 SET(2, children_user);
7486 SET(3, children_system);
7487 SET(4, elapsed);
7488
7489#undef SET
7490
7491 return value;
7492}
7493
Larry Hastings605a62d2012-06-24 04:33:36 -07007494
Larry Hastings2f936352014-08-05 14:04:04 +10007495#ifndef MS_WINDOWS
7496#define NEED_TICKS_PER_SECOND
7497static long ticks_per_second = -1;
7498#endif /* MS_WINDOWS */
7499
7500/*[clinic input]
7501os.times
7502
7503Return a collection containing process timing information.
7504
7505The object returned behaves like a named tuple with these fields:
7506 (utime, stime, cutime, cstime, elapsed_time)
7507All fields are floating point numbers.
7508[clinic start generated code]*/
7509
Larry Hastings2f936352014-08-05 14:04:04 +10007510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007511os_times_impl(PyObject *module)
7512/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007513#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007514{
Victor Stinner8c62be82010-05-06 00:08:46 +00007515 FILETIME create, exit, kernel, user;
7516 HANDLE hProc;
7517 hProc = GetCurrentProcess();
7518 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7519 /* The fields of a FILETIME structure are the hi and lo part
7520 of a 64-bit value expressed in 100 nanosecond units.
7521 1e7 is one second in such units; 1e-7 the inverse.
7522 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7523 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007524 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 (double)(user.dwHighDateTime*429.4967296 +
7526 user.dwLowDateTime*1e-7),
7527 (double)(kernel.dwHighDateTime*429.4967296 +
7528 kernel.dwLowDateTime*1e-7),
7529 (double)0,
7530 (double)0,
7531 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007532}
Larry Hastings2f936352014-08-05 14:04:04 +10007533#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007534{
Larry Hastings2f936352014-08-05 14:04:04 +10007535
7536
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007537 struct tms t;
7538 clock_t c;
7539 errno = 0;
7540 c = times(&t);
7541 if (c == (clock_t) -1)
7542 return posix_error();
7543 return build_times_result(
7544 (double)t.tms_utime / ticks_per_second,
7545 (double)t.tms_stime / ticks_per_second,
7546 (double)t.tms_cutime / ticks_per_second,
7547 (double)t.tms_cstime / ticks_per_second,
7548 (double)c / ticks_per_second);
7549}
Larry Hastings2f936352014-08-05 14:04:04 +10007550#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007551#endif /* HAVE_TIMES */
7552
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007553
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007554#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007555/*[clinic input]
7556os.getsid
7557
7558 pid: pid_t
7559 /
7560
7561Call the system call getsid(pid) and return the result.
7562[clinic start generated code]*/
7563
Larry Hastings2f936352014-08-05 14:04:04 +10007564static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007565os_getsid_impl(PyObject *module, pid_t pid)
7566/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007567{
Victor Stinner8c62be82010-05-06 00:08:46 +00007568 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 sid = getsid(pid);
7570 if (sid < 0)
7571 return posix_error();
7572 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007573}
7574#endif /* HAVE_GETSID */
7575
7576
Guido van Rossumb6775db1994-08-01 11:34:53 +00007577#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007578/*[clinic input]
7579os.setsid
7580
7581Call the system call setsid().
7582[clinic start generated code]*/
7583
Larry Hastings2f936352014-08-05 14:04:04 +10007584static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007585os_setsid_impl(PyObject *module)
7586/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007587{
Victor Stinner8c62be82010-05-06 00:08:46 +00007588 if (setsid() < 0)
7589 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007590 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007591}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007593
Larry Hastings2f936352014-08-05 14:04:04 +10007594
Guido van Rossumb6775db1994-08-01 11:34:53 +00007595#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007596/*[clinic input]
7597os.setpgid
7598
7599 pid: pid_t
7600 pgrp: pid_t
7601 /
7602
7603Call the system call setpgid(pid, pgrp).
7604[clinic start generated code]*/
7605
Larry Hastings2f936352014-08-05 14:04:04 +10007606static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007607os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7608/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007609{
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 if (setpgid(pid, pgrp) < 0)
7611 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007612 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007613}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007614#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007615
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007616
Guido van Rossumb6775db1994-08-01 11:34:53 +00007617#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007618/*[clinic input]
7619os.tcgetpgrp
7620
7621 fd: int
7622 /
7623
7624Return the process group associated with the terminal specified by fd.
7625[clinic start generated code]*/
7626
Larry Hastings2f936352014-08-05 14:04:04 +10007627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007628os_tcgetpgrp_impl(PyObject *module, int fd)
7629/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007630{
7631 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 if (pgid < 0)
7633 return posix_error();
7634 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007635}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007636#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007638
Guido van Rossumb6775db1994-08-01 11:34:53 +00007639#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007640/*[clinic input]
7641os.tcsetpgrp
7642
7643 fd: int
7644 pgid: pid_t
7645 /
7646
7647Set the process group associated with the terminal specified by fd.
7648[clinic start generated code]*/
7649
Larry Hastings2f936352014-08-05 14:04:04 +10007650static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007651os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7652/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007653{
Victor Stinner8c62be82010-05-06 00:08:46 +00007654 if (tcsetpgrp(fd, pgid) < 0)
7655 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007656 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007657}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007658#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007659
Guido van Rossum687dd131993-05-17 08:34:16 +00007660/* Functions acting on file descriptors */
7661
Victor Stinnerdaf45552013-08-28 00:53:59 +02007662#ifdef O_CLOEXEC
7663extern int _Py_open_cloexec_works;
7664#endif
7665
Larry Hastings2f936352014-08-05 14:04:04 +10007666
7667/*[clinic input]
7668os.open -> int
7669 path: path_t
7670 flags: int
7671 mode: int = 0o777
7672 *
7673 dir_fd: dir_fd(requires='openat') = None
7674
7675# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7676
7677Open a file for low level IO. Returns a file descriptor (integer).
7678
7679If dir_fd is not None, it should be a file descriptor open to a directory,
7680 and path should be relative; path will then be relative to that directory.
7681dir_fd may not be implemented on your platform.
7682 If it is unavailable, using it will raise a NotImplementedError.
7683[clinic start generated code]*/
7684
Larry Hastings2f936352014-08-05 14:04:04 +10007685static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007686os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7687/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007688{
7689 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007690 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007691
Victor Stinnerdaf45552013-08-28 00:53:59 +02007692#ifdef O_CLOEXEC
7693 int *atomic_flag_works = &_Py_open_cloexec_works;
7694#elif !defined(MS_WINDOWS)
7695 int *atomic_flag_works = NULL;
7696#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007697
Victor Stinnerdaf45552013-08-28 00:53:59 +02007698#ifdef MS_WINDOWS
7699 flags |= O_NOINHERIT;
7700#elif defined(O_CLOEXEC)
7701 flags |= O_CLOEXEC;
7702#endif
7703
Steve Dower8fc89802015-04-12 00:26:27 -04007704 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007705 do {
7706 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007707#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007708 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007709#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007710#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007711 if (dir_fd != DEFAULT_DIR_FD)
7712 fd = openat(dir_fd, path->narrow, flags, mode);
7713 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007714#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007715 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007716#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007717 Py_END_ALLOW_THREADS
7718 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007719 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007720
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007721 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007722 if (!async_err)
7723 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007724 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007725 }
7726
Victor Stinnerdaf45552013-08-28 00:53:59 +02007727#ifndef MS_WINDOWS
7728 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7729 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007730 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007731 }
7732#endif
7733
Larry Hastings2f936352014-08-05 14:04:04 +10007734 return fd;
7735}
7736
7737
7738/*[clinic input]
7739os.close
7740
7741 fd: int
7742
7743Close a file descriptor.
7744[clinic start generated code]*/
7745
Barry Warsaw53699e91996-12-10 23:23:01 +00007746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007747os_close_impl(PyObject *module, int fd)
7748/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007749{
Larry Hastings2f936352014-08-05 14:04:04 +10007750 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007751 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7752 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7753 * for more details.
7754 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007756 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007758 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 Py_END_ALLOW_THREADS
7760 if (res < 0)
7761 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007762 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007763}
7764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007765
Larry Hastings2f936352014-08-05 14:04:04 +10007766/*[clinic input]
7767os.closerange
7768
7769 fd_low: int
7770 fd_high: int
7771 /
7772
7773Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7774[clinic start generated code]*/
7775
Larry Hastings2f936352014-08-05 14:04:04 +10007776static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007777os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7778/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007779{
7780 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007782 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007783 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007784 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007785 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 Py_END_ALLOW_THREADS
7787 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007788}
7789
7790
Larry Hastings2f936352014-08-05 14:04:04 +10007791/*[clinic input]
7792os.dup -> int
7793
7794 fd: int
7795 /
7796
7797Return a duplicate of a file descriptor.
7798[clinic start generated code]*/
7799
Larry Hastings2f936352014-08-05 14:04:04 +10007800static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007801os_dup_impl(PyObject *module, int fd)
7802/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007803{
7804 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007805}
7806
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007807
Larry Hastings2f936352014-08-05 14:04:04 +10007808/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007809os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007810 fd: int
7811 fd2: int
7812 inheritable: bool=True
7813
7814Duplicate file descriptor.
7815[clinic start generated code]*/
7816
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007817static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007818os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007819/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007820{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007821 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007822#if defined(HAVE_DUP3) && \
7823 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7824 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007825 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007826#endif
7827
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007828 if (fd < 0 || fd2 < 0) {
7829 posix_error();
7830 return -1;
7831 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007832
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007833 /* dup2() can fail with EINTR if the target FD is already open, because it
7834 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7835 * upon close(), and therefore below.
7836 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007837#ifdef MS_WINDOWS
7838 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007839 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007841 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007842 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007843 if (res < 0) {
7844 posix_error();
7845 return -1;
7846 }
7847 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007848
7849 /* Character files like console cannot be make non-inheritable */
7850 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7851 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007852 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007853 }
7854
7855#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7856 Py_BEGIN_ALLOW_THREADS
7857 if (!inheritable)
7858 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7859 else
7860 res = dup2(fd, fd2);
7861 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007862 if (res < 0) {
7863 posix_error();
7864 return -1;
7865 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007866
7867#else
7868
7869#ifdef HAVE_DUP3
7870 if (!inheritable && dup3_works != 0) {
7871 Py_BEGIN_ALLOW_THREADS
7872 res = dup3(fd, fd2, O_CLOEXEC);
7873 Py_END_ALLOW_THREADS
7874 if (res < 0) {
7875 if (dup3_works == -1)
7876 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007877 if (dup3_works) {
7878 posix_error();
7879 return -1;
7880 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007881 }
7882 }
7883
7884 if (inheritable || dup3_works == 0)
7885 {
7886#endif
7887 Py_BEGIN_ALLOW_THREADS
7888 res = dup2(fd, fd2);
7889 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007890 if (res < 0) {
7891 posix_error();
7892 return -1;
7893 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007894
7895 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7896 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007897 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007898 }
7899#ifdef HAVE_DUP3
7900 }
7901#endif
7902
7903#endif
7904
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007905 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007906}
7907
Larry Hastings2f936352014-08-05 14:04:04 +10007908
Ross Lagerwall7807c352011-03-17 20:20:30 +02007909#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007910/*[clinic input]
7911os.lockf
7912
7913 fd: int
7914 An open file descriptor.
7915 command: int
7916 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7917 length: Py_off_t
7918 The number of bytes to lock, starting at the current position.
7919 /
7920
7921Apply, test or remove a POSIX lock on an open file descriptor.
7922
7923[clinic start generated code]*/
7924
Larry Hastings2f936352014-08-05 14:04:04 +10007925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007926os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7927/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007928{
7929 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007930
7931 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007932 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007933 Py_END_ALLOW_THREADS
7934
7935 if (res < 0)
7936 return posix_error();
7937
7938 Py_RETURN_NONE;
7939}
Larry Hastings2f936352014-08-05 14:04:04 +10007940#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007942
Larry Hastings2f936352014-08-05 14:04:04 +10007943/*[clinic input]
7944os.lseek -> Py_off_t
7945
7946 fd: int
7947 position: Py_off_t
7948 how: int
7949 /
7950
7951Set the position of a file descriptor. Return the new position.
7952
7953Return the new cursor position in number of bytes
7954relative to the beginning of the file.
7955[clinic start generated code]*/
7956
Larry Hastings2f936352014-08-05 14:04:04 +10007957static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007958os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7959/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007960{
7961 Py_off_t result;
7962
Guido van Rossum687dd131993-05-17 08:34:16 +00007963#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7965 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007966 case 0: how = SEEK_SET; break;
7967 case 1: how = SEEK_CUR; break;
7968 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007970#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007971
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007973 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007974
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007976 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007977#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007978 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007979#else
Larry Hastings2f936352014-08-05 14:04:04 +10007980 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007981#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007982 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007984 if (result < 0)
7985 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007986
Larry Hastings2f936352014-08-05 14:04:04 +10007987 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007988}
7989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007990
Larry Hastings2f936352014-08-05 14:04:04 +10007991/*[clinic input]
7992os.read
7993 fd: int
7994 length: Py_ssize_t
7995 /
7996
7997Read from a file descriptor. Returns a bytes object.
7998[clinic start generated code]*/
7999
Larry Hastings2f936352014-08-05 14:04:04 +10008000static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008001os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8002/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008003{
Victor Stinner8c62be82010-05-06 00:08:46 +00008004 Py_ssize_t n;
8005 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008006
8007 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008008 errno = EINVAL;
8009 return posix_error();
8010 }
Larry Hastings2f936352014-08-05 14:04:04 +10008011
8012#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008013 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008014 if (length > INT_MAX)
8015 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008016#endif
8017
8018 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008019 if (buffer == NULL)
8020 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008021
Victor Stinner66aab0c2015-03-19 22:53:20 +01008022 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8023 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008025 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 }
Larry Hastings2f936352014-08-05 14:04:04 +10008027
8028 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008029 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008030
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008032}
8033
Ross Lagerwall7807c352011-03-17 20:20:30 +02008034#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008035 || defined(__APPLE__))) \
8036 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8037 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8038static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008039iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008040{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008041 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008042
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008043 *iov = PyMem_New(struct iovec, cnt);
8044 if (*iov == NULL) {
8045 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008046 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008047 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008048
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008049 *buf = PyMem_New(Py_buffer, cnt);
8050 if (*buf == NULL) {
8051 PyMem_Del(*iov);
8052 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008053 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054 }
8055
8056 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008057 PyObject *item = PySequence_GetItem(seq, i);
8058 if (item == NULL)
8059 goto fail;
8060 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8061 Py_DECREF(item);
8062 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008064 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008066 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008067 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008068 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008069
8070fail:
8071 PyMem_Del(*iov);
8072 for (j = 0; j < i; j++) {
8073 PyBuffer_Release(&(*buf)[j]);
8074 }
8075 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008076 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077}
8078
8079static void
8080iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8081{
8082 int i;
8083 PyMem_Del(iov);
8084 for (i = 0; i < cnt; i++) {
8085 PyBuffer_Release(&buf[i]);
8086 }
8087 PyMem_Del(buf);
8088}
8089#endif
8090
Larry Hastings2f936352014-08-05 14:04:04 +10008091
Ross Lagerwall7807c352011-03-17 20:20:30 +02008092#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008093/*[clinic input]
8094os.readv -> Py_ssize_t
8095
8096 fd: int
8097 buffers: object
8098 /
8099
8100Read from a file descriptor fd into an iterable of buffers.
8101
8102The buffers should be mutable buffers accepting bytes.
8103readv will transfer data into each buffer until it is full
8104and then move on to the next buffer in the sequence to hold
8105the rest of the data.
8106
8107readv returns the total number of bytes read,
8108which may be less than the total capacity of all the buffers.
8109[clinic start generated code]*/
8110
Larry Hastings2f936352014-08-05 14:04:04 +10008111static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008112os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8113/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008114{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008115 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008116 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008117 struct iovec *iov;
8118 Py_buffer *buf;
8119
Larry Hastings2f936352014-08-05 14:04:04 +10008120 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008121 PyErr_SetString(PyExc_TypeError,
8122 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008123 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008124 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125
Larry Hastings2f936352014-08-05 14:04:04 +10008126 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008127 if (cnt < 0)
8128 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008129
8130 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8131 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008132
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008133 do {
8134 Py_BEGIN_ALLOW_THREADS
8135 n = readv(fd, iov, cnt);
8136 Py_END_ALLOW_THREADS
8137 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008138
8139 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008140 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008141 if (!async_err)
8142 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008143 return -1;
8144 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008145
Larry Hastings2f936352014-08-05 14:04:04 +10008146 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008147}
Larry Hastings2f936352014-08-05 14:04:04 +10008148#endif /* HAVE_READV */
8149
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150
8151#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008152/*[clinic input]
8153# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8154os.pread
8155
8156 fd: int
8157 length: int
8158 offset: Py_off_t
8159 /
8160
8161Read a number of bytes from a file descriptor starting at a particular offset.
8162
8163Read length bytes from file descriptor fd, starting at offset bytes from
8164the beginning of the file. The file offset remains unchanged.
8165[clinic start generated code]*/
8166
Larry Hastings2f936352014-08-05 14:04:04 +10008167static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008168os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8169/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008170{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008172 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008173 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008174
Larry Hastings2f936352014-08-05 14:04:04 +10008175 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008176 errno = EINVAL;
8177 return posix_error();
8178 }
Larry Hastings2f936352014-08-05 14:04:04 +10008179 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008180 if (buffer == NULL)
8181 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008182
8183 do {
8184 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008185 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008186 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008187 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008188 Py_END_ALLOW_THREADS
8189 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8190
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191 if (n < 0) {
8192 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008193 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194 }
Larry Hastings2f936352014-08-05 14:04:04 +10008195 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008196 _PyBytes_Resize(&buffer, n);
8197 return buffer;
8198}
Larry Hastings2f936352014-08-05 14:04:04 +10008199#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008200
Pablo Galindo4defba32018-01-27 16:16:37 +00008201#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8202/*[clinic input]
8203os.preadv -> Py_ssize_t
8204
8205 fd: int
8206 buffers: object
8207 offset: Py_off_t
8208 flags: int = 0
8209 /
8210
8211Reads from a file descriptor into a number of mutable bytes-like objects.
8212
8213Combines the functionality of readv() and pread(). As readv(), it will
8214transfer data into each buffer until it is full and then move on to the next
8215buffer in the sequence to hold the rest of the data. Its fourth argument,
8216specifies the file offset at which the input operation is to be performed. It
8217will return the total number of bytes read (which can be less than the total
8218capacity of all the objects).
8219
8220The flags argument contains a bitwise OR of zero or more of the following flags:
8221
8222- RWF_HIPRI
8223- RWF_NOWAIT
8224
8225Using non-zero flags requires Linux 4.6 or newer.
8226[clinic start generated code]*/
8227
8228static Py_ssize_t
8229os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8230 int flags)
8231/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8232{
8233 Py_ssize_t cnt, n;
8234 int async_err = 0;
8235 struct iovec *iov;
8236 Py_buffer *buf;
8237
8238 if (!PySequence_Check(buffers)) {
8239 PyErr_SetString(PyExc_TypeError,
8240 "preadv2() arg 2 must be a sequence");
8241 return -1;
8242 }
8243
8244 cnt = PySequence_Size(buffers);
8245 if (cnt < 0) {
8246 return -1;
8247 }
8248
8249#ifndef HAVE_PREADV2
8250 if(flags != 0) {
8251 argument_unavailable_error("preadv2", "flags");
8252 return -1;
8253 }
8254#endif
8255
8256 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8257 return -1;
8258 }
8259#ifdef HAVE_PREADV2
8260 do {
8261 Py_BEGIN_ALLOW_THREADS
8262 _Py_BEGIN_SUPPRESS_IPH
8263 n = preadv2(fd, iov, cnt, offset, flags);
8264 _Py_END_SUPPRESS_IPH
8265 Py_END_ALLOW_THREADS
8266 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8267#else
8268 do {
8269 Py_BEGIN_ALLOW_THREADS
8270 _Py_BEGIN_SUPPRESS_IPH
8271 n = preadv(fd, iov, cnt, offset);
8272 _Py_END_SUPPRESS_IPH
8273 Py_END_ALLOW_THREADS
8274 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8275#endif
8276
8277 iov_cleanup(iov, buf, cnt);
8278 if (n < 0) {
8279 if (!async_err) {
8280 posix_error();
8281 }
8282 return -1;
8283 }
8284
8285 return n;
8286}
8287#endif /* HAVE_PREADV */
8288
Larry Hastings2f936352014-08-05 14:04:04 +10008289
8290/*[clinic input]
8291os.write -> Py_ssize_t
8292
8293 fd: int
8294 data: Py_buffer
8295 /
8296
8297Write a bytes object to a file descriptor.
8298[clinic start generated code]*/
8299
Larry Hastings2f936352014-08-05 14:04:04 +10008300static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008301os_write_impl(PyObject *module, int fd, Py_buffer *data)
8302/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008303{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008304 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008305}
8306
8307#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008309"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008310sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008312Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008313
Larry Hastings2f936352014-08-05 14:04:04 +10008314/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008315static PyObject *
8316posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8317{
8318 int in, out;
8319 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008320 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321 off_t offset;
8322
8323#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8324#ifndef __APPLE__
8325 Py_ssize_t len;
8326#endif
8327 PyObject *headers = NULL, *trailers = NULL;
8328 Py_buffer *hbuf, *tbuf;
8329 off_t sbytes;
8330 struct sf_hdtr sf;
8331 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008332 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008333 static char *keywords[] = {"out", "in",
8334 "offset", "count",
8335 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008336
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008337 sf.headers = NULL;
8338 sf.trailers = NULL;
8339
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008340#ifdef __APPLE__
8341 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008342 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008343#else
8344 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008345 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008346#endif
8347 &headers, &trailers, &flags))
8348 return NULL;
8349 if (headers != NULL) {
8350 if (!PySequence_Check(headers)) {
8351 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008352 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008353 return NULL;
8354 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008355 Py_ssize_t i = PySequence_Size(headers);
8356 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008357 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008358 if (i > INT_MAX) {
8359 PyErr_SetString(PyExc_OverflowError,
8360 "sendfile() header is too large");
8361 return NULL;
8362 }
8363 if (i > 0) {
8364 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008365 if (iov_setup(&(sf.headers), &hbuf,
8366 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008367 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008368#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008369 for (i = 0; i < sf.hdr_cnt; i++) {
8370 Py_ssize_t blen = sf.headers[i].iov_len;
8371# define OFF_T_MAX 0x7fffffffffffffff
8372 if (sbytes >= OFF_T_MAX - blen) {
8373 PyErr_SetString(PyExc_OverflowError,
8374 "sendfile() header is too large");
8375 return NULL;
8376 }
8377 sbytes += blen;
8378 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008379#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008380 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008381 }
8382 }
8383 if (trailers != NULL) {
8384 if (!PySequence_Check(trailers)) {
8385 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008386 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008387 return NULL;
8388 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008389 Py_ssize_t i = PySequence_Size(trailers);
8390 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008391 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008392 if (i > INT_MAX) {
8393 PyErr_SetString(PyExc_OverflowError,
8394 "sendfile() trailer is too large");
8395 return NULL;
8396 }
8397 if (i > 0) {
8398 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008399 if (iov_setup(&(sf.trailers), &tbuf,
8400 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008401 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008402 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008403 }
8404 }
8405
Steve Dower8fc89802015-04-12 00:26:27 -04008406 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008407 do {
8408 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008409#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008410 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008411#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008412 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008413#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008414 Py_END_ALLOW_THREADS
8415 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008416 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008417
8418 if (sf.headers != NULL)
8419 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8420 if (sf.trailers != NULL)
8421 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8422
8423 if (ret < 0) {
8424 if ((errno == EAGAIN) || (errno == EBUSY)) {
8425 if (sbytes != 0) {
8426 // some data has been sent
8427 goto done;
8428 }
8429 else {
8430 // no data has been sent; upper application is supposed
8431 // to retry on EAGAIN or EBUSY
8432 return posix_error();
8433 }
8434 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008435 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008436 }
8437 goto done;
8438
8439done:
8440 #if !defined(HAVE_LARGEFILE_SUPPORT)
8441 return Py_BuildValue("l", sbytes);
8442 #else
8443 return Py_BuildValue("L", sbytes);
8444 #endif
8445
8446#else
8447 Py_ssize_t count;
8448 PyObject *offobj;
8449 static char *keywords[] = {"out", "in",
8450 "offset", "count", NULL};
8451 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8452 keywords, &out, &in, &offobj, &count))
8453 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008454#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008455 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008456 do {
8457 Py_BEGIN_ALLOW_THREADS
8458 ret = sendfile(out, in, NULL, count);
8459 Py_END_ALLOW_THREADS
8460 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008461 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008462 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008463 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008464 }
8465#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008466 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008467 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008468
8469 do {
8470 Py_BEGIN_ALLOW_THREADS
8471 ret = sendfile(out, in, &offset, count);
8472 Py_END_ALLOW_THREADS
8473 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008474 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008475 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008476 return Py_BuildValue("n", ret);
8477#endif
8478}
Larry Hastings2f936352014-08-05 14:04:04 +10008479#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008480
Larry Hastings2f936352014-08-05 14:04:04 +10008481
8482/*[clinic input]
8483os.fstat
8484
8485 fd : int
8486
8487Perform a stat system call on the given file descriptor.
8488
8489Like stat(), but for an open file descriptor.
8490Equivalent to os.stat(fd).
8491[clinic start generated code]*/
8492
Larry Hastings2f936352014-08-05 14:04:04 +10008493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008494os_fstat_impl(PyObject *module, int fd)
8495/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008496{
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 STRUCT_STAT st;
8498 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008499 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008500
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008501 do {
8502 Py_BEGIN_ALLOW_THREADS
8503 res = FSTAT(fd, &st);
8504 Py_END_ALLOW_THREADS
8505 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008506 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008507#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008508 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008509#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008510 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008511#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008512 }
Tim Peters5aa91602002-01-30 05:46:57 +00008513
Victor Stinner4195b5c2012-02-08 23:03:19 +01008514 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008515}
8516
Larry Hastings2f936352014-08-05 14:04:04 +10008517
8518/*[clinic input]
8519os.isatty -> bool
8520 fd: int
8521 /
8522
8523Return True if the fd is connected to a terminal.
8524
8525Return True if the file descriptor is an open file descriptor
8526connected to the slave end of a terminal.
8527[clinic start generated code]*/
8528
Larry Hastings2f936352014-08-05 14:04:04 +10008529static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008530os_isatty_impl(PyObject *module, int fd)
8531/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008532{
Steve Dower8fc89802015-04-12 00:26:27 -04008533 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008534 _Py_BEGIN_SUPPRESS_IPH
8535 return_value = isatty(fd);
8536 _Py_END_SUPPRESS_IPH
8537 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008538}
8539
8540
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008541#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008542/*[clinic input]
8543os.pipe
8544
8545Create a pipe.
8546
8547Returns a tuple of two file descriptors:
8548 (read_fd, write_fd)
8549[clinic start generated code]*/
8550
Larry Hastings2f936352014-08-05 14:04:04 +10008551static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008552os_pipe_impl(PyObject *module)
8553/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008554{
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008556#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008557 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008558 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008559 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008560#else
8561 int res;
8562#endif
8563
8564#ifdef MS_WINDOWS
8565 attr.nLength = sizeof(attr);
8566 attr.lpSecurityDescriptor = NULL;
8567 attr.bInheritHandle = FALSE;
8568
8569 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008570 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008571 ok = CreatePipe(&read, &write, &attr, 0);
8572 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008573 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8574 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008575 if (fds[0] == -1 || fds[1] == -1) {
8576 CloseHandle(read);
8577 CloseHandle(write);
8578 ok = 0;
8579 }
8580 }
Steve Dowerc3630612016-11-19 18:41:16 -08008581 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008582 Py_END_ALLOW_THREADS
8583
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008585 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008586#else
8587
8588#ifdef HAVE_PIPE2
8589 Py_BEGIN_ALLOW_THREADS
8590 res = pipe2(fds, O_CLOEXEC);
8591 Py_END_ALLOW_THREADS
8592
8593 if (res != 0 && errno == ENOSYS)
8594 {
8595#endif
8596 Py_BEGIN_ALLOW_THREADS
8597 res = pipe(fds);
8598 Py_END_ALLOW_THREADS
8599
8600 if (res == 0) {
8601 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8602 close(fds[0]);
8603 close(fds[1]);
8604 return NULL;
8605 }
8606 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8607 close(fds[0]);
8608 close(fds[1]);
8609 return NULL;
8610 }
8611 }
8612#ifdef HAVE_PIPE2
8613 }
8614#endif
8615
8616 if (res != 0)
8617 return PyErr_SetFromErrno(PyExc_OSError);
8618#endif /* !MS_WINDOWS */
8619 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008620}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008621#endif /* HAVE_PIPE */
8622
Larry Hastings2f936352014-08-05 14:04:04 +10008623
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008624#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008625/*[clinic input]
8626os.pipe2
8627
8628 flags: int
8629 /
8630
8631Create a pipe with flags set atomically.
8632
8633Returns a tuple of two file descriptors:
8634 (read_fd, write_fd)
8635
8636flags can be constructed by ORing together one or more of these values:
8637O_NONBLOCK, O_CLOEXEC.
8638[clinic start generated code]*/
8639
Larry Hastings2f936352014-08-05 14:04:04 +10008640static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008641os_pipe2_impl(PyObject *module, int flags)
8642/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008643{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008644 int fds[2];
8645 int res;
8646
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008647 res = pipe2(fds, flags);
8648 if (res != 0)
8649 return posix_error();
8650 return Py_BuildValue("(ii)", fds[0], fds[1]);
8651}
8652#endif /* HAVE_PIPE2 */
8653
Larry Hastings2f936352014-08-05 14:04:04 +10008654
Ross Lagerwall7807c352011-03-17 20:20:30 +02008655#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008656/*[clinic input]
8657os.writev -> Py_ssize_t
8658 fd: int
8659 buffers: object
8660 /
8661
8662Iterate over buffers, and write the contents of each to a file descriptor.
8663
8664Returns the total number of bytes written.
8665buffers must be a sequence of bytes-like objects.
8666[clinic start generated code]*/
8667
Larry Hastings2f936352014-08-05 14:04:04 +10008668static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008669os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8670/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008671{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008672 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008673 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008674 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008675 struct iovec *iov;
8676 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008677
8678 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008679 PyErr_SetString(PyExc_TypeError,
8680 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008681 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008682 }
Larry Hastings2f936352014-08-05 14:04:04 +10008683 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008684 if (cnt < 0)
8685 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008686
Larry Hastings2f936352014-08-05 14:04:04 +10008687 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8688 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008689 }
8690
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008691 do {
8692 Py_BEGIN_ALLOW_THREADS
8693 result = writev(fd, iov, cnt);
8694 Py_END_ALLOW_THREADS
8695 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696
8697 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008698 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008699 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008700
Georg Brandl306336b2012-06-24 12:55:33 +02008701 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008702}
Larry Hastings2f936352014-08-05 14:04:04 +10008703#endif /* HAVE_WRITEV */
8704
8705
8706#ifdef HAVE_PWRITE
8707/*[clinic input]
8708os.pwrite -> Py_ssize_t
8709
8710 fd: int
8711 buffer: Py_buffer
8712 offset: Py_off_t
8713 /
8714
8715Write bytes to a file descriptor starting at a particular offset.
8716
8717Write buffer to fd, starting at offset bytes from the beginning of
8718the file. Returns the number of bytes writte. Does not change the
8719current file offset.
8720[clinic start generated code]*/
8721
Larry Hastings2f936352014-08-05 14:04:04 +10008722static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008723os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8724/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008725{
8726 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008727 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008728
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008729 do {
8730 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008731 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008732 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008733 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008734 Py_END_ALLOW_THREADS
8735 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008736
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008737 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008738 posix_error();
8739 return size;
8740}
8741#endif /* HAVE_PWRITE */
8742
Pablo Galindo4defba32018-01-27 16:16:37 +00008743#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8744/*[clinic input]
8745os.pwritev -> Py_ssize_t
8746
8747 fd: int
8748 buffers: object
8749 offset: Py_off_t
8750 flags: int = 0
8751 /
8752
8753Writes the contents of bytes-like objects to a file descriptor at a given offset.
8754
8755Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8756of bytes-like objects. Buffers are processed in array order. Entire contents of first
8757buffer is written before proceeding to second, and so on. The operating system may
8758set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8759This function writes the contents of each object to the file descriptor and returns
8760the total number of bytes written.
8761
8762The flags argument contains a bitwise OR of zero or more of the following flags:
8763
8764- RWF_DSYNC
8765- RWF_SYNC
8766
8767Using non-zero flags requires Linux 4.7 or newer.
8768[clinic start generated code]*/
8769
8770static Py_ssize_t
8771os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8772 int flags)
8773/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8774{
8775 Py_ssize_t cnt;
8776 Py_ssize_t result;
8777 int async_err = 0;
8778 struct iovec *iov;
8779 Py_buffer *buf;
8780
8781 if (!PySequence_Check(buffers)) {
8782 PyErr_SetString(PyExc_TypeError,
8783 "pwritev() arg 2 must be a sequence");
8784 return -1;
8785 }
8786
8787 cnt = PySequence_Size(buffers);
8788 if (cnt < 0) {
8789 return -1;
8790 }
8791
8792#ifndef HAVE_PWRITEV2
8793 if(flags != 0) {
8794 argument_unavailable_error("pwritev2", "flags");
8795 return -1;
8796 }
8797#endif
8798
8799 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8800 return -1;
8801 }
8802#ifdef HAVE_PWRITEV2
8803 do {
8804 Py_BEGIN_ALLOW_THREADS
8805 _Py_BEGIN_SUPPRESS_IPH
8806 result = pwritev2(fd, iov, cnt, offset, flags);
8807 _Py_END_SUPPRESS_IPH
8808 Py_END_ALLOW_THREADS
8809 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8810#else
8811 do {
8812 Py_BEGIN_ALLOW_THREADS
8813 _Py_BEGIN_SUPPRESS_IPH
8814 result = pwritev(fd, iov, cnt, offset);
8815 _Py_END_SUPPRESS_IPH
8816 Py_END_ALLOW_THREADS
8817 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8818#endif
8819
8820 iov_cleanup(iov, buf, cnt);
8821 if (result < 0) {
8822 if (!async_err) {
8823 posix_error();
8824 }
8825 return -1;
8826 }
8827
8828 return result;
8829}
8830#endif /* HAVE_PWRITEV */
8831
8832
8833
Larry Hastings2f936352014-08-05 14:04:04 +10008834
8835#ifdef HAVE_MKFIFO
8836/*[clinic input]
8837os.mkfifo
8838
8839 path: path_t
8840 mode: int=0o666
8841 *
8842 dir_fd: dir_fd(requires='mkfifoat')=None
8843
8844Create a "fifo" (a POSIX named pipe).
8845
8846If dir_fd is not None, it should be a file descriptor open to a directory,
8847 and path should be relative; path will then be relative to that directory.
8848dir_fd may not be implemented on your platform.
8849 If it is unavailable, using it will raise a NotImplementedError.
8850[clinic start generated code]*/
8851
Larry Hastings2f936352014-08-05 14:04:04 +10008852static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008853os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8854/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008855{
8856 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008857 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008858
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008859 do {
8860 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008861#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008862 if (dir_fd != DEFAULT_DIR_FD)
8863 result = mkfifoat(dir_fd, path->narrow, mode);
8864 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008865#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008866 result = mkfifo(path->narrow, mode);
8867 Py_END_ALLOW_THREADS
8868 } while (result != 0 && errno == EINTR &&
8869 !(async_err = PyErr_CheckSignals()));
8870 if (result != 0)
8871 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008872
8873 Py_RETURN_NONE;
8874}
8875#endif /* HAVE_MKFIFO */
8876
8877
8878#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8879/*[clinic input]
8880os.mknod
8881
8882 path: path_t
8883 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008884 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008885 *
8886 dir_fd: dir_fd(requires='mknodat')=None
8887
8888Create a node in the file system.
8889
8890Create a node in the file system (file, device special file or named pipe)
8891at path. mode specifies both the permissions to use and the
8892type of node to be created, being combined (bitwise OR) with one of
8893S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8894device defines the newly created device special file (probably using
8895os.makedev()). Otherwise device is ignored.
8896
8897If dir_fd is not None, it should be a file descriptor open to a directory,
8898 and path should be relative; path will then be relative to that directory.
8899dir_fd may not be implemented on your platform.
8900 If it is unavailable, using it will raise a NotImplementedError.
8901[clinic start generated code]*/
8902
Larry Hastings2f936352014-08-05 14:04:04 +10008903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008904os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008905 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008906/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008907{
8908 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008909 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008910
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008911 do {
8912 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008913#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008914 if (dir_fd != DEFAULT_DIR_FD)
8915 result = mknodat(dir_fd, path->narrow, mode, device);
8916 else
Larry Hastings2f936352014-08-05 14:04:04 +10008917#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008918 result = mknod(path->narrow, mode, device);
8919 Py_END_ALLOW_THREADS
8920 } while (result != 0 && errno == EINTR &&
8921 !(async_err = PyErr_CheckSignals()));
8922 if (result != 0)
8923 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008924
8925 Py_RETURN_NONE;
8926}
8927#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8928
8929
8930#ifdef HAVE_DEVICE_MACROS
8931/*[clinic input]
8932os.major -> unsigned_int
8933
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008934 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008935 /
8936
8937Extracts a device major number from a raw device number.
8938[clinic start generated code]*/
8939
Larry Hastings2f936352014-08-05 14:04:04 +10008940static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008941os_major_impl(PyObject *module, dev_t device)
8942/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008943{
8944 return major(device);
8945}
8946
8947
8948/*[clinic input]
8949os.minor -> unsigned_int
8950
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008951 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008952 /
8953
8954Extracts a device minor number from a raw device number.
8955[clinic start generated code]*/
8956
Larry Hastings2f936352014-08-05 14:04:04 +10008957static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008958os_minor_impl(PyObject *module, dev_t device)
8959/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008960{
8961 return minor(device);
8962}
8963
8964
8965/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008966os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008967
8968 major: int
8969 minor: int
8970 /
8971
8972Composes a raw device number from the major and minor device numbers.
8973[clinic start generated code]*/
8974
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008975static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008976os_makedev_impl(PyObject *module, int major, int minor)
8977/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008978{
8979 return makedev(major, minor);
8980}
8981#endif /* HAVE_DEVICE_MACROS */
8982
8983
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008984#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008985/*[clinic input]
8986os.ftruncate
8987
8988 fd: int
8989 length: Py_off_t
8990 /
8991
8992Truncate a file, specified by file descriptor, to a specific length.
8993[clinic start generated code]*/
8994
Larry Hastings2f936352014-08-05 14:04:04 +10008995static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008996os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8997/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008998{
8999 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009000 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009001
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009002 do {
9003 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009004 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009005#ifdef MS_WINDOWS
9006 result = _chsize_s(fd, length);
9007#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009008 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009009#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009010 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009011 Py_END_ALLOW_THREADS
9012 } while (result != 0 && errno == EINTR &&
9013 !(async_err = PyErr_CheckSignals()));
9014 if (result != 0)
9015 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009016 Py_RETURN_NONE;
9017}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009018#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009019
9020
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009021#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009022/*[clinic input]
9023os.truncate
9024 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9025 length: Py_off_t
9026
9027Truncate a file, specified by path, to a specific length.
9028
9029On some platforms, path may also be specified as an open file descriptor.
9030 If this functionality is unavailable, using it raises an exception.
9031[clinic start generated code]*/
9032
Larry Hastings2f936352014-08-05 14:04:04 +10009033static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009034os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9035/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009036{
9037 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009038#ifdef MS_WINDOWS
9039 int fd;
9040#endif
9041
9042 if (path->fd != -1)
9043 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009044
9045 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009046 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009047#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009048 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009049 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009050 result = -1;
9051 else {
9052 result = _chsize_s(fd, length);
9053 close(fd);
9054 if (result < 0)
9055 errno = result;
9056 }
9057#else
9058 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009059#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009060 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009061 Py_END_ALLOW_THREADS
9062 if (result < 0)
9063 return path_error(path);
9064
9065 Py_RETURN_NONE;
9066}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009067#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009068
Ross Lagerwall7807c352011-03-17 20:20:30 +02009069
Victor Stinnerd6b17692014-09-30 12:20:05 +02009070/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9071 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9072 defined, which is the case in Python on AIX. AIX bug report:
9073 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9074#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9075# define POSIX_FADVISE_AIX_BUG
9076#endif
9077
Victor Stinnerec39e262014-09-30 12:35:58 +02009078
Victor Stinnerd6b17692014-09-30 12:20:05 +02009079#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009080/*[clinic input]
9081os.posix_fallocate
9082
9083 fd: int
9084 offset: Py_off_t
9085 length: Py_off_t
9086 /
9087
9088Ensure a file has allocated at least a particular number of bytes on disk.
9089
9090Ensure that the file specified by fd encompasses a range of bytes
9091starting at offset bytes from the beginning and continuing for length bytes.
9092[clinic start generated code]*/
9093
Larry Hastings2f936352014-08-05 14:04:04 +10009094static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009095os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009096 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009097/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009098{
9099 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009100 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009101
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009102 do {
9103 Py_BEGIN_ALLOW_THREADS
9104 result = posix_fallocate(fd, offset, length);
9105 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009106 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9107
9108 if (result == 0)
9109 Py_RETURN_NONE;
9110
9111 if (async_err)
9112 return NULL;
9113
9114 errno = result;
9115 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009116}
Victor Stinnerec39e262014-09-30 12:35:58 +02009117#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009118
Ross Lagerwall7807c352011-03-17 20:20:30 +02009119
Victor Stinnerd6b17692014-09-30 12:20:05 +02009120#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009121/*[clinic input]
9122os.posix_fadvise
9123
9124 fd: int
9125 offset: Py_off_t
9126 length: Py_off_t
9127 advice: int
9128 /
9129
9130Announce an intention to access data in a specific pattern.
9131
9132Announce an intention to access data in a specific pattern, thus allowing
9133the kernel to make optimizations.
9134The advice applies to the region of the file specified by fd starting at
9135offset and continuing for length bytes.
9136advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9137POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9138POSIX_FADV_DONTNEED.
9139[clinic start generated code]*/
9140
Larry Hastings2f936352014-08-05 14:04:04 +10009141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009142os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009143 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009144/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009145{
9146 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009147 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009148
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009149 do {
9150 Py_BEGIN_ALLOW_THREADS
9151 result = posix_fadvise(fd, offset, length, advice);
9152 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009153 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9154
9155 if (result == 0)
9156 Py_RETURN_NONE;
9157
9158 if (async_err)
9159 return NULL;
9160
9161 errno = result;
9162 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009163}
Victor Stinnerec39e262014-09-30 12:35:58 +02009164#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009165
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009166#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009167
Fred Drake762e2061999-08-26 17:23:54 +00009168/* Save putenv() parameters as values here, so we can collect them when they
9169 * get re-set with another call for the same key. */
9170static PyObject *posix_putenv_garbage;
9171
Larry Hastings2f936352014-08-05 14:04:04 +10009172static void
9173posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009174{
Larry Hastings2f936352014-08-05 14:04:04 +10009175 /* Install the first arg and newstr in posix_putenv_garbage;
9176 * this will cause previous value to be collected. This has to
9177 * happen after the real putenv() call because the old value
9178 * was still accessible until then. */
9179 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9180 /* really not much we can do; just leak */
9181 PyErr_Clear();
9182 else
9183 Py_DECREF(value);
9184}
9185
9186
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009187#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009188/*[clinic input]
9189os.putenv
9190
9191 name: unicode
9192 value: unicode
9193 /
9194
9195Change or add an environment variable.
9196[clinic start generated code]*/
9197
Larry Hastings2f936352014-08-05 14:04:04 +10009198static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009199os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9200/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009201{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009202 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009203 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009204
Serhiy Storchaka77703942017-06-25 07:33:01 +03009205 /* Search from index 1 because on Windows starting '=' is allowed for
9206 defining hidden environment variables. */
9207 if (PyUnicode_GET_LENGTH(name) == 0 ||
9208 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9209 {
9210 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9211 return NULL;
9212 }
Larry Hastings2f936352014-08-05 14:04:04 +10009213 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9214 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009215 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009216 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009217
9218 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9219 if (env == NULL)
9220 goto error;
9221 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009222 PyErr_Format(PyExc_ValueError,
9223 "the environment variable is longer than %u characters",
9224 _MAX_ENV);
9225 goto error;
9226 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009227 if (wcslen(env) != (size_t)size) {
9228 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009229 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009230 }
9231
Larry Hastings2f936352014-08-05 14:04:04 +10009232 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009234 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009236
Larry Hastings2f936352014-08-05 14:04:04 +10009237 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009238 Py_RETURN_NONE;
9239
9240error:
Larry Hastings2f936352014-08-05 14:04:04 +10009241 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009242 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009243}
Larry Hastings2f936352014-08-05 14:04:04 +10009244#else /* MS_WINDOWS */
9245/*[clinic input]
9246os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009247
Larry Hastings2f936352014-08-05 14:04:04 +10009248 name: FSConverter
9249 value: FSConverter
9250 /
9251
9252Change or add an environment variable.
9253[clinic start generated code]*/
9254
Larry Hastings2f936352014-08-05 14:04:04 +10009255static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009256os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9257/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009258{
9259 PyObject *bytes = NULL;
9260 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009261 const char *name_string = PyBytes_AS_STRING(name);
9262 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009263
Serhiy Storchaka77703942017-06-25 07:33:01 +03009264 if (strchr(name_string, '=') != NULL) {
9265 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9266 return NULL;
9267 }
Larry Hastings2f936352014-08-05 14:04:04 +10009268 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9269 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009270 return NULL;
9271 }
9272
9273 env = PyBytes_AS_STRING(bytes);
9274 if (putenv(env)) {
9275 Py_DECREF(bytes);
9276 return posix_error();
9277 }
9278
9279 posix_putenv_garbage_setitem(name, bytes);
9280 Py_RETURN_NONE;
9281}
9282#endif /* MS_WINDOWS */
9283#endif /* HAVE_PUTENV */
9284
9285
9286#ifdef HAVE_UNSETENV
9287/*[clinic input]
9288os.unsetenv
9289 name: FSConverter
9290 /
9291
9292Delete an environment variable.
9293[clinic start generated code]*/
9294
Larry Hastings2f936352014-08-05 14:04:04 +10009295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009296os_unsetenv_impl(PyObject *module, PyObject *name)
9297/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009298{
Victor Stinner984890f2011-11-24 13:53:38 +01009299#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009300 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009301#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009302
Victor Stinner984890f2011-11-24 13:53:38 +01009303#ifdef HAVE_BROKEN_UNSETENV
9304 unsetenv(PyBytes_AS_STRING(name));
9305#else
Victor Stinner65170952011-11-22 22:16:17 +01009306 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009307 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009308 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009309#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009310
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 /* Remove the key from posix_putenv_garbage;
9312 * this will cause it to be collected. This has to
9313 * happen after the real unsetenv() call because the
9314 * old value was still accessible until then.
9315 */
Victor Stinner65170952011-11-22 22:16:17 +01009316 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 /* really not much we can do; just leak */
9318 PyErr_Clear();
9319 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009320 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009321}
Larry Hastings2f936352014-08-05 14:04:04 +10009322#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009323
Larry Hastings2f936352014-08-05 14:04:04 +10009324
9325/*[clinic input]
9326os.strerror
9327
9328 code: int
9329 /
9330
9331Translate an error code to a message string.
9332[clinic start generated code]*/
9333
Larry Hastings2f936352014-08-05 14:04:04 +10009334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009335os_strerror_impl(PyObject *module, int code)
9336/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009337{
9338 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 if (message == NULL) {
9340 PyErr_SetString(PyExc_ValueError,
9341 "strerror() argument out of range");
9342 return NULL;
9343 }
Victor Stinner1b579672011-12-17 05:47:23 +01009344 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009345}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009346
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009347
Guido van Rossumc9641791998-08-04 15:26:23 +00009348#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009349#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009350/*[clinic input]
9351os.WCOREDUMP -> bool
9352
9353 status: int
9354 /
9355
9356Return True if the process returning status was dumped to a core file.
9357[clinic start generated code]*/
9358
Larry Hastings2f936352014-08-05 14:04:04 +10009359static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009360os_WCOREDUMP_impl(PyObject *module, int status)
9361/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009362{
9363 WAIT_TYPE wait_status;
9364 WAIT_STATUS_INT(wait_status) = status;
9365 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009366}
9367#endif /* WCOREDUMP */
9368
Larry Hastings2f936352014-08-05 14:04:04 +10009369
Fred Drake106c1a02002-04-23 15:58:02 +00009370#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009371/*[clinic input]
9372os.WIFCONTINUED -> bool
9373
9374 status: int
9375
9376Return True if a particular process was continued from a job control stop.
9377
9378Return True if the process returning status was continued from a
9379job control stop.
9380[clinic start generated code]*/
9381
Larry Hastings2f936352014-08-05 14:04:04 +10009382static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009383os_WIFCONTINUED_impl(PyObject *module, int status)
9384/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009385{
9386 WAIT_TYPE wait_status;
9387 WAIT_STATUS_INT(wait_status) = status;
9388 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009389}
9390#endif /* WIFCONTINUED */
9391
Larry Hastings2f936352014-08-05 14:04:04 +10009392
Guido van Rossumc9641791998-08-04 15:26:23 +00009393#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009394/*[clinic input]
9395os.WIFSTOPPED -> bool
9396
9397 status: int
9398
9399Return True if the process returning status was stopped.
9400[clinic start generated code]*/
9401
Larry Hastings2f936352014-08-05 14:04:04 +10009402static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009403os_WIFSTOPPED_impl(PyObject *module, int status)
9404/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009405{
9406 WAIT_TYPE wait_status;
9407 WAIT_STATUS_INT(wait_status) = status;
9408 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009409}
9410#endif /* WIFSTOPPED */
9411
Larry Hastings2f936352014-08-05 14:04:04 +10009412
Guido van Rossumc9641791998-08-04 15:26:23 +00009413#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009414/*[clinic input]
9415os.WIFSIGNALED -> bool
9416
9417 status: int
9418
9419Return True if the process returning status was terminated by a signal.
9420[clinic start generated code]*/
9421
Larry Hastings2f936352014-08-05 14:04:04 +10009422static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009423os_WIFSIGNALED_impl(PyObject *module, int status)
9424/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009425{
9426 WAIT_TYPE wait_status;
9427 WAIT_STATUS_INT(wait_status) = status;
9428 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009429}
9430#endif /* WIFSIGNALED */
9431
Larry Hastings2f936352014-08-05 14:04:04 +10009432
Guido van Rossumc9641791998-08-04 15:26:23 +00009433#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009434/*[clinic input]
9435os.WIFEXITED -> bool
9436
9437 status: int
9438
9439Return True if the process returning status exited via the exit() system call.
9440[clinic start generated code]*/
9441
Larry Hastings2f936352014-08-05 14:04:04 +10009442static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009443os_WIFEXITED_impl(PyObject *module, int status)
9444/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009445{
9446 WAIT_TYPE wait_status;
9447 WAIT_STATUS_INT(wait_status) = status;
9448 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009449}
9450#endif /* WIFEXITED */
9451
Larry Hastings2f936352014-08-05 14:04:04 +10009452
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009453#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009454/*[clinic input]
9455os.WEXITSTATUS -> int
9456
9457 status: int
9458
9459Return the process return code from status.
9460[clinic start generated code]*/
9461
Larry Hastings2f936352014-08-05 14:04:04 +10009462static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009463os_WEXITSTATUS_impl(PyObject *module, int status)
9464/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009465{
9466 WAIT_TYPE wait_status;
9467 WAIT_STATUS_INT(wait_status) = status;
9468 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009469}
9470#endif /* WEXITSTATUS */
9471
Larry Hastings2f936352014-08-05 14:04:04 +10009472
Guido van Rossumc9641791998-08-04 15:26:23 +00009473#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009474/*[clinic input]
9475os.WTERMSIG -> int
9476
9477 status: int
9478
9479Return the signal that terminated the process that provided the status value.
9480[clinic start generated code]*/
9481
Larry Hastings2f936352014-08-05 14:04:04 +10009482static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009483os_WTERMSIG_impl(PyObject *module, int status)
9484/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009485{
9486 WAIT_TYPE wait_status;
9487 WAIT_STATUS_INT(wait_status) = status;
9488 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009489}
9490#endif /* WTERMSIG */
9491
Larry Hastings2f936352014-08-05 14:04:04 +10009492
Guido van Rossumc9641791998-08-04 15:26:23 +00009493#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009494/*[clinic input]
9495os.WSTOPSIG -> int
9496
9497 status: int
9498
9499Return the signal that stopped the process that provided the status value.
9500[clinic start generated code]*/
9501
Larry Hastings2f936352014-08-05 14:04:04 +10009502static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009503os_WSTOPSIG_impl(PyObject *module, int status)
9504/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009505{
9506 WAIT_TYPE wait_status;
9507 WAIT_STATUS_INT(wait_status) = status;
9508 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009509}
9510#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009511#endif /* HAVE_SYS_WAIT_H */
9512
9513
Thomas Wouters477c8d52006-05-27 19:21:47 +00009514#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009515#ifdef _SCO_DS
9516/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9517 needed definitions in sys/statvfs.h */
9518#define _SVID3
9519#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009520#include <sys/statvfs.h>
9521
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009522static PyObject*
9523_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9525 if (v == NULL)
9526 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009527
9528#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9530 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9531 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9532 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9533 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9534 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9535 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9536 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9537 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9538 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009539#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9541 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9542 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009543 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009545 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009547 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009549 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009551 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009553 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9555 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009556#endif
Michael Felt502d5512018-01-05 13:01:58 +01009557/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9558 * (issue #32390). */
9559#if defined(_AIX) && defined(_ALL_SOURCE)
9560 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9561#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009562 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009563#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009564 if (PyErr_Occurred()) {
9565 Py_DECREF(v);
9566 return NULL;
9567 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009568
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009570}
9571
Larry Hastings2f936352014-08-05 14:04:04 +10009572
9573/*[clinic input]
9574os.fstatvfs
9575 fd: int
9576 /
9577
9578Perform an fstatvfs system call on the given fd.
9579
9580Equivalent to statvfs(fd).
9581[clinic start generated code]*/
9582
Larry Hastings2f936352014-08-05 14:04:04 +10009583static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009584os_fstatvfs_impl(PyObject *module, int fd)
9585/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009586{
9587 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009588 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009590
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009591 do {
9592 Py_BEGIN_ALLOW_THREADS
9593 result = fstatvfs(fd, &st);
9594 Py_END_ALLOW_THREADS
9595 } while (result != 0 && errno == EINTR &&
9596 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009597 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009598 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009599
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009601}
Larry Hastings2f936352014-08-05 14:04:04 +10009602#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009603
9604
Thomas Wouters477c8d52006-05-27 19:21:47 +00009605#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009606#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009607/*[clinic input]
9608os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009609
Larry Hastings2f936352014-08-05 14:04:04 +10009610 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9611
9612Perform a statvfs system call on the given path.
9613
9614path may always be specified as a string.
9615On some platforms, path may also be specified as an open file descriptor.
9616 If this functionality is unavailable, using it raises an exception.
9617[clinic start generated code]*/
9618
Larry Hastings2f936352014-08-05 14:04:04 +10009619static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009620os_statvfs_impl(PyObject *module, path_t *path)
9621/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009622{
9623 int result;
9624 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009625
9626 Py_BEGIN_ALLOW_THREADS
9627#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009628 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009629#ifdef __APPLE__
9630 /* handle weak-linking on Mac OS X 10.3 */
9631 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009632 fd_specified("statvfs", path->fd);
9633 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009634 }
9635#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009636 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009637 }
9638 else
9639#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009640 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009641 Py_END_ALLOW_THREADS
9642
9643 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009644 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009645 }
9646
Larry Hastings2f936352014-08-05 14:04:04 +10009647 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009648}
Larry Hastings2f936352014-08-05 14:04:04 +10009649#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9650
Guido van Rossum94f6f721999-01-06 18:42:14 +00009651
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009652#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009653/*[clinic input]
9654os._getdiskusage
9655
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009656 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009657
9658Return disk usage statistics about the given path as a (total, free) tuple.
9659[clinic start generated code]*/
9660
Larry Hastings2f936352014-08-05 14:04:04 +10009661static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009662os__getdiskusage_impl(PyObject *module, path_t *path)
9663/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009664{
9665 BOOL retval;
9666 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009667
9668 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009669 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009670 Py_END_ALLOW_THREADS
9671 if (retval == 0)
9672 return PyErr_SetFromWindowsErr(0);
9673
9674 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9675}
Larry Hastings2f936352014-08-05 14:04:04 +10009676#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009677
9678
Fred Drakec9680921999-12-13 16:37:25 +00009679/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9680 * It maps strings representing configuration variable names to
9681 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009682 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009683 * rarely-used constants. There are three separate tables that use
9684 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009685 *
9686 * This code is always included, even if none of the interfaces that
9687 * need it are included. The #if hackery needed to avoid it would be
9688 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009689 */
9690struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009691 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009692 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009693};
9694
Fred Drake12c6e2d1999-12-14 21:25:03 +00009695static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009696conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009697 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009698{
Christian Heimes217cfd12007-12-02 14:31:20 +00009699 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009700 int value = _PyLong_AsInt(arg);
9701 if (value == -1 && PyErr_Occurred())
9702 return 0;
9703 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009704 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009705 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009706 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009707 /* look up the value in the table using a binary search */
9708 size_t lo = 0;
9709 size_t mid;
9710 size_t hi = tablesize;
9711 int cmp;
9712 const char *confname;
9713 if (!PyUnicode_Check(arg)) {
9714 PyErr_SetString(PyExc_TypeError,
9715 "configuration names must be strings or integers");
9716 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009718 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009719 if (confname == NULL)
9720 return 0;
9721 while (lo < hi) {
9722 mid = (lo + hi) / 2;
9723 cmp = strcmp(confname, table[mid].name);
9724 if (cmp < 0)
9725 hi = mid;
9726 else if (cmp > 0)
9727 lo = mid + 1;
9728 else {
9729 *valuep = table[mid].value;
9730 return 1;
9731 }
9732 }
9733 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9734 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009736}
9737
9738
9739#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9740static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009741#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009743#endif
9744#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009746#endif
Fred Drakec9680921999-12-13 16:37:25 +00009747#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009792#ifdef _PC_ACL_ENABLED
9793 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9794#endif
9795#ifdef _PC_MIN_HOLE_SIZE
9796 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9797#endif
9798#ifdef _PC_ALLOC_SIZE_MIN
9799 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9800#endif
9801#ifdef _PC_REC_INCR_XFER_SIZE
9802 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9803#endif
9804#ifdef _PC_REC_MAX_XFER_SIZE
9805 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9806#endif
9807#ifdef _PC_REC_MIN_XFER_SIZE
9808 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9809#endif
9810#ifdef _PC_REC_XFER_ALIGN
9811 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9812#endif
9813#ifdef _PC_SYMLINK_MAX
9814 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9815#endif
9816#ifdef _PC_XATTR_ENABLED
9817 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9818#endif
9819#ifdef _PC_XATTR_EXISTS
9820 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9821#endif
9822#ifdef _PC_TIMESTAMP_RESOLUTION
9823 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9824#endif
Fred Drakec9680921999-12-13 16:37:25 +00009825};
9826
Fred Drakec9680921999-12-13 16:37:25 +00009827static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009828conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009829{
9830 return conv_confname(arg, valuep, posix_constants_pathconf,
9831 sizeof(posix_constants_pathconf)
9832 / sizeof(struct constdef));
9833}
9834#endif
9835
Larry Hastings2f936352014-08-05 14:04:04 +10009836
Fred Drakec9680921999-12-13 16:37:25 +00009837#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009838/*[clinic input]
9839os.fpathconf -> long
9840
9841 fd: int
9842 name: path_confname
9843 /
9844
9845Return the configuration limit name for the file descriptor fd.
9846
9847If there is no limit, return -1.
9848[clinic start generated code]*/
9849
Larry Hastings2f936352014-08-05 14:04:04 +10009850static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009851os_fpathconf_impl(PyObject *module, int fd, int name)
9852/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009853{
9854 long limit;
9855
9856 errno = 0;
9857 limit = fpathconf(fd, name);
9858 if (limit == -1 && errno != 0)
9859 posix_error();
9860
9861 return limit;
9862}
9863#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009864
9865
9866#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009867/*[clinic input]
9868os.pathconf -> long
9869 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9870 name: path_confname
9871
9872Return the configuration limit name for the file or directory path.
9873
9874If there is no limit, return -1.
9875On some platforms, path may also be specified as an open file descriptor.
9876 If this functionality is unavailable, using it raises an exception.
9877[clinic start generated code]*/
9878
Larry Hastings2f936352014-08-05 14:04:04 +10009879static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009880os_pathconf_impl(PyObject *module, path_t *path, int name)
9881/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009882{
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009884
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009886#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009887 if (path->fd != -1)
9888 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009889 else
9890#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009891 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 if (limit == -1 && errno != 0) {
9893 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009894 /* could be a path or name problem */
9895 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009896 else
Larry Hastings2f936352014-08-05 14:04:04 +10009897 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 }
Larry Hastings2f936352014-08-05 14:04:04 +10009899
9900 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009901}
Larry Hastings2f936352014-08-05 14:04:04 +10009902#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009903
9904#ifdef HAVE_CONFSTR
9905static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009906#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009908#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009909#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009911#endif
9912#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009914#endif
Fred Draked86ed291999-12-15 15:34:33 +00009915#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009917#endif
9918#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009920#endif
9921#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009923#endif
9924#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009926#endif
Fred Drakec9680921999-12-13 16:37:25 +00009927#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
Fred Draked86ed291999-12-15 15:34:33 +00009951#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009953#endif
Fred Drakec9680921999-12-13 16:37:25 +00009954#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
Fred Draked86ed291999-12-15 15:34:33 +00009957#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009959#endif
9960#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009962#endif
9963#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009965#endif
9966#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009968#endif
Fred Drakec9680921999-12-13 16:37:25 +00009969#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
Fred Draked86ed291999-12-15 15:34:33 +000010017#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010019#endif
10020#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010022#endif
10023#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010025#endif
10026#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010028#endif
10029#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010031#endif
10032#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
10035#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010037#endif
10038#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010040#endif
10041#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010043#endif
10044#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010046#endif
10047#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010049#endif
10050#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010052#endif
10053#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010055#endif
Fred Drakec9680921999-12-13 16:37:25 +000010056};
10057
10058static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010059conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010060{
10061 return conv_confname(arg, valuep, posix_constants_confstr,
10062 sizeof(posix_constants_confstr)
10063 / sizeof(struct constdef));
10064}
10065
Larry Hastings2f936352014-08-05 14:04:04 +100010066
10067/*[clinic input]
10068os.confstr
10069
10070 name: confstr_confname
10071 /
10072
10073Return a string-valued system configuration variable.
10074[clinic start generated code]*/
10075
Larry Hastings2f936352014-08-05 14:04:04 +100010076static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010077os_confstr_impl(PyObject *module, int name)
10078/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010079{
10080 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010081 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010082 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010083
Victor Stinnercb043522010-09-10 23:49:04 +000010084 errno = 0;
10085 len = confstr(name, buffer, sizeof(buffer));
10086 if (len == 0) {
10087 if (errno) {
10088 posix_error();
10089 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010090 }
10091 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010092 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010093 }
10094 }
Victor Stinnercb043522010-09-10 23:49:04 +000010095
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010096 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010097 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010098 char *buf = PyMem_Malloc(len);
10099 if (buf == NULL)
10100 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010101 len2 = confstr(name, buf, len);
10102 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010103 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010104 PyMem_Free(buf);
10105 }
10106 else
10107 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010108 return result;
10109}
Larry Hastings2f936352014-08-05 14:04:04 +100010110#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010111
10112
10113#ifdef HAVE_SYSCONF
10114static struct constdef posix_constants_sysconf[] = {
10115#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
Fred Draked86ed291999-12-15 15:34:33 +000010145#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010147#endif
10148#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010150#endif
Fred Drakec9680921999-12-13 16:37:25 +000010151#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
Fred Drakec9680921999-12-13 16:37:25 +000010154#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
Fred Draked86ed291999-12-15 15:34:33 +000010169#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010171#endif
Fred Drakec9680921999-12-13 16:37:25 +000010172#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
Fred Draked86ed291999-12-15 15:34:33 +000010187#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010189#endif
Fred Drakec9680921999-12-13 16:37:25 +000010190#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
Fred Draked86ed291999-12-15 15:34:33 +000010259#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010261#endif
Fred Drakec9680921999-12-13 16:37:25 +000010262#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
Fred Draked86ed291999-12-15 15:34:33 +000010271#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
Fred Drakec9680921999-12-13 16:37:25 +000010274#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
Fred Draked86ed291999-12-15 15:34:33 +000010277#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010279#endif
10280#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010282#endif
Fred Drakec9680921999-12-13 16:37:25 +000010283#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
Fred Draked86ed291999-12-15 15:34:33 +000010295#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010297#endif
Fred Drakec9680921999-12-13 16:37:25 +000010298#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
Fred Draked86ed291999-12-15 15:34:33 +000010319#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010321#endif
Fred Drakec9680921999-12-13 16:37:25 +000010322#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
Fred Draked86ed291999-12-15 15:34:33 +000010328#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010330#endif
Fred Drakec9680921999-12-13 16:37:25 +000010331#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
Fred Draked86ed291999-12-15 15:34:33 +000010358#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010360#endif
10361#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010363#endif
Fred Drakec9680921999-12-13 16:37:25 +000010364#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
10430#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010432#endif
10433#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
10448#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010450#endif
10451#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010453#endif
10454#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010456#endif
10457#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010459#endif
10460#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010462#endif
10463#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010465#endif
10466#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010468#endif
Fred Draked86ed291999-12-15 15:34:33 +000010469#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010471#endif
Fred Drakec9680921999-12-13 16:37:25 +000010472#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010474#endif
10475#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010477#endif
10478#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010480#endif
10481#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010483#endif
10484#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
10511#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010513#endif
10514#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
10517#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010519#endif
10520#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010522#endif
10523#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010525#endif
10526#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010528#endif
10529#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010531#endif
10532#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010534#endif
10535#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010537#endif
10538#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010540#endif
10541#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010543#endif
10544#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010546#endif
10547#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
10577#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010579#endif
10580#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010582#endif
10583#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010585#endif
10586#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010588#endif
10589#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010591#endif
10592#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010594#endif
10595#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010597#endif
10598#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010600#endif
10601#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010603#endif
10604#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010606#endif
10607};
10608
10609static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010610conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010611{
10612 return conv_confname(arg, valuep, posix_constants_sysconf,
10613 sizeof(posix_constants_sysconf)
10614 / sizeof(struct constdef));
10615}
10616
Larry Hastings2f936352014-08-05 14:04:04 +100010617
10618/*[clinic input]
10619os.sysconf -> long
10620 name: sysconf_confname
10621 /
10622
10623Return an integer-valued system configuration variable.
10624[clinic start generated code]*/
10625
Larry Hastings2f936352014-08-05 14:04:04 +100010626static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010627os_sysconf_impl(PyObject *module, int name)
10628/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010629{
10630 long value;
10631
10632 errno = 0;
10633 value = sysconf(name);
10634 if (value == -1 && errno != 0)
10635 posix_error();
10636 return value;
10637}
10638#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010639
10640
Fred Drakebec628d1999-12-15 18:31:10 +000010641/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010642 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010643 * the exported dictionaries that are used to publish information about the
10644 * names available on the host platform.
10645 *
10646 * Sorting the table at runtime ensures that the table is properly ordered
10647 * when used, even for platforms we're not able to test on. It also makes
10648 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010649 */
Fred Drakebec628d1999-12-15 18:31:10 +000010650
10651static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010652cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010653{
10654 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010655 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010656 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010658
10659 return strcmp(c1->name, c2->name);
10660}
10661
10662static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010663setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010664 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010665{
Fred Drakebec628d1999-12-15 18:31:10 +000010666 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010667 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010668
10669 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10670 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010671 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010673
Barry Warsaw3155db32000-04-13 15:20:40 +000010674 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 PyObject *o = PyLong_FromLong(table[i].value);
10676 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10677 Py_XDECREF(o);
10678 Py_DECREF(d);
10679 return -1;
10680 }
10681 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010682 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010683 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010684}
10685
Fred Drakebec628d1999-12-15 18:31:10 +000010686/* Return -1 on failure, 0 on success. */
10687static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010688setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010689{
10690#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010691 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010692 sizeof(posix_constants_pathconf)
10693 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010694 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010695 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010696#endif
10697#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010698 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010699 sizeof(posix_constants_confstr)
10700 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010701 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010702 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010703#endif
10704#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010705 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010706 sizeof(posix_constants_sysconf)
10707 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010708 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010709 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010710#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010711 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010712}
Fred Draked86ed291999-12-15 15:34:33 +000010713
10714
Larry Hastings2f936352014-08-05 14:04:04 +100010715/*[clinic input]
10716os.abort
10717
10718Abort the interpreter immediately.
10719
10720This function 'dumps core' or otherwise fails in the hardest way possible
10721on the hosting operating system. This function never returns.
10722[clinic start generated code]*/
10723
Larry Hastings2f936352014-08-05 14:04:04 +100010724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010725os_abort_impl(PyObject *module)
10726/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010727{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010728 abort();
10729 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010730#ifndef __clang__
10731 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10732 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10733 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010734 Py_FatalError("abort() called from Python code didn't abort!");
10735 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010736#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010737}
Fred Drakebec628d1999-12-15 18:31:10 +000010738
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010739#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010740/* Grab ShellExecute dynamically from shell32 */
10741static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010742static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10743 LPCWSTR, INT);
10744static int
10745check_ShellExecute()
10746{
10747 HINSTANCE hShell32;
10748
10749 /* only recheck */
10750 if (-1 == has_ShellExecute) {
10751 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010752 /* Security note: this call is not vulnerable to "DLL hijacking".
10753 SHELL32 is part of "KnownDLLs" and so Windows always load
10754 the system SHELL32.DLL, even if there is another SHELL32.DLL
10755 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010756 hShell32 = LoadLibraryW(L"SHELL32");
10757 Py_END_ALLOW_THREADS
10758 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010759 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10760 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010761 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010762 } else {
10763 has_ShellExecute = 0;
10764 }
10765 }
10766 return has_ShellExecute;
10767}
10768
10769
Steve Dowercc16be82016-09-08 10:35:16 -070010770/*[clinic input]
10771os.startfile
10772 filepath: path_t
10773 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010774
Steve Dowercc16be82016-09-08 10:35:16 -070010775startfile(filepath [, operation])
10776
10777Start a file with its associated application.
10778
10779When "operation" is not specified or "open", this acts like
10780double-clicking the file in Explorer, or giving the file name as an
10781argument to the DOS "start" command: the file is opened with whatever
10782application (if any) its extension is associated.
10783When another "operation" is given, it specifies what should be done with
10784the file. A typical operation is "print".
10785
10786startfile returns as soon as the associated application is launched.
10787There is no option to wait for the application to close, and no way
10788to retrieve the application's exit status.
10789
10790The filepath is relative to the current directory. If you want to use
10791an absolute path, make sure the first character is not a slash ("/");
10792the underlying Win32 ShellExecute function doesn't work if it is.
10793[clinic start generated code]*/
10794
10795static PyObject *
10796os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10797/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10798{
10799 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010800
10801 if(!check_ShellExecute()) {
10802 /* If the OS doesn't have ShellExecute, return a
10803 NotImplementedError. */
10804 return PyErr_Format(PyExc_NotImplementedError,
10805 "startfile not available on this platform");
10806 }
10807
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010809 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010810 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 Py_END_ALLOW_THREADS
10812
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010814 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010815 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 }
Steve Dowercc16be82016-09-08 10:35:16 -070010817 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010818}
Larry Hastings2f936352014-08-05 14:04:04 +100010819#endif /* MS_WINDOWS */
10820
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010821
Martin v. Löwis438b5342002-12-27 10:16:42 +000010822#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010823/*[clinic input]
10824os.getloadavg
10825
10826Return average recent system load information.
10827
10828Return the number of processes in the system run queue averaged over
10829the last 1, 5, and 15 minutes as a tuple of three floats.
10830Raises OSError if the load average was unobtainable.
10831[clinic start generated code]*/
10832
Larry Hastings2f936352014-08-05 14:04:04 +100010833static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010834os_getloadavg_impl(PyObject *module)
10835/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010836{
10837 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010838 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010839 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10840 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010841 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010842 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010843}
Larry Hastings2f936352014-08-05 14:04:04 +100010844#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010845
Larry Hastings2f936352014-08-05 14:04:04 +100010846
10847/*[clinic input]
10848os.device_encoding
10849 fd: int
10850
10851Return a string describing the encoding of a terminal's file descriptor.
10852
10853The file descriptor must be attached to a terminal.
10854If the device is not a terminal, return None.
10855[clinic start generated code]*/
10856
Larry Hastings2f936352014-08-05 14:04:04 +100010857static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010858os_device_encoding_impl(PyObject *module, int fd)
10859/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010860{
Brett Cannonefb00c02012-02-29 18:31:31 -050010861 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010862}
10863
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010864
Larry Hastings2f936352014-08-05 14:04:04 +100010865#ifdef HAVE_SETRESUID
10866/*[clinic input]
10867os.setresuid
10868
10869 ruid: uid_t
10870 euid: uid_t
10871 suid: uid_t
10872 /
10873
10874Set the current process's real, effective, and saved user ids.
10875[clinic start generated code]*/
10876
Larry Hastings2f936352014-08-05 14:04:04 +100010877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010878os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10879/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010880{
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 if (setresuid(ruid, euid, suid) < 0)
10882 return posix_error();
10883 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010884}
Larry Hastings2f936352014-08-05 14:04:04 +100010885#endif /* HAVE_SETRESUID */
10886
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010887
10888#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010889/*[clinic input]
10890os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010891
Larry Hastings2f936352014-08-05 14:04:04 +100010892 rgid: gid_t
10893 egid: gid_t
10894 sgid: gid_t
10895 /
10896
10897Set the current process's real, effective, and saved group ids.
10898[clinic start generated code]*/
10899
Larry Hastings2f936352014-08-05 14:04:04 +100010900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010901os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10902/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010903{
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 if (setresgid(rgid, egid, sgid) < 0)
10905 return posix_error();
10906 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010907}
Larry Hastings2f936352014-08-05 14:04:04 +100010908#endif /* HAVE_SETRESGID */
10909
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010910
10911#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010912/*[clinic input]
10913os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010914
Larry Hastings2f936352014-08-05 14:04:04 +100010915Return a tuple of the current process's real, effective, and saved user ids.
10916[clinic start generated code]*/
10917
Larry Hastings2f936352014-08-05 14:04:04 +100010918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010919os_getresuid_impl(PyObject *module)
10920/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010921{
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010923 if (getresuid(&ruid, &euid, &suid) < 0)
10924 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010925 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10926 _PyLong_FromUid(euid),
10927 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010928}
Larry Hastings2f936352014-08-05 14:04:04 +100010929#endif /* HAVE_GETRESUID */
10930
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010931
10932#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010933/*[clinic input]
10934os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010935
Larry Hastings2f936352014-08-05 14:04:04 +100010936Return a tuple of the current process's real, effective, and saved group ids.
10937[clinic start generated code]*/
10938
Larry Hastings2f936352014-08-05 14:04:04 +100010939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010940os_getresgid_impl(PyObject *module)
10941/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010942{
10943 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 if (getresgid(&rgid, &egid, &sgid) < 0)
10945 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010946 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10947 _PyLong_FromGid(egid),
10948 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010949}
Larry Hastings2f936352014-08-05 14:04:04 +100010950#endif /* HAVE_GETRESGID */
10951
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010952
Benjamin Peterson9428d532011-09-14 11:45:52 -040010953#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010954/*[clinic input]
10955os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010956
Larry Hastings2f936352014-08-05 14:04:04 +100010957 path: path_t(allow_fd=True)
10958 attribute: path_t
10959 *
10960 follow_symlinks: bool = True
10961
10962Return the value of extended attribute attribute on path.
10963
10964path may be either a string or an open file descriptor.
10965If follow_symlinks is False, and the last element of the path is a symbolic
10966 link, getxattr will examine the symbolic link itself instead of the file
10967 the link points to.
10968
10969[clinic start generated code]*/
10970
Larry Hastings2f936352014-08-05 14:04:04 +100010971static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010972os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010973 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010974/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010975{
10976 Py_ssize_t i;
10977 PyObject *buffer = NULL;
10978
10979 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10980 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010981
Larry Hastings9cf065c2012-06-22 16:30:09 -070010982 for (i = 0; ; i++) {
10983 void *ptr;
10984 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010985 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010986 Py_ssize_t buffer_size = buffer_sizes[i];
10987 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010988 path_error(path);
10989 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 }
10991 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10992 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010993 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010994 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010995
Larry Hastings9cf065c2012-06-22 16:30:09 -070010996 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010997 if (path->fd >= 0)
10998 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010999 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011000 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011001 else
Larry Hastings2f936352014-08-05 14:04:04 +100011002 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011003 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011004
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 if (result < 0) {
11006 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 if (errno == ERANGE)
11008 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011009 path_error(path);
11010 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 if (result != buffer_size) {
11014 /* Can only shrink. */
11015 _PyBytes_Resize(&buffer, result);
11016 }
11017 break;
11018 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011019
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011021}
11022
Larry Hastings2f936352014-08-05 14:04:04 +100011023
11024/*[clinic input]
11025os.setxattr
11026
11027 path: path_t(allow_fd=True)
11028 attribute: path_t
11029 value: Py_buffer
11030 flags: int = 0
11031 *
11032 follow_symlinks: bool = True
11033
11034Set extended attribute attribute on path to value.
11035
11036path may be either a string or an open file descriptor.
11037If follow_symlinks is False, and the last element of the path is a symbolic
11038 link, setxattr will modify the symbolic link itself instead of the file
11039 the link points to.
11040
11041[clinic start generated code]*/
11042
Benjamin Peterson799bd802011-08-31 22:15:17 -040011043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011044os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011045 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011046/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011047{
Larry Hastings2f936352014-08-05 14:04:04 +100011048 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011049
Larry Hastings2f936352014-08-05 14:04:04 +100011050 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011051 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011052
Benjamin Peterson799bd802011-08-31 22:15:17 -040011053 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011054 if (path->fd > -1)
11055 result = fsetxattr(path->fd, attribute->narrow,
11056 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011057 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011058 result = setxattr(path->narrow, attribute->narrow,
11059 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011060 else
Larry Hastings2f936352014-08-05 14:04:04 +100011061 result = lsetxattr(path->narrow, attribute->narrow,
11062 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011063 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011064
Larry Hastings9cf065c2012-06-22 16:30:09 -070011065 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011066 path_error(path);
11067 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011068 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011069
Larry Hastings2f936352014-08-05 14:04:04 +100011070 Py_RETURN_NONE;
11071}
11072
11073
11074/*[clinic input]
11075os.removexattr
11076
11077 path: path_t(allow_fd=True)
11078 attribute: path_t
11079 *
11080 follow_symlinks: bool = True
11081
11082Remove extended attribute attribute on path.
11083
11084path may be either a string or an open file descriptor.
11085If follow_symlinks is False, and the last element of the path is a symbolic
11086 link, removexattr will modify the symbolic link itself instead of the file
11087 the link points to.
11088
11089[clinic start generated code]*/
11090
Larry Hastings2f936352014-08-05 14:04:04 +100011091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011092os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011093 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011094/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011095{
11096 ssize_t result;
11097
11098 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11099 return NULL;
11100
11101 Py_BEGIN_ALLOW_THREADS;
11102 if (path->fd > -1)
11103 result = fremovexattr(path->fd, attribute->narrow);
11104 else if (follow_symlinks)
11105 result = removexattr(path->narrow, attribute->narrow);
11106 else
11107 result = lremovexattr(path->narrow, attribute->narrow);
11108 Py_END_ALLOW_THREADS;
11109
11110 if (result) {
11111 return path_error(path);
11112 }
11113
11114 Py_RETURN_NONE;
11115}
11116
11117
11118/*[clinic input]
11119os.listxattr
11120
11121 path: path_t(allow_fd=True, nullable=True) = None
11122 *
11123 follow_symlinks: bool = True
11124
11125Return a list of extended attributes on path.
11126
11127path may be either None, a string, or an open file descriptor.
11128if path is None, listxattr will examine the current directory.
11129If follow_symlinks is False, and the last element of the path is a symbolic
11130 link, listxattr will examine the symbolic link itself instead of the file
11131 the link points to.
11132[clinic start generated code]*/
11133
Larry Hastings2f936352014-08-05 14:04:04 +100011134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011135os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11136/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011137{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011138 Py_ssize_t i;
11139 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011140 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011141 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011142
Larry Hastings2f936352014-08-05 14:04:04 +100011143 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011144 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011145
Larry Hastings2f936352014-08-05 14:04:04 +100011146 name = path->narrow ? path->narrow : ".";
11147
Larry Hastings9cf065c2012-06-22 16:30:09 -070011148 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011149 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011150 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011151 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011152 Py_ssize_t buffer_size = buffer_sizes[i];
11153 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011154 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011155 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011156 break;
11157 }
11158 buffer = PyMem_MALLOC(buffer_size);
11159 if (!buffer) {
11160 PyErr_NoMemory();
11161 break;
11162 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011163
Larry Hastings9cf065c2012-06-22 16:30:09 -070011164 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011165 if (path->fd > -1)
11166 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011167 else if (follow_symlinks)
11168 length = listxattr(name, buffer, buffer_size);
11169 else
11170 length = llistxattr(name, buffer, buffer_size);
11171 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011172
Larry Hastings9cf065c2012-06-22 16:30:09 -070011173 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011174 if (errno == ERANGE) {
11175 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011176 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011177 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011178 }
Larry Hastings2f936352014-08-05 14:04:04 +100011179 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011180 break;
11181 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011182
Larry Hastings9cf065c2012-06-22 16:30:09 -070011183 result = PyList_New(0);
11184 if (!result) {
11185 goto exit;
11186 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011187
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188 end = buffer + length;
11189 for (trace = start = buffer; trace != end; trace++) {
11190 if (!*trace) {
11191 int error;
11192 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11193 trace - start);
11194 if (!attribute) {
11195 Py_DECREF(result);
11196 result = NULL;
11197 goto exit;
11198 }
11199 error = PyList_Append(result, attribute);
11200 Py_DECREF(attribute);
11201 if (error) {
11202 Py_DECREF(result);
11203 result = NULL;
11204 goto exit;
11205 }
11206 start = trace + 1;
11207 }
11208 }
11209 break;
11210 }
11211exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011212 if (buffer)
11213 PyMem_FREE(buffer);
11214 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011215}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011216#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011217
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011218
Larry Hastings2f936352014-08-05 14:04:04 +100011219/*[clinic input]
11220os.urandom
11221
11222 size: Py_ssize_t
11223 /
11224
11225Return a bytes object containing random bytes suitable for cryptographic use.
11226[clinic start generated code]*/
11227
Larry Hastings2f936352014-08-05 14:04:04 +100011228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011229os_urandom_impl(PyObject *module, Py_ssize_t size)
11230/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011231{
11232 PyObject *bytes;
11233 int result;
11234
Georg Brandl2fb477c2012-02-21 00:33:36 +010011235 if (size < 0)
11236 return PyErr_Format(PyExc_ValueError,
11237 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011238 bytes = PyBytes_FromStringAndSize(NULL, size);
11239 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011240 return NULL;
11241
Victor Stinnere66987e2016-09-06 16:33:52 -070011242 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011243 if (result == -1) {
11244 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011245 return NULL;
11246 }
Larry Hastings2f936352014-08-05 14:04:04 +100011247 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011248}
11249
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011250/* Terminal size querying */
11251
11252static PyTypeObject TerminalSizeType;
11253
11254PyDoc_STRVAR(TerminalSize_docstring,
11255 "A tuple of (columns, lines) for holding terminal window size");
11256
11257static PyStructSequence_Field TerminalSize_fields[] = {
11258 {"columns", "width of the terminal window in characters"},
11259 {"lines", "height of the terminal window in characters"},
11260 {NULL, NULL}
11261};
11262
11263static PyStructSequence_Desc TerminalSize_desc = {
11264 "os.terminal_size",
11265 TerminalSize_docstring,
11266 TerminalSize_fields,
11267 2,
11268};
11269
11270#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011271/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011272PyDoc_STRVAR(termsize__doc__,
11273 "Return the size of the terminal window as (columns, lines).\n" \
11274 "\n" \
11275 "The optional argument fd (default standard output) specifies\n" \
11276 "which file descriptor should be queried.\n" \
11277 "\n" \
11278 "If the file descriptor is not connected to a terminal, an OSError\n" \
11279 "is thrown.\n" \
11280 "\n" \
11281 "This function will only be defined if an implementation is\n" \
11282 "available for this system.\n" \
11283 "\n" \
11284 "shutil.get_terminal_size is the high-level function which should \n" \
11285 "normally be used, os.get_terminal_size is the low-level implementation.");
11286
11287static PyObject*
11288get_terminal_size(PyObject *self, PyObject *args)
11289{
11290 int columns, lines;
11291 PyObject *termsize;
11292
11293 int fd = fileno(stdout);
11294 /* Under some conditions stdout may not be connected and
11295 * fileno(stdout) may point to an invalid file descriptor. For example
11296 * GUI apps don't have valid standard streams by default.
11297 *
11298 * If this happens, and the optional fd argument is not present,
11299 * the ioctl below will fail returning EBADF. This is what we want.
11300 */
11301
11302 if (!PyArg_ParseTuple(args, "|i", &fd))
11303 return NULL;
11304
11305#ifdef TERMSIZE_USE_IOCTL
11306 {
11307 struct winsize w;
11308 if (ioctl(fd, TIOCGWINSZ, &w))
11309 return PyErr_SetFromErrno(PyExc_OSError);
11310 columns = w.ws_col;
11311 lines = w.ws_row;
11312 }
11313#endif /* TERMSIZE_USE_IOCTL */
11314
11315#ifdef TERMSIZE_USE_CONIO
11316 {
11317 DWORD nhandle;
11318 HANDLE handle;
11319 CONSOLE_SCREEN_BUFFER_INFO csbi;
11320 switch (fd) {
11321 case 0: nhandle = STD_INPUT_HANDLE;
11322 break;
11323 case 1: nhandle = STD_OUTPUT_HANDLE;
11324 break;
11325 case 2: nhandle = STD_ERROR_HANDLE;
11326 break;
11327 default:
11328 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11329 }
11330 handle = GetStdHandle(nhandle);
11331 if (handle == NULL)
11332 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11333 if (handle == INVALID_HANDLE_VALUE)
11334 return PyErr_SetFromWindowsErr(0);
11335
11336 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11337 return PyErr_SetFromWindowsErr(0);
11338
11339 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11340 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11341 }
11342#endif /* TERMSIZE_USE_CONIO */
11343
11344 termsize = PyStructSequence_New(&TerminalSizeType);
11345 if (termsize == NULL)
11346 return NULL;
11347 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11348 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11349 if (PyErr_Occurred()) {
11350 Py_DECREF(termsize);
11351 return NULL;
11352 }
11353 return termsize;
11354}
11355#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11356
Larry Hastings2f936352014-08-05 14:04:04 +100011357
11358/*[clinic input]
11359os.cpu_count
11360
Charles-François Natali80d62e62015-08-13 20:37:08 +010011361Return the number of CPUs in the system; return None if indeterminable.
11362
11363This number is not equivalent to the number of CPUs the current process can
11364use. The number of usable CPUs can be obtained with
11365``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011366[clinic start generated code]*/
11367
Larry Hastings2f936352014-08-05 14:04:04 +100011368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011369os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011370/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011371{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011372 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011373#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011374 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11375 Need to fallback to Vista behavior if this call isn't present */
11376 HINSTANCE hKernel32;
11377 hKernel32 = GetModuleHandleW(L"KERNEL32");
11378
11379 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11380 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11381 "GetMaximumProcessorCount");
11382 if (_GetMaximumProcessorCount != NULL) {
11383 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11384 }
11385 else {
11386 SYSTEM_INFO sysinfo;
11387 GetSystemInfo(&sysinfo);
11388 ncpu = sysinfo.dwNumberOfProcessors;
11389 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011390#elif defined(__hpux)
11391 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11392#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11393 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011394#elif defined(__DragonFly__) || \
11395 defined(__OpenBSD__) || \
11396 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011397 defined(__NetBSD__) || \
11398 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011399 int mib[2];
11400 size_t len = sizeof(ncpu);
11401 mib[0] = CTL_HW;
11402 mib[1] = HW_NCPU;
11403 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11404 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011405#endif
11406 if (ncpu >= 1)
11407 return PyLong_FromLong(ncpu);
11408 else
11409 Py_RETURN_NONE;
11410}
11411
Victor Stinnerdaf45552013-08-28 00:53:59 +020011412
Larry Hastings2f936352014-08-05 14:04:04 +100011413/*[clinic input]
11414os.get_inheritable -> bool
11415
11416 fd: int
11417 /
11418
11419Get the close-on-exe flag of the specified file descriptor.
11420[clinic start generated code]*/
11421
Larry Hastings2f936352014-08-05 14:04:04 +100011422static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011423os_get_inheritable_impl(PyObject *module, int fd)
11424/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011425{
Steve Dower8fc89802015-04-12 00:26:27 -040011426 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011427 _Py_BEGIN_SUPPRESS_IPH
11428 return_value = _Py_get_inheritable(fd);
11429 _Py_END_SUPPRESS_IPH
11430 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011431}
11432
11433
11434/*[clinic input]
11435os.set_inheritable
11436 fd: int
11437 inheritable: int
11438 /
11439
11440Set the inheritable flag of the specified file descriptor.
11441[clinic start generated code]*/
11442
Larry Hastings2f936352014-08-05 14:04:04 +100011443static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011444os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11445/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011446{
Steve Dower8fc89802015-04-12 00:26:27 -040011447 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011448
Steve Dower8fc89802015-04-12 00:26:27 -040011449 _Py_BEGIN_SUPPRESS_IPH
11450 result = _Py_set_inheritable(fd, inheritable, NULL);
11451 _Py_END_SUPPRESS_IPH
11452 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011453 return NULL;
11454 Py_RETURN_NONE;
11455}
11456
11457
11458#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011459/*[clinic input]
11460os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011461 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011462 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011463
Larry Hastings2f936352014-08-05 14:04:04 +100011464Get the close-on-exe flag of the specified file descriptor.
11465[clinic start generated code]*/
11466
Larry Hastings2f936352014-08-05 14:04:04 +100011467static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011468os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011469/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011470{
11471 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011472
11473 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11474 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011475 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011476 }
11477
Larry Hastings2f936352014-08-05 14:04:04 +100011478 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011479}
11480
Victor Stinnerdaf45552013-08-28 00:53:59 +020011481
Larry Hastings2f936352014-08-05 14:04:04 +100011482/*[clinic input]
11483os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011484 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011485 inheritable: bool
11486 /
11487
11488Set the inheritable flag of the specified handle.
11489[clinic start generated code]*/
11490
Larry Hastings2f936352014-08-05 14:04:04 +100011491static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011492os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011493 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011494/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011495{
11496 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011497 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11498 PyErr_SetFromWindowsErr(0);
11499 return NULL;
11500 }
11501 Py_RETURN_NONE;
11502}
Larry Hastings2f936352014-08-05 14:04:04 +100011503#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011504
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011505#ifndef MS_WINDOWS
11506PyDoc_STRVAR(get_blocking__doc__,
11507 "get_blocking(fd) -> bool\n" \
11508 "\n" \
11509 "Get the blocking mode of the file descriptor:\n" \
11510 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11511
11512static PyObject*
11513posix_get_blocking(PyObject *self, PyObject *args)
11514{
11515 int fd;
11516 int blocking;
11517
11518 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11519 return NULL;
11520
Steve Dower8fc89802015-04-12 00:26:27 -040011521 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011522 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011523 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011524 if (blocking < 0)
11525 return NULL;
11526 return PyBool_FromLong(blocking);
11527}
11528
11529PyDoc_STRVAR(set_blocking__doc__,
11530 "set_blocking(fd, blocking)\n" \
11531 "\n" \
11532 "Set the blocking mode of the specified file descriptor.\n" \
11533 "Set the O_NONBLOCK flag if blocking is False,\n" \
11534 "clear the O_NONBLOCK flag otherwise.");
11535
11536static PyObject*
11537posix_set_blocking(PyObject *self, PyObject *args)
11538{
Steve Dower8fc89802015-04-12 00:26:27 -040011539 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011540
11541 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11542 return NULL;
11543
Steve Dower8fc89802015-04-12 00:26:27 -040011544 _Py_BEGIN_SUPPRESS_IPH
11545 result = _Py_set_blocking(fd, blocking);
11546 _Py_END_SUPPRESS_IPH
11547 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011548 return NULL;
11549 Py_RETURN_NONE;
11550}
11551#endif /* !MS_WINDOWS */
11552
11553
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011554/*[clinic input]
11555class os.DirEntry "DirEntry *" "&DirEntryType"
11556[clinic start generated code]*/
11557/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011558
11559typedef struct {
11560 PyObject_HEAD
11561 PyObject *name;
11562 PyObject *path;
11563 PyObject *stat;
11564 PyObject *lstat;
11565#ifdef MS_WINDOWS
11566 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011567 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011568 int got_file_index;
11569#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011570#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011571 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011572#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011573 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011574 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011575#endif
11576} DirEntry;
11577
11578static void
11579DirEntry_dealloc(DirEntry *entry)
11580{
11581 Py_XDECREF(entry->name);
11582 Py_XDECREF(entry->path);
11583 Py_XDECREF(entry->stat);
11584 Py_XDECREF(entry->lstat);
11585 Py_TYPE(entry)->tp_free((PyObject *)entry);
11586}
11587
11588/* Forward reference */
11589static int
11590DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11591
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011592/*[clinic input]
11593os.DirEntry.is_symlink -> bool
11594
11595Return True if the entry is a symbolic link; cached per entry.
11596[clinic start generated code]*/
11597
Victor Stinner6036e442015-03-08 01:58:04 +010011598static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011599os_DirEntry_is_symlink_impl(DirEntry *self)
11600/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011601{
11602#ifdef MS_WINDOWS
11603 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011604#elif defined(HAVE_DIRENT_D_TYPE)
11605 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011606 if (self->d_type != DT_UNKNOWN)
11607 return self->d_type == DT_LNK;
11608 else
11609 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011610#else
11611 /* POSIX without d_type */
11612 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011613#endif
11614}
11615
11616static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011617DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11618{
11619 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011620 STRUCT_STAT st;
11621 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011622
11623#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011624 if (!PyUnicode_FSDecoder(self->path, &ub))
11625 return NULL;
11626 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011627#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011628 if (!PyUnicode_FSConverter(self->path, &ub))
11629 return NULL;
11630 const char *path = PyBytes_AS_STRING(ub);
11631 if (self->dir_fd != DEFAULT_DIR_FD) {
11632#ifdef HAVE_FSTATAT
11633 result = fstatat(self->dir_fd, path, &st,
11634 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11635#else
11636 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11637 return NULL;
11638#endif /* HAVE_FSTATAT */
11639 }
11640 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011641#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011642 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011643 if (follow_symlinks)
11644 result = STAT(path, &st);
11645 else
11646 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011647 }
11648 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011649
11650 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011651 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011652
11653 return _pystat_fromstructstat(&st);
11654}
11655
11656static PyObject *
11657DirEntry_get_lstat(DirEntry *self)
11658{
11659 if (!self->lstat) {
11660#ifdef MS_WINDOWS
11661 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11662#else /* POSIX */
11663 self->lstat = DirEntry_fetch_stat(self, 0);
11664#endif
11665 }
11666 Py_XINCREF(self->lstat);
11667 return self->lstat;
11668}
11669
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011670/*[clinic input]
11671os.DirEntry.stat
11672 *
11673 follow_symlinks: bool = True
11674
11675Return stat_result object for the entry; cached per entry.
11676[clinic start generated code]*/
11677
Victor Stinner6036e442015-03-08 01:58:04 +010011678static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011679os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11680/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011681{
11682 if (!follow_symlinks)
11683 return DirEntry_get_lstat(self);
11684
11685 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011686 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011687 if (result == -1)
11688 return NULL;
11689 else if (result)
11690 self->stat = DirEntry_fetch_stat(self, 1);
11691 else
11692 self->stat = DirEntry_get_lstat(self);
11693 }
11694
11695 Py_XINCREF(self->stat);
11696 return self->stat;
11697}
11698
Victor Stinner6036e442015-03-08 01:58:04 +010011699/* Set exception and return -1 on error, 0 for False, 1 for True */
11700static int
11701DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11702{
11703 PyObject *stat = NULL;
11704 PyObject *st_mode = NULL;
11705 long mode;
11706 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011707#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011708 int is_symlink;
11709 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011710#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011711#ifdef MS_WINDOWS
11712 unsigned long dir_bits;
11713#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011714 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011715
11716#ifdef MS_WINDOWS
11717 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11718 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011719#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011720 is_symlink = self->d_type == DT_LNK;
11721 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11722#endif
11723
Victor Stinner35a97c02015-03-08 02:59:09 +010011724#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011725 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011726#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011727 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011728 if (!stat) {
11729 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11730 /* If file doesn't exist (anymore), then return False
11731 (i.e., say it's not a file/directory) */
11732 PyErr_Clear();
11733 return 0;
11734 }
11735 goto error;
11736 }
11737 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11738 if (!st_mode)
11739 goto error;
11740
11741 mode = PyLong_AsLong(st_mode);
11742 if (mode == -1 && PyErr_Occurred())
11743 goto error;
11744 Py_CLEAR(st_mode);
11745 Py_CLEAR(stat);
11746 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011747#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011748 }
11749 else if (is_symlink) {
11750 assert(mode_bits != S_IFLNK);
11751 result = 0;
11752 }
11753 else {
11754 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11755#ifdef MS_WINDOWS
11756 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11757 if (mode_bits == S_IFDIR)
11758 result = dir_bits != 0;
11759 else
11760 result = dir_bits == 0;
11761#else /* POSIX */
11762 if (mode_bits == S_IFDIR)
11763 result = self->d_type == DT_DIR;
11764 else
11765 result = self->d_type == DT_REG;
11766#endif
11767 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011768#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011769
11770 return result;
11771
11772error:
11773 Py_XDECREF(st_mode);
11774 Py_XDECREF(stat);
11775 return -1;
11776}
11777
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011778/*[clinic input]
11779os.DirEntry.is_dir -> bool
11780 *
11781 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011782
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011783Return True if the entry is a directory; cached per entry.
11784[clinic start generated code]*/
11785
11786static int
11787os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11788/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11789{
11790 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011791}
11792
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011793/*[clinic input]
11794os.DirEntry.is_file -> bool
11795 *
11796 follow_symlinks: bool = True
11797
11798Return True if the entry is a file; cached per entry.
11799[clinic start generated code]*/
11800
11801static int
11802os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11803/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011804{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011805 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011806}
11807
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011808/*[clinic input]
11809os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011810
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011811Return inode of the entry; cached per entry.
11812[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011813
11814static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011815os_DirEntry_inode_impl(DirEntry *self)
11816/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011817{
11818#ifdef MS_WINDOWS
11819 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011820 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011821 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011822 STRUCT_STAT stat;
11823 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011824
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011825 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011826 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011827 path = PyUnicode_AsUnicode(unicode);
11828 result = LSTAT(path, &stat);
11829 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011830
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011831 if (result != 0)
11832 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011833
11834 self->win32_file_index = stat.st_ino;
11835 self->got_file_index = 1;
11836 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011837 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11838 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011839#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011840 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11841 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011842#endif
11843}
11844
11845static PyObject *
11846DirEntry_repr(DirEntry *self)
11847{
11848 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11849}
11850
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011851/*[clinic input]
11852os.DirEntry.__fspath__
11853
11854Returns the path for the entry.
11855[clinic start generated code]*/
11856
Brett Cannon96881cd2016-06-10 14:37:21 -070011857static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011858os_DirEntry___fspath___impl(DirEntry *self)
11859/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011860{
11861 Py_INCREF(self->path);
11862 return self->path;
11863}
11864
Victor Stinner6036e442015-03-08 01:58:04 +010011865static PyMemberDef DirEntry_members[] = {
11866 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11867 "the entry's base filename, relative to scandir() \"path\" argument"},
11868 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11869 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11870 {NULL}
11871};
11872
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011873#include "clinic/posixmodule.c.h"
11874
Victor Stinner6036e442015-03-08 01:58:04 +010011875static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011876 OS_DIRENTRY_IS_DIR_METHODDEF
11877 OS_DIRENTRY_IS_FILE_METHODDEF
11878 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11879 OS_DIRENTRY_STAT_METHODDEF
11880 OS_DIRENTRY_INODE_METHODDEF
11881 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011882 {NULL}
11883};
11884
Benjamin Peterson5646de42015-04-12 17:56:34 -040011885static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011886 PyVarObject_HEAD_INIT(NULL, 0)
11887 MODNAME ".DirEntry", /* tp_name */
11888 sizeof(DirEntry), /* tp_basicsize */
11889 0, /* tp_itemsize */
11890 /* methods */
11891 (destructor)DirEntry_dealloc, /* tp_dealloc */
11892 0, /* tp_print */
11893 0, /* tp_getattr */
11894 0, /* tp_setattr */
11895 0, /* tp_compare */
11896 (reprfunc)DirEntry_repr, /* tp_repr */
11897 0, /* tp_as_number */
11898 0, /* tp_as_sequence */
11899 0, /* tp_as_mapping */
11900 0, /* tp_hash */
11901 0, /* tp_call */
11902 0, /* tp_str */
11903 0, /* tp_getattro */
11904 0, /* tp_setattro */
11905 0, /* tp_as_buffer */
11906 Py_TPFLAGS_DEFAULT, /* tp_flags */
11907 0, /* tp_doc */
11908 0, /* tp_traverse */
11909 0, /* tp_clear */
11910 0, /* tp_richcompare */
11911 0, /* tp_weaklistoffset */
11912 0, /* tp_iter */
11913 0, /* tp_iternext */
11914 DirEntry_methods, /* tp_methods */
11915 DirEntry_members, /* tp_members */
11916};
11917
11918#ifdef MS_WINDOWS
11919
11920static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011921join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011922{
11923 Py_ssize_t path_len;
11924 Py_ssize_t size;
11925 wchar_t *result;
11926 wchar_t ch;
11927
11928 if (!path_wide) { /* Default arg: "." */
11929 path_wide = L".";
11930 path_len = 1;
11931 }
11932 else {
11933 path_len = wcslen(path_wide);
11934 }
11935
11936 /* The +1's are for the path separator and the NUL */
11937 size = path_len + 1 + wcslen(filename) + 1;
11938 result = PyMem_New(wchar_t, size);
11939 if (!result) {
11940 PyErr_NoMemory();
11941 return NULL;
11942 }
11943 wcscpy(result, path_wide);
11944 if (path_len > 0) {
11945 ch = result[path_len - 1];
11946 if (ch != SEP && ch != ALTSEP && ch != L':')
11947 result[path_len++] = SEP;
11948 wcscpy(result + path_len, filename);
11949 }
11950 return result;
11951}
11952
11953static PyObject *
11954DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11955{
11956 DirEntry *entry;
11957 BY_HANDLE_FILE_INFORMATION file_info;
11958 ULONG reparse_tag;
11959 wchar_t *joined_path;
11960
11961 entry = PyObject_New(DirEntry, &DirEntryType);
11962 if (!entry)
11963 return NULL;
11964 entry->name = NULL;
11965 entry->path = NULL;
11966 entry->stat = NULL;
11967 entry->lstat = NULL;
11968 entry->got_file_index = 0;
11969
11970 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11971 if (!entry->name)
11972 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011973 if (path->narrow) {
11974 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11975 if (!entry->name)
11976 goto error;
11977 }
Victor Stinner6036e442015-03-08 01:58:04 +010011978
11979 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11980 if (!joined_path)
11981 goto error;
11982
11983 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11984 PyMem_Free(joined_path);
11985 if (!entry->path)
11986 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011987 if (path->narrow) {
11988 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11989 if (!entry->path)
11990 goto error;
11991 }
Victor Stinner6036e442015-03-08 01:58:04 +010011992
Steve Dowercc16be82016-09-08 10:35:16 -070011993 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011994 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11995
11996 return (PyObject *)entry;
11997
11998error:
11999 Py_DECREF(entry);
12000 return NULL;
12001}
12002
12003#else /* POSIX */
12004
12005static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012006join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012007{
12008 Py_ssize_t path_len;
12009 Py_ssize_t size;
12010 char *result;
12011
12012 if (!path_narrow) { /* Default arg: "." */
12013 path_narrow = ".";
12014 path_len = 1;
12015 }
12016 else {
12017 path_len = strlen(path_narrow);
12018 }
12019
12020 if (filename_len == -1)
12021 filename_len = strlen(filename);
12022
12023 /* The +1's are for the path separator and the NUL */
12024 size = path_len + 1 + filename_len + 1;
12025 result = PyMem_New(char, size);
12026 if (!result) {
12027 PyErr_NoMemory();
12028 return NULL;
12029 }
12030 strcpy(result, path_narrow);
12031 if (path_len > 0 && result[path_len - 1] != '/')
12032 result[path_len++] = '/';
12033 strcpy(result + path_len, filename);
12034 return result;
12035}
12036
12037static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012038DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012039 ino_t d_ino
12040#ifdef HAVE_DIRENT_D_TYPE
12041 , unsigned char d_type
12042#endif
12043 )
Victor Stinner6036e442015-03-08 01:58:04 +010012044{
12045 DirEntry *entry;
12046 char *joined_path;
12047
12048 entry = PyObject_New(DirEntry, &DirEntryType);
12049 if (!entry)
12050 return NULL;
12051 entry->name = NULL;
12052 entry->path = NULL;
12053 entry->stat = NULL;
12054 entry->lstat = NULL;
12055
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012056 if (path->fd != -1) {
12057 entry->dir_fd = path->fd;
12058 joined_path = NULL;
12059 }
12060 else {
12061 entry->dir_fd = DEFAULT_DIR_FD;
12062 joined_path = join_path_filename(path->narrow, name, name_len);
12063 if (!joined_path)
12064 goto error;
12065 }
Victor Stinner6036e442015-03-08 01:58:04 +010012066
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012067 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012068 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012069 if (joined_path)
12070 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012071 }
12072 else {
12073 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012074 if (joined_path)
12075 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012076 }
12077 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012078 if (!entry->name)
12079 goto error;
12080
12081 if (path->fd != -1) {
12082 entry->path = entry->name;
12083 Py_INCREF(entry->path);
12084 }
12085 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012086 goto error;
12087
Victor Stinner35a97c02015-03-08 02:59:09 +010012088#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012089 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012090#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012091 entry->d_ino = d_ino;
12092
12093 return (PyObject *)entry;
12094
12095error:
12096 Py_XDECREF(entry);
12097 return NULL;
12098}
12099
12100#endif
12101
12102
12103typedef struct {
12104 PyObject_HEAD
12105 path_t path;
12106#ifdef MS_WINDOWS
12107 HANDLE handle;
12108 WIN32_FIND_DATAW file_data;
12109 int first_time;
12110#else /* POSIX */
12111 DIR *dirp;
12112#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012113#ifdef HAVE_FDOPENDIR
12114 int fd;
12115#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012116} ScandirIterator;
12117
12118#ifdef MS_WINDOWS
12119
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012120static int
12121ScandirIterator_is_closed(ScandirIterator *iterator)
12122{
12123 return iterator->handle == INVALID_HANDLE_VALUE;
12124}
12125
Victor Stinner6036e442015-03-08 01:58:04 +010012126static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012127ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012128{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012129 HANDLE handle = iterator->handle;
12130
12131 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012132 return;
12133
Victor Stinner6036e442015-03-08 01:58:04 +010012134 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012135 Py_BEGIN_ALLOW_THREADS
12136 FindClose(handle);
12137 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012138}
12139
12140static PyObject *
12141ScandirIterator_iternext(ScandirIterator *iterator)
12142{
12143 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12144 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012145 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012146
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012147 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012148 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012149 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012150
12151 while (1) {
12152 if (!iterator->first_time) {
12153 Py_BEGIN_ALLOW_THREADS
12154 success = FindNextFileW(iterator->handle, file_data);
12155 Py_END_ALLOW_THREADS
12156 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012157 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012158 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012159 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012160 break;
12161 }
12162 }
12163 iterator->first_time = 0;
12164
12165 /* Skip over . and .. */
12166 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012167 wcscmp(file_data->cFileName, L"..") != 0) {
12168 entry = DirEntry_from_find_data(&iterator->path, file_data);
12169 if (!entry)
12170 break;
12171 return entry;
12172 }
Victor Stinner6036e442015-03-08 01:58:04 +010012173
12174 /* Loop till we get a non-dot directory or finish iterating */
12175 }
12176
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012177 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012178 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012179 return NULL;
12180}
12181
12182#else /* POSIX */
12183
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012184static int
12185ScandirIterator_is_closed(ScandirIterator *iterator)
12186{
12187 return !iterator->dirp;
12188}
12189
Victor Stinner6036e442015-03-08 01:58:04 +010012190static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012191ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012192{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012193 DIR *dirp = iterator->dirp;
12194
12195 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012196 return;
12197
Victor Stinner6036e442015-03-08 01:58:04 +010012198 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012199 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012200#ifdef HAVE_FDOPENDIR
12201 if (iterator->path.fd != -1)
12202 rewinddir(dirp);
12203#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012204 closedir(dirp);
12205 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012206 return;
12207}
12208
12209static PyObject *
12210ScandirIterator_iternext(ScandirIterator *iterator)
12211{
12212 struct dirent *direntp;
12213 Py_ssize_t name_len;
12214 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012215 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012216
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012217 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012218 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012219 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012220
12221 while (1) {
12222 errno = 0;
12223 Py_BEGIN_ALLOW_THREADS
12224 direntp = readdir(iterator->dirp);
12225 Py_END_ALLOW_THREADS
12226
12227 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012228 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012229 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012230 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012231 break;
12232 }
12233
12234 /* Skip over . and .. */
12235 name_len = NAMLEN(direntp);
12236 is_dot = direntp->d_name[0] == '.' &&
12237 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12238 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012239 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012240 name_len, direntp->d_ino
12241#ifdef HAVE_DIRENT_D_TYPE
12242 , direntp->d_type
12243#endif
12244 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012245 if (!entry)
12246 break;
12247 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012248 }
12249
12250 /* Loop till we get a non-dot directory or finish iterating */
12251 }
12252
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012253 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012254 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012255 return NULL;
12256}
12257
12258#endif
12259
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012260static PyObject *
12261ScandirIterator_close(ScandirIterator *self, PyObject *args)
12262{
12263 ScandirIterator_closedir(self);
12264 Py_RETURN_NONE;
12265}
12266
12267static PyObject *
12268ScandirIterator_enter(PyObject *self, PyObject *args)
12269{
12270 Py_INCREF(self);
12271 return self;
12272}
12273
12274static PyObject *
12275ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12276{
12277 ScandirIterator_closedir(self);
12278 Py_RETURN_NONE;
12279}
12280
Victor Stinner6036e442015-03-08 01:58:04 +010012281static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012282ScandirIterator_finalize(ScandirIterator *iterator)
12283{
12284 PyObject *error_type, *error_value, *error_traceback;
12285
12286 /* Save the current exception, if any. */
12287 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12288
12289 if (!ScandirIterator_is_closed(iterator)) {
12290 ScandirIterator_closedir(iterator);
12291
12292 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12293 "unclosed scandir iterator %R", iterator)) {
12294 /* Spurious errors can appear at shutdown */
12295 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12296 PyErr_WriteUnraisable((PyObject *) iterator);
12297 }
12298 }
12299 }
12300
Victor Stinner7bfa4092016-03-23 00:43:54 +010012301 path_cleanup(&iterator->path);
12302
12303 /* Restore the saved exception. */
12304 PyErr_Restore(error_type, error_value, error_traceback);
12305}
12306
12307static void
Victor Stinner6036e442015-03-08 01:58:04 +010012308ScandirIterator_dealloc(ScandirIterator *iterator)
12309{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012310 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12311 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012312
Victor Stinner6036e442015-03-08 01:58:04 +010012313 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12314}
12315
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012316static PyMethodDef ScandirIterator_methods[] = {
12317 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12318 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12319 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12320 {NULL}
12321};
12322
Benjamin Peterson5646de42015-04-12 17:56:34 -040012323static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012324 PyVarObject_HEAD_INIT(NULL, 0)
12325 MODNAME ".ScandirIterator", /* tp_name */
12326 sizeof(ScandirIterator), /* tp_basicsize */
12327 0, /* tp_itemsize */
12328 /* methods */
12329 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12330 0, /* tp_print */
12331 0, /* tp_getattr */
12332 0, /* tp_setattr */
12333 0, /* tp_compare */
12334 0, /* tp_repr */
12335 0, /* tp_as_number */
12336 0, /* tp_as_sequence */
12337 0, /* tp_as_mapping */
12338 0, /* tp_hash */
12339 0, /* tp_call */
12340 0, /* tp_str */
12341 0, /* tp_getattro */
12342 0, /* tp_setattro */
12343 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012344 Py_TPFLAGS_DEFAULT
12345 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012346 0, /* tp_doc */
12347 0, /* tp_traverse */
12348 0, /* tp_clear */
12349 0, /* tp_richcompare */
12350 0, /* tp_weaklistoffset */
12351 PyObject_SelfIter, /* tp_iter */
12352 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012353 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012354 0, /* tp_members */
12355 0, /* tp_getset */
12356 0, /* tp_base */
12357 0, /* tp_dict */
12358 0, /* tp_descr_get */
12359 0, /* tp_descr_set */
12360 0, /* tp_dictoffset */
12361 0, /* tp_init */
12362 0, /* tp_alloc */
12363 0, /* tp_new */
12364 0, /* tp_free */
12365 0, /* tp_is_gc */
12366 0, /* tp_bases */
12367 0, /* tp_mro */
12368 0, /* tp_cache */
12369 0, /* tp_subclasses */
12370 0, /* tp_weaklist */
12371 0, /* tp_del */
12372 0, /* tp_version_tag */
12373 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012374};
12375
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012376/*[clinic input]
12377os.scandir
12378
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012379 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012380
12381Return an iterator of DirEntry objects for given path.
12382
12383path can be specified as either str, bytes or path-like object. If path
12384is bytes, the names of yielded DirEntry objects will also be bytes; in
12385all other circumstances they will be str.
12386
12387If path is None, uses the path='.'.
12388[clinic start generated code]*/
12389
Victor Stinner6036e442015-03-08 01:58:04 +010012390static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012391os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012392/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012393{
12394 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012395#ifdef MS_WINDOWS
12396 wchar_t *path_strW;
12397#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012398 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012399#ifdef HAVE_FDOPENDIR
12400 int fd = -1;
12401#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012402#endif
12403
12404 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12405 if (!iterator)
12406 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012407
12408#ifdef MS_WINDOWS
12409 iterator->handle = INVALID_HANDLE_VALUE;
12410#else
12411 iterator->dirp = NULL;
12412#endif
12413
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012414 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012415 /* Move the ownership to iterator->path */
12416 path->object = NULL;
12417 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012418
12419#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012420 iterator->first_time = 1;
12421
12422 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12423 if (!path_strW)
12424 goto error;
12425
12426 Py_BEGIN_ALLOW_THREADS
12427 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12428 Py_END_ALLOW_THREADS
12429
12430 PyMem_Free(path_strW);
12431
12432 if (iterator->handle == INVALID_HANDLE_VALUE) {
12433 path_error(&iterator->path);
12434 goto error;
12435 }
12436#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012437 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012438#ifdef HAVE_FDOPENDIR
12439 if (path->fd != -1) {
12440 /* closedir() closes the FD, so we duplicate it */
12441 fd = _Py_dup(path->fd);
12442 if (fd == -1)
12443 goto error;
12444
12445 Py_BEGIN_ALLOW_THREADS
12446 iterator->dirp = fdopendir(fd);
12447 Py_END_ALLOW_THREADS
12448 }
12449 else
12450#endif
12451 {
12452 if (iterator->path.narrow)
12453 path_str = iterator->path.narrow;
12454 else
12455 path_str = ".";
12456
12457 Py_BEGIN_ALLOW_THREADS
12458 iterator->dirp = opendir(path_str);
12459 Py_END_ALLOW_THREADS
12460 }
Victor Stinner6036e442015-03-08 01:58:04 +010012461
12462 if (!iterator->dirp) {
12463 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012464#ifdef HAVE_FDOPENDIR
12465 if (fd != -1) {
12466 Py_BEGIN_ALLOW_THREADS
12467 close(fd);
12468 Py_END_ALLOW_THREADS
12469 }
12470#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012471 goto error;
12472 }
12473#endif
12474
12475 return (PyObject *)iterator;
12476
12477error:
12478 Py_DECREF(iterator);
12479 return NULL;
12480}
12481
Ethan Furman410ef8e2016-06-04 12:06:26 -070012482/*
12483 Return the file system path representation of the object.
12484
12485 If the object is str or bytes, then allow it to pass through with
12486 an incremented refcount. If the object defines __fspath__(), then
12487 return the result of that method. All other types raise a TypeError.
12488*/
12489PyObject *
12490PyOS_FSPath(PyObject *path)
12491{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012492 /* For error message reasons, this function is manually inlined in
12493 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012494 _Py_IDENTIFIER(__fspath__);
12495 PyObject *func = NULL;
12496 PyObject *path_repr = NULL;
12497
12498 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12499 Py_INCREF(path);
12500 return path;
12501 }
12502
12503 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12504 if (NULL == func) {
12505 return PyErr_Format(PyExc_TypeError,
12506 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012507 "not %.200s",
12508 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012509 }
12510
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012511 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012512 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012513 if (NULL == path_repr) {
12514 return NULL;
12515 }
12516
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012517 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12518 PyErr_Format(PyExc_TypeError,
12519 "expected %.200s.__fspath__() to return str or bytes, "
12520 "not %.200s", Py_TYPE(path)->tp_name,
12521 Py_TYPE(path_repr)->tp_name);
12522 Py_DECREF(path_repr);
12523 return NULL;
12524 }
12525
Ethan Furman410ef8e2016-06-04 12:06:26 -070012526 return path_repr;
12527}
12528
12529/*[clinic input]
12530os.fspath
12531
12532 path: object
12533
12534Return the file system path representation of the object.
12535
Brett Cannonb4f43e92016-06-09 14:32:08 -070012536If the object is str or bytes, then allow it to pass through as-is. If the
12537object defines __fspath__(), then return the result of that method. All other
12538types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012539[clinic start generated code]*/
12540
12541static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012542os_fspath_impl(PyObject *module, PyObject *path)
12543/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012544{
12545 return PyOS_FSPath(path);
12546}
Victor Stinner6036e442015-03-08 01:58:04 +010012547
Victor Stinner9b1f4742016-09-06 16:18:52 -070012548#ifdef HAVE_GETRANDOM_SYSCALL
12549/*[clinic input]
12550os.getrandom
12551
12552 size: Py_ssize_t
12553 flags: int=0
12554
12555Obtain a series of random bytes.
12556[clinic start generated code]*/
12557
12558static PyObject *
12559os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12560/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12561{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012562 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012563 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012564
12565 if (size < 0) {
12566 errno = EINVAL;
12567 return posix_error();
12568 }
12569
Victor Stinnerec2319c2016-09-20 23:00:59 +020012570 bytes = PyBytes_FromStringAndSize(NULL, size);
12571 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012572 PyErr_NoMemory();
12573 return NULL;
12574 }
12575
12576 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012577 n = syscall(SYS_getrandom,
12578 PyBytes_AS_STRING(bytes),
12579 PyBytes_GET_SIZE(bytes),
12580 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012581 if (n < 0 && errno == EINTR) {
12582 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012583 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012584 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012585
12586 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012587 continue;
12588 }
12589 break;
12590 }
12591
12592 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012593 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012594 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012595 }
12596
Victor Stinnerec2319c2016-09-20 23:00:59 +020012597 if (n != size) {
12598 _PyBytes_Resize(&bytes, n);
12599 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012600
12601 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012602
12603error:
12604 Py_DECREF(bytes);
12605 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012606}
12607#endif /* HAVE_GETRANDOM_SYSCALL */
12608
Larry Hastings31826802013-10-19 00:09:25 -070012609
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012610static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012611
12612 OS_STAT_METHODDEF
12613 OS_ACCESS_METHODDEF
12614 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012615 OS_CHDIR_METHODDEF
12616 OS_CHFLAGS_METHODDEF
12617 OS_CHMOD_METHODDEF
12618 OS_FCHMOD_METHODDEF
12619 OS_LCHMOD_METHODDEF
12620 OS_CHOWN_METHODDEF
12621 OS_FCHOWN_METHODDEF
12622 OS_LCHOWN_METHODDEF
12623 OS_LCHFLAGS_METHODDEF
12624 OS_CHROOT_METHODDEF
12625 OS_CTERMID_METHODDEF
12626 OS_GETCWD_METHODDEF
12627 OS_GETCWDB_METHODDEF
12628 OS_LINK_METHODDEF
12629 OS_LISTDIR_METHODDEF
12630 OS_LSTAT_METHODDEF
12631 OS_MKDIR_METHODDEF
12632 OS_NICE_METHODDEF
12633 OS_GETPRIORITY_METHODDEF
12634 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012635#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012636 {"readlink", (PyCFunction)posix_readlink,
12637 METH_VARARGS | METH_KEYWORDS,
12638 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012639#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012640#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012641 {"readlink", (PyCFunction)win_readlink,
12642 METH_VARARGS | METH_KEYWORDS,
12643 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012644#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012645 OS_RENAME_METHODDEF
12646 OS_REPLACE_METHODDEF
12647 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012648 OS_SYMLINK_METHODDEF
12649 OS_SYSTEM_METHODDEF
12650 OS_UMASK_METHODDEF
12651 OS_UNAME_METHODDEF
12652 OS_UNLINK_METHODDEF
12653 OS_REMOVE_METHODDEF
12654 OS_UTIME_METHODDEF
12655 OS_TIMES_METHODDEF
12656 OS__EXIT_METHODDEF
12657 OS_EXECV_METHODDEF
12658 OS_EXECVE_METHODDEF
12659 OS_SPAWNV_METHODDEF
12660 OS_SPAWNVE_METHODDEF
12661 OS_FORK1_METHODDEF
12662 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012663 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012664 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12665 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12666 OS_SCHED_GETPARAM_METHODDEF
12667 OS_SCHED_GETSCHEDULER_METHODDEF
12668 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12669 OS_SCHED_SETPARAM_METHODDEF
12670 OS_SCHED_SETSCHEDULER_METHODDEF
12671 OS_SCHED_YIELD_METHODDEF
12672 OS_SCHED_SETAFFINITY_METHODDEF
12673 OS_SCHED_GETAFFINITY_METHODDEF
12674 OS_OPENPTY_METHODDEF
12675 OS_FORKPTY_METHODDEF
12676 OS_GETEGID_METHODDEF
12677 OS_GETEUID_METHODDEF
12678 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012679#ifdef HAVE_GETGROUPLIST
12680 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12681#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012682 OS_GETGROUPS_METHODDEF
12683 OS_GETPID_METHODDEF
12684 OS_GETPGRP_METHODDEF
12685 OS_GETPPID_METHODDEF
12686 OS_GETUID_METHODDEF
12687 OS_GETLOGIN_METHODDEF
12688 OS_KILL_METHODDEF
12689 OS_KILLPG_METHODDEF
12690 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012691#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012692 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012693#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012694 OS_SETUID_METHODDEF
12695 OS_SETEUID_METHODDEF
12696 OS_SETREUID_METHODDEF
12697 OS_SETGID_METHODDEF
12698 OS_SETEGID_METHODDEF
12699 OS_SETREGID_METHODDEF
12700 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012701#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012702 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012703#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012704 OS_GETPGID_METHODDEF
12705 OS_SETPGRP_METHODDEF
12706 OS_WAIT_METHODDEF
12707 OS_WAIT3_METHODDEF
12708 OS_WAIT4_METHODDEF
12709 OS_WAITID_METHODDEF
12710 OS_WAITPID_METHODDEF
12711 OS_GETSID_METHODDEF
12712 OS_SETSID_METHODDEF
12713 OS_SETPGID_METHODDEF
12714 OS_TCGETPGRP_METHODDEF
12715 OS_TCSETPGRP_METHODDEF
12716 OS_OPEN_METHODDEF
12717 OS_CLOSE_METHODDEF
12718 OS_CLOSERANGE_METHODDEF
12719 OS_DEVICE_ENCODING_METHODDEF
12720 OS_DUP_METHODDEF
12721 OS_DUP2_METHODDEF
12722 OS_LOCKF_METHODDEF
12723 OS_LSEEK_METHODDEF
12724 OS_READ_METHODDEF
12725 OS_READV_METHODDEF
12726 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012727 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012728 OS_WRITE_METHODDEF
12729 OS_WRITEV_METHODDEF
12730 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012731 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012732#ifdef HAVE_SENDFILE
12733 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12734 posix_sendfile__doc__},
12735#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012736 OS_FSTAT_METHODDEF
12737 OS_ISATTY_METHODDEF
12738 OS_PIPE_METHODDEF
12739 OS_PIPE2_METHODDEF
12740 OS_MKFIFO_METHODDEF
12741 OS_MKNOD_METHODDEF
12742 OS_MAJOR_METHODDEF
12743 OS_MINOR_METHODDEF
12744 OS_MAKEDEV_METHODDEF
12745 OS_FTRUNCATE_METHODDEF
12746 OS_TRUNCATE_METHODDEF
12747 OS_POSIX_FALLOCATE_METHODDEF
12748 OS_POSIX_FADVISE_METHODDEF
12749 OS_PUTENV_METHODDEF
12750 OS_UNSETENV_METHODDEF
12751 OS_STRERROR_METHODDEF
12752 OS_FCHDIR_METHODDEF
12753 OS_FSYNC_METHODDEF
12754 OS_SYNC_METHODDEF
12755 OS_FDATASYNC_METHODDEF
12756 OS_WCOREDUMP_METHODDEF
12757 OS_WIFCONTINUED_METHODDEF
12758 OS_WIFSTOPPED_METHODDEF
12759 OS_WIFSIGNALED_METHODDEF
12760 OS_WIFEXITED_METHODDEF
12761 OS_WEXITSTATUS_METHODDEF
12762 OS_WTERMSIG_METHODDEF
12763 OS_WSTOPSIG_METHODDEF
12764 OS_FSTATVFS_METHODDEF
12765 OS_STATVFS_METHODDEF
12766 OS_CONFSTR_METHODDEF
12767 OS_SYSCONF_METHODDEF
12768 OS_FPATHCONF_METHODDEF
12769 OS_PATHCONF_METHODDEF
12770 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012771 OS__GETFULLPATHNAME_METHODDEF
12772 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012773 OS__GETDISKUSAGE_METHODDEF
12774 OS__GETFINALPATHNAME_METHODDEF
12775 OS__GETVOLUMEPATHNAME_METHODDEF
12776 OS_GETLOADAVG_METHODDEF
12777 OS_URANDOM_METHODDEF
12778 OS_SETRESUID_METHODDEF
12779 OS_SETRESGID_METHODDEF
12780 OS_GETRESUID_METHODDEF
12781 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012782
Larry Hastings2f936352014-08-05 14:04:04 +100012783 OS_GETXATTR_METHODDEF
12784 OS_SETXATTR_METHODDEF
12785 OS_REMOVEXATTR_METHODDEF
12786 OS_LISTXATTR_METHODDEF
12787
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012788#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12789 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12790#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012791 OS_CPU_COUNT_METHODDEF
12792 OS_GET_INHERITABLE_METHODDEF
12793 OS_SET_INHERITABLE_METHODDEF
12794 OS_GET_HANDLE_INHERITABLE_METHODDEF
12795 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012796#ifndef MS_WINDOWS
12797 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12798 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12799#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012800 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012801 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012802 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012803 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012804};
12805
12806
Brian Curtin52173d42010-12-02 18:29:18 +000012807#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012808static int
Brian Curtin52173d42010-12-02 18:29:18 +000012809enable_symlink()
12810{
12811 HANDLE tok;
12812 TOKEN_PRIVILEGES tok_priv;
12813 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012814
12815 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012816 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012817
12818 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012819 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012820
12821 tok_priv.PrivilegeCount = 1;
12822 tok_priv.Privileges[0].Luid = luid;
12823 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12824
12825 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12826 sizeof(TOKEN_PRIVILEGES),
12827 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012828 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012829
Brian Curtin3b4499c2010-12-28 14:31:47 +000012830 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12831 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012832}
12833#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12834
Barry Warsaw4a342091996-12-19 23:50:02 +000012835static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012836all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012837{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012838#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012839 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012840#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012841#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012843#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012844#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012846#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012847#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012849#endif
Fred Drakec9680921999-12-13 16:37:25 +000012850#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012852#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012853#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012855#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012856#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012858#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012859#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012861#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012862#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012863 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012864#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012865#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012867#endif
12868#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012870#endif
12871#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012873#endif
12874#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012876#endif
12877#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012879#endif
12880#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012882#endif
12883#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012885#endif
12886#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012888#endif
12889#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012891#endif
12892#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012894#endif
12895#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012897#endif
12898#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012900#endif
12901#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012903#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012904#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012906#endif
12907#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012909#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012910#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012911 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012912#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012913#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012915#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012916#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012917#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012918 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012919#endif
12920#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012922#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012923#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012924#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012925 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012926#endif
12927#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012928 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012929#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012930#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012931 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012932#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012933#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012934 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012935#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012936#ifdef O_TMPFILE
12937 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12938#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012939#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012941#endif
12942#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012943 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012944#endif
12945#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012947#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012948#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012950#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012951#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012953#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012954
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012955
Jesus Cea94363612012-06-22 18:32:07 +020012956#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012957 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012958#endif
12959#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012961#endif
12962
Tim Peters5aa91602002-01-30 05:46:57 +000012963/* MS Windows */
12964#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012965 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012966 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012967#endif
12968#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 /* Optimize for short life (keep in memory). */
12970 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012971 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012972#endif
12973#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012974 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012975 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012976#endif
12977#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012978 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012980#endif
12981#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012983 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012984#endif
12985
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012986/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012987#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012988 /* Send a SIGIO signal whenever input or output
12989 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012991#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012992#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012993 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012994 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012995#endif
12996#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012998 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012999#endif
13000#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013002 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013003#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013004#ifdef O_NOLINKS
13005 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013007#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013008#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013009 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013010 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013011#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013012
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013014#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013016#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013017#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013019#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013020#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013022#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013023#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013024 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013025#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013026#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013027 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013028#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013029#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013030 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013031#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013032#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013033 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013034#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013035#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013036 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013037#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013038#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013039 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013040#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013041#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013042 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013043#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013044#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013046#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013047#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013048 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013049#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013050#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013051 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013052#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013053#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013054 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013055#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013056#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013057 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013058#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013059#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013060 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013061#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013062#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013063 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013064#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013065
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013066 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013067#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013068 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013069#endif /* ST_RDONLY */
13070#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013071 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013072#endif /* ST_NOSUID */
13073
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013074 /* GNU extensions */
13075#ifdef ST_NODEV
13076 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13077#endif /* ST_NODEV */
13078#ifdef ST_NOEXEC
13079 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13080#endif /* ST_NOEXEC */
13081#ifdef ST_SYNCHRONOUS
13082 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13083#endif /* ST_SYNCHRONOUS */
13084#ifdef ST_MANDLOCK
13085 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13086#endif /* ST_MANDLOCK */
13087#ifdef ST_WRITE
13088 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13089#endif /* ST_WRITE */
13090#ifdef ST_APPEND
13091 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13092#endif /* ST_APPEND */
13093#ifdef ST_NOATIME
13094 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13095#endif /* ST_NOATIME */
13096#ifdef ST_NODIRATIME
13097 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13098#endif /* ST_NODIRATIME */
13099#ifdef ST_RELATIME
13100 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13101#endif /* ST_RELATIME */
13102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013103 /* FreeBSD sendfile() constants */
13104#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013105 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013106#endif
13107#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013108 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013109#endif
13110#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013111 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013112#endif
13113
Ross Lagerwall7807c352011-03-17 20:20:30 +020013114 /* constants for posix_fadvise */
13115#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013116 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013117#endif
13118#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013119 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013120#endif
13121#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013122 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013123#endif
13124#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013125 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013126#endif
13127#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013128 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013129#endif
13130#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013131 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013132#endif
13133
13134 /* constants for waitid */
13135#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013136 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13137 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13138 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013139#endif
13140#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013141 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013142#endif
13143#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013144 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013145#endif
13146#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013147 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013148#endif
13149#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013150 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013151#endif
13152#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013153 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013154#endif
13155#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013156 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013157#endif
13158#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013159 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013160#endif
13161
13162 /* constants for lockf */
13163#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013164 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013165#endif
13166#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013167 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013168#endif
13169#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013170 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013171#endif
13172#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013173 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013174#endif
13175
Pablo Galindo4defba32018-01-27 16:16:37 +000013176#ifdef RWF_DSYNC
13177 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13178#endif
13179#ifdef RWF_HIPRI
13180 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13181#endif
13182#ifdef RWF_SYNC
13183 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13184#endif
13185#ifdef RWF_NOWAIT
13186 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13187#endif
13188
Guido van Rossum246bc171999-02-01 23:54:31 +000013189#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013190 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13191 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13192 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13193 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13194 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013195#endif
13196
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013197#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013198#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013199 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013200#endif
13201#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013202 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013203#endif
13204#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013205 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013206#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013207#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013208 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013209#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013210#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013211 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013212#endif
13213#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013214 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013215#endif
13216#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013217 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013218#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013219#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013220 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013221#endif
13222#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013223 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013224#endif
13225#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013226 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013227#endif
13228#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013229 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013230#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013231#endif
13232
Benjamin Peterson9428d532011-09-14 11:45:52 -040013233#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013234 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13235 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13236 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013237#endif
13238
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013239#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013240 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013241#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013242#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013243 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013244#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013245#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013246 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013247#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013248#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013249 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013250#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013251#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013252 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013253#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013254#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013255 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013256#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013257#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013258 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013259#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013260#if HAVE_DECL_RTLD_MEMBER
13261 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13262#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013263
Victor Stinner9b1f4742016-09-06 16:18:52 -070013264#ifdef HAVE_GETRANDOM_SYSCALL
13265 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13266 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13267#endif
13268
Victor Stinner8c62be82010-05-06 00:08:46 +000013269 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013270}
13271
13272
Martin v. Löwis1a214512008-06-11 05:26:20 +000013273static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013274 PyModuleDef_HEAD_INIT,
13275 MODNAME,
13276 posix__doc__,
13277 -1,
13278 posix_methods,
13279 NULL,
13280 NULL,
13281 NULL,
13282 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013283};
13284
13285
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013286static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013287
13288#ifdef HAVE_FACCESSAT
13289 "HAVE_FACCESSAT",
13290#endif
13291
13292#ifdef HAVE_FCHDIR
13293 "HAVE_FCHDIR",
13294#endif
13295
13296#ifdef HAVE_FCHMOD
13297 "HAVE_FCHMOD",
13298#endif
13299
13300#ifdef HAVE_FCHMODAT
13301 "HAVE_FCHMODAT",
13302#endif
13303
13304#ifdef HAVE_FCHOWN
13305 "HAVE_FCHOWN",
13306#endif
13307
Larry Hastings00964ed2013-08-12 13:49:30 -040013308#ifdef HAVE_FCHOWNAT
13309 "HAVE_FCHOWNAT",
13310#endif
13311
Larry Hastings9cf065c2012-06-22 16:30:09 -070013312#ifdef HAVE_FEXECVE
13313 "HAVE_FEXECVE",
13314#endif
13315
13316#ifdef HAVE_FDOPENDIR
13317 "HAVE_FDOPENDIR",
13318#endif
13319
Georg Brandl306336b2012-06-24 12:55:33 +020013320#ifdef HAVE_FPATHCONF
13321 "HAVE_FPATHCONF",
13322#endif
13323
Larry Hastings9cf065c2012-06-22 16:30:09 -070013324#ifdef HAVE_FSTATAT
13325 "HAVE_FSTATAT",
13326#endif
13327
13328#ifdef HAVE_FSTATVFS
13329 "HAVE_FSTATVFS",
13330#endif
13331
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013332#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013333 "HAVE_FTRUNCATE",
13334#endif
13335
Larry Hastings9cf065c2012-06-22 16:30:09 -070013336#ifdef HAVE_FUTIMENS
13337 "HAVE_FUTIMENS",
13338#endif
13339
13340#ifdef HAVE_FUTIMES
13341 "HAVE_FUTIMES",
13342#endif
13343
13344#ifdef HAVE_FUTIMESAT
13345 "HAVE_FUTIMESAT",
13346#endif
13347
13348#ifdef HAVE_LINKAT
13349 "HAVE_LINKAT",
13350#endif
13351
13352#ifdef HAVE_LCHFLAGS
13353 "HAVE_LCHFLAGS",
13354#endif
13355
13356#ifdef HAVE_LCHMOD
13357 "HAVE_LCHMOD",
13358#endif
13359
13360#ifdef HAVE_LCHOWN
13361 "HAVE_LCHOWN",
13362#endif
13363
13364#ifdef HAVE_LSTAT
13365 "HAVE_LSTAT",
13366#endif
13367
13368#ifdef HAVE_LUTIMES
13369 "HAVE_LUTIMES",
13370#endif
13371
13372#ifdef HAVE_MKDIRAT
13373 "HAVE_MKDIRAT",
13374#endif
13375
13376#ifdef HAVE_MKFIFOAT
13377 "HAVE_MKFIFOAT",
13378#endif
13379
13380#ifdef HAVE_MKNODAT
13381 "HAVE_MKNODAT",
13382#endif
13383
13384#ifdef HAVE_OPENAT
13385 "HAVE_OPENAT",
13386#endif
13387
13388#ifdef HAVE_READLINKAT
13389 "HAVE_READLINKAT",
13390#endif
13391
13392#ifdef HAVE_RENAMEAT
13393 "HAVE_RENAMEAT",
13394#endif
13395
13396#ifdef HAVE_SYMLINKAT
13397 "HAVE_SYMLINKAT",
13398#endif
13399
13400#ifdef HAVE_UNLINKAT
13401 "HAVE_UNLINKAT",
13402#endif
13403
13404#ifdef HAVE_UTIMENSAT
13405 "HAVE_UTIMENSAT",
13406#endif
13407
13408#ifdef MS_WINDOWS
13409 "MS_WINDOWS",
13410#endif
13411
13412 NULL
13413};
13414
13415
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013416PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013417INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013418{
Victor Stinner8c62be82010-05-06 00:08:46 +000013419 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013420 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013421 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013422
Brian Curtin52173d42010-12-02 18:29:18 +000013423#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013424 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013425#endif
13426
Victor Stinner8c62be82010-05-06 00:08:46 +000013427 m = PyModule_Create(&posixmodule);
13428 if (m == NULL)
13429 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013430
Victor Stinner8c62be82010-05-06 00:08:46 +000013431 /* Initialize environ dictionary */
13432 v = convertenviron();
13433 Py_XINCREF(v);
13434 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13435 return NULL;
13436 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013437
Victor Stinner8c62be82010-05-06 00:08:46 +000013438 if (all_ins(m))
13439 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013440
Victor Stinner8c62be82010-05-06 00:08:46 +000013441 if (setup_confname_tables(m))
13442 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013443
Victor Stinner8c62be82010-05-06 00:08:46 +000013444 Py_INCREF(PyExc_OSError);
13445 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013446
Guido van Rossumb3d39562000-01-31 18:41:26 +000013447#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013448 if (posix_putenv_garbage == NULL)
13449 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013450#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013451
Victor Stinner8c62be82010-05-06 00:08:46 +000013452 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013453#if defined(HAVE_WAITID) && !defined(__APPLE__)
13454 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013455 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13456 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013457#endif
13458
Christian Heimes25827622013-10-12 01:27:08 +020013459 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013460 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13461 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13462 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013463 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13464 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013465 structseq_new = StatResultType.tp_new;
13466 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013467
Christian Heimes25827622013-10-12 01:27:08 +020013468 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013469 if (PyStructSequence_InitType2(&StatVFSResultType,
13470 &statvfs_result_desc) < 0)
13471 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013472#ifdef NEED_TICKS_PER_SECOND
13473# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013474 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013475# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013476 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013477# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013478 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013479# endif
13480#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013481
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013482#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013483 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013484 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13485 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013486 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013487#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013488
13489 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013490 if (PyStructSequence_InitType2(&TerminalSizeType,
13491 &TerminalSize_desc) < 0)
13492 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013493
13494 /* initialize scandir types */
13495 if (PyType_Ready(&ScandirIteratorType) < 0)
13496 return NULL;
13497 if (PyType_Ready(&DirEntryType) < 0)
13498 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013499 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013500#if defined(HAVE_WAITID) && !defined(__APPLE__)
13501 Py_INCREF((PyObject*) &WaitidResultType);
13502 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13503#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013504 Py_INCREF((PyObject*) &StatResultType);
13505 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13506 Py_INCREF((PyObject*) &StatVFSResultType);
13507 PyModule_AddObject(m, "statvfs_result",
13508 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013509
13510#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013511 Py_INCREF(&SchedParamType);
13512 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013513#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013514
Larry Hastings605a62d2012-06-24 04:33:36 -070013515 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013516 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13517 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013518 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13519
13520 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013521 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13522 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013523 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13524
Thomas Wouters477c8d52006-05-27 19:21:47 +000013525#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013526 /*
13527 * Step 2 of weak-linking support on Mac OS X.
13528 *
13529 * The code below removes functions that are not available on the
13530 * currently active platform.
13531 *
13532 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013533 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013534 * OSX 10.4.
13535 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013536#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013537 if (fstatvfs == NULL) {
13538 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13539 return NULL;
13540 }
13541 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013542#endif /* HAVE_FSTATVFS */
13543
13544#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013545 if (statvfs == NULL) {
13546 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13547 return NULL;
13548 }
13549 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013550#endif /* HAVE_STATVFS */
13551
13552# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013553 if (lchown == NULL) {
13554 if (PyObject_DelAttrString(m, "lchown") == -1) {
13555 return NULL;
13556 }
13557 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013558#endif /* HAVE_LCHOWN */
13559
13560
13561#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013562
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013563 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013564 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13565
Larry Hastings6fe20b32012-04-19 15:07:49 -070013566 billion = PyLong_FromLong(1000000000);
13567 if (!billion)
13568 return NULL;
13569
Larry Hastings9cf065c2012-06-22 16:30:09 -070013570 /* suppress "function not used" warnings */
13571 {
13572 int ignored;
13573 fd_specified("", -1);
13574 follow_symlinks_specified("", 1);
13575 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13576 dir_fd_converter(Py_None, &ignored);
13577 dir_fd_unavailable(Py_None, &ignored);
13578 }
13579
13580 /*
13581 * provide list of locally available functions
13582 * so os.py can populate support_* lists
13583 */
13584 list = PyList_New(0);
13585 if (!list)
13586 return NULL;
13587 for (trace = have_functions; *trace; trace++) {
13588 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13589 if (!unicode)
13590 return NULL;
13591 if (PyList_Append(list, unicode))
13592 return NULL;
13593 Py_DECREF(unicode);
13594 }
13595 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013596
13597 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013598 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013599
13600 initialized = 1;
13601
Victor Stinner8c62be82010-05-06 00:08:46 +000013602 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013603}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013604
13605#ifdef __cplusplus
13606}
13607#endif