blob: d487e5386e89617e10b3fc60cfcbc37eaae50f69 [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;
4566 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4567 if ((*s == -1) && PyErr_Occurred())
4568 goto exit;
4569 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004570 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004571 goto exit;
4572
4573 result = 1;
4574exit:
4575 Py_XDECREF(divmod);
4576 return result;
4577}
4578
Larry Hastings2f936352014-08-05 14:04:04 +10004579
4580/*[clinic input]
4581os.utime
4582
4583 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4584 times: object = NULL
4585 *
4586 ns: object = NULL
4587 dir_fd: dir_fd(requires='futimensat') = None
4588 follow_symlinks: bool=True
4589
Martin Panter0ff89092015-09-09 01:56:53 +00004590# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004591
4592Set the access and modified time of path.
4593
4594path may always be specified as a string.
4595On some platforms, path may also be specified as an open file descriptor.
4596 If this functionality is unavailable, using it raises an exception.
4597
4598If times is not None, it must be a tuple (atime, mtime);
4599 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004600If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004601 atime_ns and mtime_ns should be expressed as integer nanoseconds
4602 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004603If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004604Specifying tuples for both times and ns is an error.
4605
4606If dir_fd is not None, it should be a file descriptor open to a directory,
4607 and path should be relative; path will then be relative to that directory.
4608If follow_symlinks is False, and the last element of the path is a symbolic
4609 link, utime will modify the symbolic link itself instead of the file the
4610 link points to.
4611It is an error to use dir_fd or follow_symlinks when specifying path
4612 as an open file descriptor.
4613dir_fd and follow_symlinks may not be available on your platform.
4614 If they are unavailable, using them will raise a NotImplementedError.
4615
4616[clinic start generated code]*/
4617
Larry Hastings2f936352014-08-05 14:04:04 +10004618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004619os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4620 int dir_fd, int follow_symlinks)
4621/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004622{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004623#ifdef MS_WINDOWS
4624 HANDLE hFile;
4625 FILETIME atime, mtime;
4626#else
4627 int result;
4628#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004629
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004631 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004632
Christian Heimesb3c87242013-08-01 00:08:16 +02004633 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004634
Larry Hastings9cf065c2012-06-22 16:30:09 -07004635 if (times && (times != Py_None) && ns) {
4636 PyErr_SetString(PyExc_ValueError,
4637 "utime: you may specify either 'times'"
4638 " or 'ns' but not both");
4639 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004640 }
4641
4642 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004643 time_t a_sec, m_sec;
4644 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004645 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 PyErr_SetString(PyExc_TypeError,
4647 "utime: 'times' must be either"
4648 " a tuple of two ints or None");
4649 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004650 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004652 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004653 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004654 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004655 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004656 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004657 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004658 utime.atime_s = a_sec;
4659 utime.atime_ns = a_nsec;
4660 utime.mtime_s = m_sec;
4661 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004662 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004664 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 PyErr_SetString(PyExc_TypeError,
4666 "utime: 'ns' must be a tuple of two ints");
4667 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004669 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004670 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004672 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673 &utime.mtime_s, &utime.mtime_ns)) {
4674 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004675 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004676 }
4677 else {
4678 /* times and ns are both None/unspecified. use "now". */
4679 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004680 }
4681
Victor Stinner4552ced2015-09-21 22:37:15 +02004682#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 if (follow_symlinks_specified("utime", follow_symlinks))
4684 goto exit;
4685#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004686
Larry Hastings2f936352014-08-05 14:04:04 +10004687 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4688 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4689 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004691
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692#if !defined(HAVE_UTIMENSAT)
4693 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004694 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695 "utime: cannot use dir_fd and follow_symlinks "
4696 "together on this platform");
4697 goto exit;
4698 }
4699#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004700
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004701#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004703 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4704 NULL, OPEN_EXISTING,
4705 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 Py_END_ALLOW_THREADS
4707 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004708 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004710 }
4711
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004713 GetSystemTimeAsFileTime(&mtime);
4714 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004715 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004716 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004717 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4718 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004719 }
4720 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4721 /* Avoid putting the file name into the error here,
4722 as that may confuse the user into believing that
4723 something is wrong with the file, when it also
4724 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004725 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004727 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004728#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004730
Victor Stinner4552ced2015-09-21 22:37:15 +02004731#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004733 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004735#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736
Victor Stinner528a9ab2015-09-03 21:30:26 +02004737#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004739 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 else
4741#endif
4742
Victor Stinner528a9ab2015-09-03 21:30:26 +02004743#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004744 if (path->fd != -1)
4745 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 else
4747#endif
4748
Larry Hastings2f936352014-08-05 14:04:04 +10004749 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750
4751 Py_END_ALLOW_THREADS
4752
4753 if (result < 0) {
4754 /* see previous comment about not putting filename in error here */
4755 return_value = posix_error();
4756 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004757 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004758
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004759#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760
4761 Py_INCREF(Py_None);
4762 return_value = Py_None;
4763
4764exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765#ifdef MS_WINDOWS
4766 if (hFile != INVALID_HANDLE_VALUE)
4767 CloseHandle(hFile);
4768#endif
4769 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004770}
4771
Guido van Rossum3b066191991-06-04 19:40:25 +00004772/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004773
Larry Hastings2f936352014-08-05 14:04:04 +10004774
4775/*[clinic input]
4776os._exit
4777
4778 status: int
4779
4780Exit to the system with specified status, without normal exit processing.
4781[clinic start generated code]*/
4782
Larry Hastings2f936352014-08-05 14:04:04 +10004783static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004784os__exit_impl(PyObject *module, int status)
4785/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004786{
4787 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004789}
4790
Steve Dowercc16be82016-09-08 10:35:16 -07004791#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4792#define EXECV_CHAR wchar_t
4793#else
4794#define EXECV_CHAR char
4795#endif
4796
Martin v. Löwis114619e2002-10-07 06:44:21 +00004797#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4798static void
Steve Dowercc16be82016-09-08 10:35:16 -07004799free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004800{
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 Py_ssize_t i;
4802 for (i = 0; i < count; i++)
4803 PyMem_Free(array[i]);
4804 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004805}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004806
Berker Peksag81816462016-09-15 20:19:47 +03004807static int
4808fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004809{
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004811 PyObject *ub;
4812 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004813#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004814 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004815 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004816 *out = PyUnicode_AsWideCharString(ub, &size);
4817 if (*out)
4818 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004819#else
Berker Peksag81816462016-09-15 20:19:47 +03004820 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004822 size = PyBytes_GET_SIZE(ub);
4823 *out = PyMem_Malloc(size + 1);
4824 if (*out) {
4825 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4826 result = 1;
4827 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004828 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004829#endif
Berker Peksag81816462016-09-15 20:19:47 +03004830 Py_DECREF(ub);
4831 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004832}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004833#endif
4834
Ross Lagerwall7807c352011-03-17 20:20:30 +02004835#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004836static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004837parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4838{
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 Py_ssize_t i, pos, envc;
4840 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004841 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004842 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004843
Victor Stinner8c62be82010-05-06 00:08:46 +00004844 i = PyMapping_Size(env);
4845 if (i < 0)
4846 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004847 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 if (envlist == NULL) {
4849 PyErr_NoMemory();
4850 return NULL;
4851 }
4852 envc = 0;
4853 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004854 if (!keys)
4855 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004857 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 goto error;
4859 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4860 PyErr_Format(PyExc_TypeError,
4861 "env.keys() or env.values() is not a list");
4862 goto error;
4863 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004864
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 for (pos = 0; pos < i; pos++) {
4866 key = PyList_GetItem(keys, pos);
4867 val = PyList_GetItem(vals, pos);
4868 if (!key || !val)
4869 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004870
Berker Peksag81816462016-09-15 20:19:47 +03004871#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4872 if (!PyUnicode_FSDecoder(key, &key2))
4873 goto error;
4874 if (!PyUnicode_FSDecoder(val, &val2)) {
4875 Py_DECREF(key2);
4876 goto error;
4877 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004878 /* Search from index 1 because on Windows starting '=' is allowed for
4879 defining hidden environment variables. */
4880 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4881 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4882 {
4883 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004884 Py_DECREF(key2);
4885 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004886 goto error;
4887 }
Berker Peksag81816462016-09-15 20:19:47 +03004888 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4889#else
4890 if (!PyUnicode_FSConverter(key, &key2))
4891 goto error;
4892 if (!PyUnicode_FSConverter(val, &val2)) {
4893 Py_DECREF(key2);
4894 goto error;
4895 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004896 if (PyBytes_GET_SIZE(key2) == 0 ||
4897 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4898 {
4899 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004900 Py_DECREF(key2);
4901 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004902 goto error;
4903 }
Berker Peksag81816462016-09-15 20:19:47 +03004904 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4905 PyBytes_AS_STRING(val2));
4906#endif
4907 Py_DECREF(key2);
4908 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004909 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004910 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004911
4912 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4913 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 goto error;
4915 }
Berker Peksag81816462016-09-15 20:19:47 +03004916
Steve Dowercc16be82016-09-08 10:35:16 -07004917 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 }
4919 Py_DECREF(vals);
4920 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004921
Victor Stinner8c62be82010-05-06 00:08:46 +00004922 envlist[envc] = 0;
4923 *envc_ptr = envc;
4924 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004925
4926error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 Py_XDECREF(keys);
4928 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004929 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004931}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Steve Dowercc16be82016-09-08 10:35:16 -07004933static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004934parse_arglist(PyObject* argv, Py_ssize_t *argc)
4935{
4936 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004937 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004938 if (argvlist == NULL) {
4939 PyErr_NoMemory();
4940 return NULL;
4941 }
4942 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004943 PyObject* item = PySequence_ITEM(argv, i);
4944 if (item == NULL)
4945 goto fail;
4946 if (!fsconvert_strdup(item, &argvlist[i])) {
4947 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004948 goto fail;
4949 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004950 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004951 }
4952 argvlist[*argc] = NULL;
4953 return argvlist;
4954fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004955 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956 free_string_array(argvlist, *argc);
4957 return NULL;
4958}
Steve Dowercc16be82016-09-08 10:35:16 -07004959
Ross Lagerwall7807c352011-03-17 20:20:30 +02004960#endif
4961
Larry Hastings2f936352014-08-05 14:04:04 +10004962
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004964/*[clinic input]
4965os.execv
4966
Steve Dowercc16be82016-09-08 10:35:16 -07004967 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004968 Path of executable file.
4969 argv: object
4970 Tuple or list of strings.
4971 /
4972
4973Execute an executable path with arguments, replacing current process.
4974[clinic start generated code]*/
4975
Larry Hastings2f936352014-08-05 14:04:04 +10004976static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004977os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4978/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004979{
Steve Dowercc16be82016-09-08 10:35:16 -07004980 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004981 Py_ssize_t argc;
4982
4983 /* execv has two arguments: (path, argv), where
4984 argv is a list or tuple of strings. */
4985
Ross Lagerwall7807c352011-03-17 20:20:30 +02004986 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4987 PyErr_SetString(PyExc_TypeError,
4988 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004989 return NULL;
4990 }
4991 argc = PySequence_Size(argv);
4992 if (argc < 1) {
4993 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004994 return NULL;
4995 }
4996
4997 argvlist = parse_arglist(argv, &argc);
4998 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999 return NULL;
5000 }
Steve Dowerbce26262016-11-19 19:17:26 -08005001 if (!argvlist[0][0]) {
5002 PyErr_SetString(PyExc_ValueError,
5003 "execv() arg 2 first element cannot be empty");
5004 free_string_array(argvlist, argc);
5005 return NULL;
5006 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005007
Steve Dowerbce26262016-11-19 19:17:26 -08005008 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005009#ifdef HAVE_WEXECV
5010 _wexecv(path->wide, argvlist);
5011#else
5012 execv(path->narrow, argvlist);
5013#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005014 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015
5016 /* If we get here it's definitely an error */
5017
5018 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019 return posix_error();
5020}
5021
Larry Hastings2f936352014-08-05 14:04:04 +10005022
5023/*[clinic input]
5024os.execve
5025
5026 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5027 Path of executable file.
5028 argv: object
5029 Tuple or list of strings.
5030 env: object
5031 Dictionary of strings mapping to strings.
5032
5033Execute an executable path with arguments, replacing current process.
5034[clinic start generated code]*/
5035
Larry Hastings2f936352014-08-05 14:04:04 +10005036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005037os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5038/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005039{
Steve Dowercc16be82016-09-08 10:35:16 -07005040 EXECV_CHAR **argvlist = NULL;
5041 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005042 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005043
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 /* execve has three arguments: (path, argv, env), where
5045 argv is a list or tuple of strings and env is a dictionary
5046 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005047
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005050 "execve: argv must be a tuple or list");
5051 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005052 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005054 if (argc < 1) {
5055 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5056 return NULL;
5057 }
5058
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 if (!PyMapping_Check(env)) {
5060 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005061 "execve: environment must be a mapping object");
5062 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005064
Ross Lagerwall7807c352011-03-17 20:20:30 +02005065 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005067 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 }
Steve Dowerbce26262016-11-19 19:17:26 -08005069 if (!argvlist[0][0]) {
5070 PyErr_SetString(PyExc_ValueError,
5071 "execve: argv first element cannot be empty");
5072 goto fail;
5073 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005074
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 envlist = parse_envlist(env, &envc);
5076 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005077 goto fail;
5078
Steve Dowerbce26262016-11-19 19:17:26 -08005079 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005080#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005081 if (path->fd > -1)
5082 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005083 else
5084#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005085#ifdef HAVE_WEXECV
5086 _wexecve(path->wide, argvlist, envlist);
5087#else
Larry Hastings2f936352014-08-05 14:04:04 +10005088 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005089#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005090 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005091
5092 /* If we get here it's definitely an error */
5093
Larry Hastings2f936352014-08-05 14:04:04 +10005094 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005095
Steve Dowercc16be82016-09-08 10:35:16 -07005096 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005098 if (argvlist)
5099 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005100 return NULL;
5101}
Steve Dowercc16be82016-09-08 10:35:16 -07005102
Larry Hastings9cf065c2012-06-22 16:30:09 -07005103#endif /* HAVE_EXECV */
5104
Steve Dowercc16be82016-09-08 10:35:16 -07005105#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005106/*[clinic input]
5107os.spawnv
5108
5109 mode: int
5110 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005111 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005112 Path of executable file.
5113 argv: object
5114 Tuple or list of strings.
5115 /
5116
5117Execute the program specified by path in a new process.
5118[clinic start generated code]*/
5119
Larry Hastings2f936352014-08-05 14:04:04 +10005120static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005121os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5122/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005123{
Steve Dowercc16be82016-09-08 10:35:16 -07005124 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005125 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005127 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005129
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 /* spawnv has three arguments: (mode, path, argv), where
5131 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005132
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 if (PyList_Check(argv)) {
5134 argc = PyList_Size(argv);
5135 getitem = PyList_GetItem;
5136 }
5137 else if (PyTuple_Check(argv)) {
5138 argc = PyTuple_Size(argv);
5139 getitem = PyTuple_GetItem;
5140 }
5141 else {
5142 PyErr_SetString(PyExc_TypeError,
5143 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 return NULL;
5145 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005146 if (argc == 0) {
5147 PyErr_SetString(PyExc_ValueError,
5148 "spawnv() arg 2 cannot be empty");
5149 return NULL;
5150 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005151
Steve Dowercc16be82016-09-08 10:35:16 -07005152 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 return PyErr_NoMemory();
5155 }
5156 for (i = 0; i < argc; i++) {
5157 if (!fsconvert_strdup((*getitem)(argv, i),
5158 &argvlist[i])) {
5159 free_string_array(argvlist, i);
5160 PyErr_SetString(
5161 PyExc_TypeError,
5162 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 return NULL;
5164 }
Steve Dower93ff8722016-11-19 19:03:54 -08005165 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005166 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005167 PyErr_SetString(
5168 PyExc_ValueError,
5169 "spawnv() arg 2 first element cannot be empty");
5170 return NULL;
5171 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 }
5173 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005174
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 if (mode == _OLD_P_OVERLAY)
5176 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005177
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005179 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005180#ifdef HAVE_WSPAWNV
5181 spawnval = _wspawnv(mode, path->wide, argvlist);
5182#else
5183 spawnval = _spawnv(mode, path->narrow, argvlist);
5184#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005185 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005187
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005189
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 if (spawnval == -1)
5191 return posix_error();
5192 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005193 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005194}
5195
Larry Hastings2f936352014-08-05 14:04:04 +10005196/*[clinic input]
5197os.spawnve
5198
5199 mode: int
5200 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005201 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005202 Path of executable file.
5203 argv: object
5204 Tuple or list of strings.
5205 env: object
5206 Dictionary of strings mapping to strings.
5207 /
5208
5209Execute the program specified by path in a new process.
5210[clinic start generated code]*/
5211
Larry Hastings2f936352014-08-05 14:04:04 +10005212static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005213os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005214 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005215/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005216{
Steve Dowercc16be82016-09-08 10:35:16 -07005217 EXECV_CHAR **argvlist;
5218 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005220 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005221 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005223 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005224
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 /* spawnve has four arguments: (mode, path, argv, env), where
5226 argv is a list or tuple of strings and env is a dictionary
5227 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005228
Victor Stinner8c62be82010-05-06 00:08:46 +00005229 if (PyList_Check(argv)) {
5230 argc = PyList_Size(argv);
5231 getitem = PyList_GetItem;
5232 }
5233 else if (PyTuple_Check(argv)) {
5234 argc = PyTuple_Size(argv);
5235 getitem = PyTuple_GetItem;
5236 }
5237 else {
5238 PyErr_SetString(PyExc_TypeError,
5239 "spawnve() arg 2 must be a tuple or list");
5240 goto fail_0;
5241 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005242 if (argc == 0) {
5243 PyErr_SetString(PyExc_ValueError,
5244 "spawnve() arg 2 cannot be empty");
5245 goto fail_0;
5246 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 if (!PyMapping_Check(env)) {
5248 PyErr_SetString(PyExc_TypeError,
5249 "spawnve() arg 3 must be a mapping object");
5250 goto fail_0;
5251 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005252
Steve Dowercc16be82016-09-08 10:35:16 -07005253 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005254 if (argvlist == NULL) {
5255 PyErr_NoMemory();
5256 goto fail_0;
5257 }
5258 for (i = 0; i < argc; i++) {
5259 if (!fsconvert_strdup((*getitem)(argv, i),
5260 &argvlist[i]))
5261 {
5262 lastarg = i;
5263 goto fail_1;
5264 }
Steve Dowerbce26262016-11-19 19:17:26 -08005265 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005266 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005267 PyErr_SetString(
5268 PyExc_ValueError,
5269 "spawnv() arg 2 first element cannot be empty");
5270 goto fail_1;
5271 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 }
5273 lastarg = argc;
5274 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005275
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 envlist = parse_envlist(env, &envc);
5277 if (envlist == NULL)
5278 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005279
Victor Stinner8c62be82010-05-06 00:08:46 +00005280 if (mode == _OLD_P_OVERLAY)
5281 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005282
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005284 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005285#ifdef HAVE_WSPAWNV
5286 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5287#else
5288 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5289#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005290 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005292
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 if (spawnval == -1)
5294 (void) posix_error();
5295 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005296 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005297
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 while (--envc >= 0)
5299 PyMem_DEL(envlist[envc]);
5300 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005301 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005302 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005303 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005305}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005306
Guido van Rossuma1065681999-01-25 23:20:23 +00005307#endif /* HAVE_SPAWNV */
5308
5309
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005310#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005311
5312/* Helper function to validate arguments.
5313 Returns 0 on success. non-zero on failure with a TypeError raised.
5314 If obj is non-NULL it must be callable. */
5315static int
5316check_null_or_callable(PyObject *obj, const char* obj_name)
5317{
5318 if (obj && !PyCallable_Check(obj)) {
5319 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5320 obj_name, Py_TYPE(obj)->tp_name);
5321 return -1;
5322 }
5323 return 0;
5324}
5325
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005326/*[clinic input]
5327os.register_at_fork
5328
Gregory P. Smith163468a2017-05-29 10:03:41 -07005329 *
5330 before: object=NULL
5331 A callable to be called in the parent before the fork() syscall.
5332 after_in_child: object=NULL
5333 A callable to be called in the child after fork().
5334 after_in_parent: object=NULL
5335 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005336
Gregory P. Smith163468a2017-05-29 10:03:41 -07005337Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005338
Gregory P. Smith163468a2017-05-29 10:03:41 -07005339'before' callbacks are called in reverse order.
5340'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005341
5342[clinic start generated code]*/
5343
5344static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005345os_register_at_fork_impl(PyObject *module, PyObject *before,
5346 PyObject *after_in_child, PyObject *after_in_parent)
5347/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005348{
5349 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005350
Gregory P. Smith163468a2017-05-29 10:03:41 -07005351 if (!before && !after_in_child && !after_in_parent) {
5352 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5353 return NULL;
5354 }
5355 if (check_null_or_callable(before, "before") ||
5356 check_null_or_callable(after_in_child, "after_in_child") ||
5357 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005358 return NULL;
5359 }
5360 interp = PyThreadState_Get()->interp;
5361
Gregory P. Smith163468a2017-05-29 10:03:41 -07005362 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005363 return NULL;
5364 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005365 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005366 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005367 }
5368 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5369 return NULL;
5370 }
5371 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005372}
5373#endif /* HAVE_FORK */
5374
5375
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005376#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005377/*[clinic input]
5378os.fork1
5379
5380Fork a child process with a single multiplexed (i.e., not bound) thread.
5381
5382Return 0 to child process and PID of child to parent process.
5383[clinic start generated code]*/
5384
Larry Hastings2f936352014-08-05 14:04:04 +10005385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005386os_fork1_impl(PyObject *module)
5387/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005388{
Victor Stinner8c62be82010-05-06 00:08:46 +00005389 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005390
5391 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 pid = fork1();
5393 if (pid == 0) {
5394 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005395 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005396 } else {
5397 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005398 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 }
5400 if (pid == -1)
5401 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005403}
Larry Hastings2f936352014-08-05 14:04:04 +10005404#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005405
5406
Guido van Rossumad0ee831995-03-01 10:34:45 +00005407#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005408/*[clinic input]
5409os.fork
5410
5411Fork a child process.
5412
5413Return 0 to child process and PID of child to parent process.
5414[clinic start generated code]*/
5415
Larry Hastings2f936352014-08-05 14:04:04 +10005416static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005417os_fork_impl(PyObject *module)
5418/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005419{
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005421
5422 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 pid = fork();
5424 if (pid == 0) {
5425 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005426 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005427 } else {
5428 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005429 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005430 }
5431 if (pid == -1)
5432 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005433 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005434}
Larry Hastings2f936352014-08-05 14:04:04 +10005435#endif /* HAVE_FORK */
5436
Guido van Rossum85e3b011991-06-03 12:42:10 +00005437
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005438#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005439#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005440/*[clinic input]
5441os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005442
Larry Hastings2f936352014-08-05 14:04:04 +10005443 policy: int
5444
5445Get the maximum scheduling priority for policy.
5446[clinic start generated code]*/
5447
Larry Hastings2f936352014-08-05 14:04:04 +10005448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005449os_sched_get_priority_max_impl(PyObject *module, int policy)
5450/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005451{
5452 int max;
5453
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005454 max = sched_get_priority_max(policy);
5455 if (max < 0)
5456 return posix_error();
5457 return PyLong_FromLong(max);
5458}
5459
Larry Hastings2f936352014-08-05 14:04:04 +10005460
5461/*[clinic input]
5462os.sched_get_priority_min
5463
5464 policy: int
5465
5466Get the minimum scheduling priority for policy.
5467[clinic start generated code]*/
5468
Larry Hastings2f936352014-08-05 14:04:04 +10005469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005470os_sched_get_priority_min_impl(PyObject *module, int policy)
5471/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005472{
5473 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005474 if (min < 0)
5475 return posix_error();
5476 return PyLong_FromLong(min);
5477}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005478#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5479
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005480
Larry Hastings2f936352014-08-05 14:04:04 +10005481#ifdef HAVE_SCHED_SETSCHEDULER
5482/*[clinic input]
5483os.sched_getscheduler
5484 pid: pid_t
5485 /
5486
5487Get the scheduling policy for the process identifiedy by pid.
5488
5489Passing 0 for pid returns the scheduling policy for the calling process.
5490[clinic start generated code]*/
5491
Larry Hastings2f936352014-08-05 14:04:04 +10005492static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005493os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5494/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005495{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496 int policy;
5497
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005498 policy = sched_getscheduler(pid);
5499 if (policy < 0)
5500 return posix_error();
5501 return PyLong_FromLong(policy);
5502}
Larry Hastings2f936352014-08-05 14:04:04 +10005503#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005504
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005505
5506#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005507/*[clinic input]
5508class os.sched_param "PyObject *" "&SchedParamType"
5509
5510@classmethod
5511os.sched_param.__new__
5512
5513 sched_priority: object
5514 A scheduling parameter.
5515
5516Current has only one field: sched_priority");
5517[clinic start generated code]*/
5518
Larry Hastings2f936352014-08-05 14:04:04 +10005519static PyObject *
5520os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005521/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005522{
5523 PyObject *res;
5524
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005525 res = PyStructSequence_New(type);
5526 if (!res)
5527 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005528 Py_INCREF(sched_priority);
5529 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005530 return res;
5531}
5532
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005533
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005534PyDoc_VAR(os_sched_param__doc__);
5535
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005536static PyStructSequence_Field sched_param_fields[] = {
5537 {"sched_priority", "the scheduling priority"},
5538 {0}
5539};
5540
5541static PyStructSequence_Desc sched_param_desc = {
5542 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005543 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005544 sched_param_fields,
5545 1
5546};
5547
5548static int
5549convert_sched_param(PyObject *param, struct sched_param *res)
5550{
5551 long priority;
5552
5553 if (Py_TYPE(param) != &SchedParamType) {
5554 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5555 return 0;
5556 }
5557 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5558 if (priority == -1 && PyErr_Occurred())
5559 return 0;
5560 if (priority > INT_MAX || priority < INT_MIN) {
5561 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5562 return 0;
5563 }
5564 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5565 return 1;
5566}
Larry Hastings2f936352014-08-05 14:04:04 +10005567#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005568
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005569
5570#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005571/*[clinic input]
5572os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005573
Larry Hastings2f936352014-08-05 14:04:04 +10005574 pid: pid_t
5575 policy: int
5576 param: sched_param
5577 /
5578
5579Set the scheduling policy for the process identified by pid.
5580
5581If pid is 0, the calling process is changed.
5582param is an instance of sched_param.
5583[clinic start generated code]*/
5584
Larry Hastings2f936352014-08-05 14:04:04 +10005585static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005586os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005587 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005588/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005589{
Jesus Cea9c822272011-09-10 01:40:52 +02005590 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005591 ** sched_setscheduler() returns 0 in Linux, but the previous
5592 ** scheduling policy under Solaris/Illumos, and others.
5593 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005594 */
Larry Hastings2f936352014-08-05 14:04:04 +10005595 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005596 return posix_error();
5597 Py_RETURN_NONE;
5598}
Larry Hastings2f936352014-08-05 14:04:04 +10005599#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005600
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005601
5602#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005603/*[clinic input]
5604os.sched_getparam
5605 pid: pid_t
5606 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005607
Larry Hastings2f936352014-08-05 14:04:04 +10005608Returns scheduling parameters for the process identified by pid.
5609
5610If pid is 0, returns parameters for the calling process.
5611Return value is an instance of sched_param.
5612[clinic start generated code]*/
5613
Larry Hastings2f936352014-08-05 14:04:04 +10005614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005615os_sched_getparam_impl(PyObject *module, pid_t pid)
5616/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005617{
5618 struct sched_param param;
5619 PyObject *result;
5620 PyObject *priority;
5621
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005622 if (sched_getparam(pid, &param))
5623 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005624 result = PyStructSequence_New(&SchedParamType);
5625 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005626 return NULL;
5627 priority = PyLong_FromLong(param.sched_priority);
5628 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005629 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005630 return NULL;
5631 }
Larry Hastings2f936352014-08-05 14:04:04 +10005632 PyStructSequence_SET_ITEM(result, 0, priority);
5633 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005634}
5635
Larry Hastings2f936352014-08-05 14:04:04 +10005636
5637/*[clinic input]
5638os.sched_setparam
5639 pid: pid_t
5640 param: sched_param
5641 /
5642
5643Set scheduling parameters for the process identified by pid.
5644
5645If pid is 0, sets parameters for the calling process.
5646param should be an instance of sched_param.
5647[clinic start generated code]*/
5648
Larry Hastings2f936352014-08-05 14:04:04 +10005649static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005650os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005651 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005652/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005653{
5654 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005655 return posix_error();
5656 Py_RETURN_NONE;
5657}
Larry Hastings2f936352014-08-05 14:04:04 +10005658#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005659
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005660
5661#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005662/*[clinic input]
5663os.sched_rr_get_interval -> double
5664 pid: pid_t
5665 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005666
Larry Hastings2f936352014-08-05 14:04:04 +10005667Return the round-robin quantum for the process identified by pid, in seconds.
5668
5669Value returned is a float.
5670[clinic start generated code]*/
5671
Larry Hastings2f936352014-08-05 14:04:04 +10005672static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005673os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5674/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005675{
5676 struct timespec interval;
5677 if (sched_rr_get_interval(pid, &interval)) {
5678 posix_error();
5679 return -1.0;
5680 }
5681 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5682}
5683#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005684
Larry Hastings2f936352014-08-05 14:04:04 +10005685
5686/*[clinic input]
5687os.sched_yield
5688
5689Voluntarily relinquish the CPU.
5690[clinic start generated code]*/
5691
Larry Hastings2f936352014-08-05 14:04:04 +10005692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005693os_sched_yield_impl(PyObject *module)
5694/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005695{
5696 if (sched_yield())
5697 return posix_error();
5698 Py_RETURN_NONE;
5699}
5700
Benjamin Peterson2740af82011-08-02 17:41:34 -05005701#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005702/* The minimum number of CPUs allocated in a cpu_set_t */
5703static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005704
Larry Hastings2f936352014-08-05 14:04:04 +10005705/*[clinic input]
5706os.sched_setaffinity
5707 pid: pid_t
5708 mask : object
5709 /
5710
5711Set the CPU affinity of the process identified by pid to mask.
5712
5713mask should be an iterable of integers identifying CPUs.
5714[clinic start generated code]*/
5715
Larry Hastings2f936352014-08-05 14:04:04 +10005716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005717os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5718/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005719{
Antoine Pitrou84869872012-08-04 16:16:35 +02005720 int ncpus;
5721 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005722 cpu_set_t *cpu_set = NULL;
5723 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005724
Larry Hastings2f936352014-08-05 14:04:04 +10005725 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005726 if (iterator == NULL)
5727 return NULL;
5728
5729 ncpus = NCPUS_START;
5730 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005731 cpu_set = CPU_ALLOC(ncpus);
5732 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005733 PyErr_NoMemory();
5734 goto error;
5735 }
Larry Hastings2f936352014-08-05 14:04:04 +10005736 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005737
5738 while ((item = PyIter_Next(iterator))) {
5739 long cpu;
5740 if (!PyLong_Check(item)) {
5741 PyErr_Format(PyExc_TypeError,
5742 "expected an iterator of ints, "
5743 "but iterator yielded %R",
5744 Py_TYPE(item));
5745 Py_DECREF(item);
5746 goto error;
5747 }
5748 cpu = PyLong_AsLong(item);
5749 Py_DECREF(item);
5750 if (cpu < 0) {
5751 if (!PyErr_Occurred())
5752 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5753 goto error;
5754 }
5755 if (cpu > INT_MAX - 1) {
5756 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5757 goto error;
5758 }
5759 if (cpu >= ncpus) {
5760 /* Grow CPU mask to fit the CPU number */
5761 int newncpus = ncpus;
5762 cpu_set_t *newmask;
5763 size_t newsetsize;
5764 while (newncpus <= cpu) {
5765 if (newncpus > INT_MAX / 2)
5766 newncpus = cpu + 1;
5767 else
5768 newncpus = newncpus * 2;
5769 }
5770 newmask = CPU_ALLOC(newncpus);
5771 if (newmask == NULL) {
5772 PyErr_NoMemory();
5773 goto error;
5774 }
5775 newsetsize = CPU_ALLOC_SIZE(newncpus);
5776 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005777 memcpy(newmask, cpu_set, setsize);
5778 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005779 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005780 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005781 ncpus = newncpus;
5782 }
Larry Hastings2f936352014-08-05 14:04:04 +10005783 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005784 }
5785 Py_CLEAR(iterator);
5786
Larry Hastings2f936352014-08-05 14:04:04 +10005787 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005788 posix_error();
5789 goto error;
5790 }
Larry Hastings2f936352014-08-05 14:04:04 +10005791 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005792 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005793
5794error:
Larry Hastings2f936352014-08-05 14:04:04 +10005795 if (cpu_set)
5796 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005797 Py_XDECREF(iterator);
5798 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005799}
5800
Larry Hastings2f936352014-08-05 14:04:04 +10005801
5802/*[clinic input]
5803os.sched_getaffinity
5804 pid: pid_t
5805 /
5806
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005807Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005808
5809The affinity is returned as a set of CPU identifiers.
5810[clinic start generated code]*/
5811
Larry Hastings2f936352014-08-05 14:04:04 +10005812static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005813os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005814/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005815{
Antoine Pitrou84869872012-08-04 16:16:35 +02005816 int cpu, ncpus, count;
5817 size_t setsize;
5818 cpu_set_t *mask = NULL;
5819 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005820
Antoine Pitrou84869872012-08-04 16:16:35 +02005821 ncpus = NCPUS_START;
5822 while (1) {
5823 setsize = CPU_ALLOC_SIZE(ncpus);
5824 mask = CPU_ALLOC(ncpus);
5825 if (mask == NULL)
5826 return PyErr_NoMemory();
5827 if (sched_getaffinity(pid, setsize, mask) == 0)
5828 break;
5829 CPU_FREE(mask);
5830 if (errno != EINVAL)
5831 return posix_error();
5832 if (ncpus > INT_MAX / 2) {
5833 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5834 "a large enough CPU set");
5835 return NULL;
5836 }
5837 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005838 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005839
5840 res = PySet_New(NULL);
5841 if (res == NULL)
5842 goto error;
5843 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5844 if (CPU_ISSET_S(cpu, setsize, mask)) {
5845 PyObject *cpu_num = PyLong_FromLong(cpu);
5846 --count;
5847 if (cpu_num == NULL)
5848 goto error;
5849 if (PySet_Add(res, cpu_num)) {
5850 Py_DECREF(cpu_num);
5851 goto error;
5852 }
5853 Py_DECREF(cpu_num);
5854 }
5855 }
5856 CPU_FREE(mask);
5857 return res;
5858
5859error:
5860 if (mask)
5861 CPU_FREE(mask);
5862 Py_XDECREF(res);
5863 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005864}
5865
Benjamin Peterson2740af82011-08-02 17:41:34 -05005866#endif /* HAVE_SCHED_SETAFFINITY */
5867
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005868#endif /* HAVE_SCHED_H */
5869
Larry Hastings2f936352014-08-05 14:04:04 +10005870
Neal Norwitzb59798b2003-03-21 01:43:31 +00005871/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005872/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5873#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005874#define DEV_PTY_FILE "/dev/ptc"
5875#define HAVE_DEV_PTMX
5876#else
5877#define DEV_PTY_FILE "/dev/ptmx"
5878#endif
5879
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005880#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005881#ifdef HAVE_PTY_H
5882#include <pty.h>
5883#else
5884#ifdef HAVE_LIBUTIL_H
5885#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005886#else
5887#ifdef HAVE_UTIL_H
5888#include <util.h>
5889#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005890#endif /* HAVE_LIBUTIL_H */
5891#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005892#ifdef HAVE_STROPTS_H
5893#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005894#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005895#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005896
Larry Hastings2f936352014-08-05 14:04:04 +10005897
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005898#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005899/*[clinic input]
5900os.openpty
5901
5902Open a pseudo-terminal.
5903
5904Return a tuple of (master_fd, slave_fd) containing open file descriptors
5905for both the master and slave ends.
5906[clinic start generated code]*/
5907
Larry Hastings2f936352014-08-05 14:04:04 +10005908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005909os_openpty_impl(PyObject *module)
5910/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005911{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005912 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005913#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005915#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005916#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005918#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005920#endif
5921#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005922
Thomas Wouters70c21a12000-07-14 14:28:33 +00005923#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005924 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005925 goto posix_error;
5926
5927 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5928 goto error;
5929 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5930 goto error;
5931
Neal Norwitzb59798b2003-03-21 01:43:31 +00005932#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5934 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005935 goto posix_error;
5936 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5937 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005938
Victor Stinnerdaf45552013-08-28 00:53:59 +02005939 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005941 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005942
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005943#else
Victor Stinner000de532013-11-25 23:19:58 +01005944 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005946 goto posix_error;
5947
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005949
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 /* change permission of slave */
5951 if (grantpt(master_fd) < 0) {
5952 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005955
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 /* unlock slave */
5957 if (unlockpt(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 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005963
Victor Stinner8c62be82010-05-06 00:08:46 +00005964 slave_name = ptsname(master_fd); /* get name of slave */
5965 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005966 goto posix_error;
5967
5968 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005969 if (slave_fd == -1)
5970 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005971
5972 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5973 goto posix_error;
5974
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005975#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5977 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005978#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005980#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005981#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005982#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005983
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005985
Victor Stinnerdaf45552013-08-28 00:53:59 +02005986posix_error:
5987 posix_error();
5988error:
5989 if (master_fd != -1)
5990 close(master_fd);
5991 if (slave_fd != -1)
5992 close(slave_fd);
5993 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005994}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005995#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005996
Larry Hastings2f936352014-08-05 14:04:04 +10005997
Fred Drake8cef4cf2000-06-28 16:40:38 +00005998#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005999/*[clinic input]
6000os.forkpty
6001
6002Fork a new process with a new pseudo-terminal as controlling tty.
6003
6004Returns a tuple of (pid, master_fd).
6005Like fork(), return pid of 0 to the child process,
6006and pid of child to the parent process.
6007To both, return fd of newly opened pseudo-terminal.
6008[clinic start generated code]*/
6009
Larry Hastings2f936352014-08-05 14:04:04 +10006010static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006011os_forkpty_impl(PyObject *module)
6012/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006013{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006014 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006016
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006017 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 pid = forkpty(&master_fd, NULL, NULL, NULL);
6019 if (pid == 0) {
6020 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006021 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006022 } else {
6023 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006024 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 }
6026 if (pid == -1)
6027 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006029}
Larry Hastings2f936352014-08-05 14:04:04 +10006030#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006031
Ross Lagerwall7807c352011-03-17 20:20:30 +02006032
Guido van Rossumad0ee831995-03-01 10:34:45 +00006033#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006034/*[clinic input]
6035os.getegid
6036
6037Return the current process's effective group id.
6038[clinic start generated code]*/
6039
Larry Hastings2f936352014-08-05 14:04:04 +10006040static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006041os_getegid_impl(PyObject *module)
6042/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006043{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006044 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006045}
Larry Hastings2f936352014-08-05 14:04:04 +10006046#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006048
Guido van Rossumad0ee831995-03-01 10:34:45 +00006049#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006050/*[clinic input]
6051os.geteuid
6052
6053Return the current process's effective user id.
6054[clinic start generated code]*/
6055
Larry Hastings2f936352014-08-05 14:04:04 +10006056static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006057os_geteuid_impl(PyObject *module)
6058/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006059{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006060 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006061}
Larry Hastings2f936352014-08-05 14:04:04 +10006062#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006064
Guido van Rossumad0ee831995-03-01 10:34:45 +00006065#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006066/*[clinic input]
6067os.getgid
6068
6069Return the current process's group id.
6070[clinic start generated code]*/
6071
Larry Hastings2f936352014-08-05 14:04:04 +10006072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006073os_getgid_impl(PyObject *module)
6074/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006075{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006076 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006077}
Larry Hastings2f936352014-08-05 14:04:04 +10006078#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006080
Berker Peksag39404992016-09-15 20:45:16 +03006081#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006082/*[clinic input]
6083os.getpid
6084
6085Return the current process id.
6086[clinic start generated code]*/
6087
Larry Hastings2f936352014-08-05 14:04:04 +10006088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006089os_getpid_impl(PyObject *module)
6090/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006091{
Victor Stinner8c62be82010-05-06 00:08:46 +00006092 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006093}
Berker Peksag39404992016-09-15 20:45:16 +03006094#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006095
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006096#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006097
6098/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006099PyDoc_STRVAR(posix_getgrouplist__doc__,
6100"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6101Returns a list of groups to which a user belongs.\n\n\
6102 user: username to lookup\n\
6103 group: base group id of the user");
6104
6105static PyObject *
6106posix_getgrouplist(PyObject *self, PyObject *args)
6107{
6108#ifdef NGROUPS_MAX
6109#define MAX_GROUPS NGROUPS_MAX
6110#else
6111 /* defined to be 16 on Solaris7, so this should be a small number */
6112#define MAX_GROUPS 64
6113#endif
6114
6115 const char *user;
6116 int i, ngroups;
6117 PyObject *list;
6118#ifdef __APPLE__
6119 int *groups, basegid;
6120#else
6121 gid_t *groups, basegid;
6122#endif
6123 ngroups = MAX_GROUPS;
6124
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006125#ifdef __APPLE__
6126 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006127 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006128#else
6129 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6130 _Py_Gid_Converter, &basegid))
6131 return NULL;
6132#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006133
6134#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006135 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006136#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006137 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006138#endif
6139 if (groups == NULL)
6140 return PyErr_NoMemory();
6141
6142 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6143 PyMem_Del(groups);
6144 return posix_error();
6145 }
6146
6147 list = PyList_New(ngroups);
6148 if (list == NULL) {
6149 PyMem_Del(groups);
6150 return NULL;
6151 }
6152
6153 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006154#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006155 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006156#else
6157 PyObject *o = _PyLong_FromGid(groups[i]);
6158#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006159 if (o == NULL) {
6160 Py_DECREF(list);
6161 PyMem_Del(groups);
6162 return NULL;
6163 }
6164 PyList_SET_ITEM(list, i, o);
6165 }
6166
6167 PyMem_Del(groups);
6168
6169 return list;
6170}
Larry Hastings2f936352014-08-05 14:04:04 +10006171#endif /* HAVE_GETGROUPLIST */
6172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006173
Fred Drakec9680921999-12-13 16:37:25 +00006174#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006175/*[clinic input]
6176os.getgroups
6177
6178Return list of supplemental group IDs for the process.
6179[clinic start generated code]*/
6180
Larry Hastings2f936352014-08-05 14:04:04 +10006181static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006182os_getgroups_impl(PyObject *module)
6183/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006184{
6185 PyObject *result = NULL;
6186
Fred Drakec9680921999-12-13 16:37:25 +00006187#ifdef NGROUPS_MAX
6188#define MAX_GROUPS NGROUPS_MAX
6189#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006190 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006191#define MAX_GROUPS 64
6192#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006193 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006194
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006195 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006196 * This is a helper variable to store the intermediate result when
6197 * that happens.
6198 *
6199 * To keep the code readable the OSX behaviour is unconditional,
6200 * according to the POSIX spec this should be safe on all unix-y
6201 * systems.
6202 */
6203 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006205
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006206#ifdef __APPLE__
6207 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6208 * there are more groups than can fit in grouplist. Therefore, on OS X
6209 * always first call getgroups with length 0 to get the actual number
6210 * of groups.
6211 */
6212 n = getgroups(0, NULL);
6213 if (n < 0) {
6214 return posix_error();
6215 } else if (n <= MAX_GROUPS) {
6216 /* groups will fit in existing array */
6217 alt_grouplist = grouplist;
6218 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006219 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006220 if (alt_grouplist == NULL) {
6221 errno = EINVAL;
6222 return posix_error();
6223 }
6224 }
6225
6226 n = getgroups(n, alt_grouplist);
6227 if (n == -1) {
6228 if (alt_grouplist != grouplist) {
6229 PyMem_Free(alt_grouplist);
6230 }
6231 return posix_error();
6232 }
6233#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006235 if (n < 0) {
6236 if (errno == EINVAL) {
6237 n = getgroups(0, NULL);
6238 if (n == -1) {
6239 return posix_error();
6240 }
6241 if (n == 0) {
6242 /* Avoid malloc(0) */
6243 alt_grouplist = grouplist;
6244 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006245 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006246 if (alt_grouplist == NULL) {
6247 errno = EINVAL;
6248 return posix_error();
6249 }
6250 n = getgroups(n, alt_grouplist);
6251 if (n == -1) {
6252 PyMem_Free(alt_grouplist);
6253 return posix_error();
6254 }
6255 }
6256 } else {
6257 return posix_error();
6258 }
6259 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006260#endif
6261
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006262 result = PyList_New(n);
6263 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 int i;
6265 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006266 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006268 Py_DECREF(result);
6269 result = NULL;
6270 break;
Fred Drakec9680921999-12-13 16:37:25 +00006271 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006273 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006274 }
6275
6276 if (alt_grouplist != grouplist) {
6277 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006279
Fred Drakec9680921999-12-13 16:37:25 +00006280 return result;
6281}
Larry Hastings2f936352014-08-05 14:04:04 +10006282#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006283
Antoine Pitroub7572f02009-12-02 20:46:48 +00006284#ifdef HAVE_INITGROUPS
6285PyDoc_STRVAR(posix_initgroups__doc__,
6286"initgroups(username, gid) -> None\n\n\
6287Call the system initgroups() to initialize the group access list with all of\n\
6288the groups of which the specified username is a member, plus the specified\n\
6289group id.");
6290
Larry Hastings2f936352014-08-05 14:04:04 +10006291/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006292static PyObject *
6293posix_initgroups(PyObject *self, PyObject *args)
6294{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006295 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006296 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006297 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006298#ifdef __APPLE__
6299 int gid;
6300#else
6301 gid_t gid;
6302#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006303
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006304#ifdef __APPLE__
6305 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6306 PyUnicode_FSConverter, &oname,
6307 &gid))
6308#else
6309 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6310 PyUnicode_FSConverter, &oname,
6311 _Py_Gid_Converter, &gid))
6312#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006314 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006315
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006316 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006317 Py_DECREF(oname);
6318 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006319 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006320
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006321 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006322}
Larry Hastings2f936352014-08-05 14:04:04 +10006323#endif /* HAVE_INITGROUPS */
6324
Antoine Pitroub7572f02009-12-02 20:46:48 +00006325
Martin v. Löwis606edc12002-06-13 21:09:11 +00006326#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006327/*[clinic input]
6328os.getpgid
6329
6330 pid: pid_t
6331
6332Call the system call getpgid(), and return the result.
6333[clinic start generated code]*/
6334
Larry Hastings2f936352014-08-05 14:04:04 +10006335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006336os_getpgid_impl(PyObject *module, pid_t pid)
6337/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006338{
6339 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 if (pgid < 0)
6341 return posix_error();
6342 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006343}
6344#endif /* HAVE_GETPGID */
6345
6346
Guido van Rossumb6775db1994-08-01 11:34:53 +00006347#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006348/*[clinic input]
6349os.getpgrp
6350
6351Return the current process group id.
6352[clinic start generated code]*/
6353
Larry Hastings2f936352014-08-05 14:04:04 +10006354static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006355os_getpgrp_impl(PyObject *module)
6356/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006357{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006358#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006360#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006362#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006363}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006364#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006366
Guido van Rossumb6775db1994-08-01 11:34:53 +00006367#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006368/*[clinic input]
6369os.setpgrp
6370
6371Make the current process the leader of its process group.
6372[clinic start generated code]*/
6373
Larry Hastings2f936352014-08-05 14:04:04 +10006374static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006375os_setpgrp_impl(PyObject *module)
6376/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006377{
Guido van Rossum64933891994-10-20 21:56:42 +00006378#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006380#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006382#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006384 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006385}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006386#endif /* HAVE_SETPGRP */
6387
Guido van Rossumad0ee831995-03-01 10:34:45 +00006388#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006389
6390#ifdef MS_WINDOWS
6391#include <tlhelp32.h>
6392
6393static PyObject*
6394win32_getppid()
6395{
6396 HANDLE snapshot;
6397 pid_t mypid;
6398 PyObject* result = NULL;
6399 BOOL have_record;
6400 PROCESSENTRY32 pe;
6401
6402 mypid = getpid(); /* This function never fails */
6403
6404 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6405 if (snapshot == INVALID_HANDLE_VALUE)
6406 return PyErr_SetFromWindowsErr(GetLastError());
6407
6408 pe.dwSize = sizeof(pe);
6409 have_record = Process32First(snapshot, &pe);
6410 while (have_record) {
6411 if (mypid == (pid_t)pe.th32ProcessID) {
6412 /* We could cache the ulong value in a static variable. */
6413 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6414 break;
6415 }
6416
6417 have_record = Process32Next(snapshot, &pe);
6418 }
6419
6420 /* If our loop exits and our pid was not found (result will be NULL)
6421 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6422 * error anyway, so let's raise it. */
6423 if (!result)
6424 result = PyErr_SetFromWindowsErr(GetLastError());
6425
6426 CloseHandle(snapshot);
6427
6428 return result;
6429}
6430#endif /*MS_WINDOWS*/
6431
Larry Hastings2f936352014-08-05 14:04:04 +10006432
6433/*[clinic input]
6434os.getppid
6435
6436Return the parent's process id.
6437
6438If the parent process has already exited, Windows machines will still
6439return its id; others systems will return the id of the 'init' process (1).
6440[clinic start generated code]*/
6441
Larry Hastings2f936352014-08-05 14:04:04 +10006442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006443os_getppid_impl(PyObject *module)
6444/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006445{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006446#ifdef MS_WINDOWS
6447 return win32_getppid();
6448#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006450#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006451}
6452#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006453
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006454
Fred Drake12c6e2d1999-12-14 21:25:03 +00006455#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006456/*[clinic input]
6457os.getlogin
6458
6459Return the actual login name.
6460[clinic start generated code]*/
6461
Larry Hastings2f936352014-08-05 14:04:04 +10006462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006463os_getlogin_impl(PyObject *module)
6464/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006465{
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006467#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006468 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006469 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006470
6471 if (GetUserNameW(user_name, &num_chars)) {
6472 /* num_chars is the number of unicode chars plus null terminator */
6473 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006474 }
6475 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006476 result = PyErr_SetFromWindowsErr(GetLastError());
6477#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006478 char *name;
6479 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006480
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 errno = 0;
6482 name = getlogin();
6483 if (name == NULL) {
6484 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006485 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006486 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006487 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 }
6489 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006490 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006492#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006493 return result;
6494}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006495#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006496
Larry Hastings2f936352014-08-05 14:04:04 +10006497
Guido van Rossumad0ee831995-03-01 10:34:45 +00006498#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006499/*[clinic input]
6500os.getuid
6501
6502Return the current process's user id.
6503[clinic start generated code]*/
6504
Larry Hastings2f936352014-08-05 14:04:04 +10006505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006506os_getuid_impl(PyObject *module)
6507/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006508{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006509 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006510}
Larry Hastings2f936352014-08-05 14:04:04 +10006511#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006512
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006513
Brian Curtineb24d742010-04-12 17:16:38 +00006514#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006515#define HAVE_KILL
6516#endif /* MS_WINDOWS */
6517
6518#ifdef HAVE_KILL
6519/*[clinic input]
6520os.kill
6521
6522 pid: pid_t
6523 signal: Py_ssize_t
6524 /
6525
6526Kill a process with a signal.
6527[clinic start generated code]*/
6528
Larry Hastings2f936352014-08-05 14:04:04 +10006529static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006530os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6531/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006532#ifndef MS_WINDOWS
6533{
6534 if (kill(pid, (int)signal) == -1)
6535 return posix_error();
6536 Py_RETURN_NONE;
6537}
6538#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006539{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006540 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006541 DWORD sig = (DWORD)signal;
6542 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006544
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 /* Console processes which share a common console can be sent CTRL+C or
6546 CTRL+BREAK events, provided they handle said events. */
6547 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006548 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 err = GetLastError();
6550 PyErr_SetFromWindowsErr(err);
6551 }
6552 else
6553 Py_RETURN_NONE;
6554 }
Brian Curtineb24d742010-04-12 17:16:38 +00006555
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6557 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006558 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 if (handle == NULL) {
6560 err = GetLastError();
6561 return PyErr_SetFromWindowsErr(err);
6562 }
Brian Curtineb24d742010-04-12 17:16:38 +00006563
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 if (TerminateProcess(handle, sig) == 0) {
6565 err = GetLastError();
6566 result = PyErr_SetFromWindowsErr(err);
6567 } else {
6568 Py_INCREF(Py_None);
6569 result = Py_None;
6570 }
Brian Curtineb24d742010-04-12 17:16:38 +00006571
Victor Stinner8c62be82010-05-06 00:08:46 +00006572 CloseHandle(handle);
6573 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006574}
Larry Hastings2f936352014-08-05 14:04:04 +10006575#endif /* !MS_WINDOWS */
6576#endif /* HAVE_KILL */
6577
6578
6579#ifdef HAVE_KILLPG
6580/*[clinic input]
6581os.killpg
6582
6583 pgid: pid_t
6584 signal: int
6585 /
6586
6587Kill a process group with a signal.
6588[clinic start generated code]*/
6589
Larry Hastings2f936352014-08-05 14:04:04 +10006590static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006591os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6592/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006593{
6594 /* XXX some man pages make the `pgid` parameter an int, others
6595 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6596 take the same type. Moreover, pid_t is always at least as wide as
6597 int (else compilation of this module fails), which is safe. */
6598 if (killpg(pgid, signal) == -1)
6599 return posix_error();
6600 Py_RETURN_NONE;
6601}
6602#endif /* HAVE_KILLPG */
6603
Brian Curtineb24d742010-04-12 17:16:38 +00006604
Guido van Rossumc0125471996-06-28 18:55:32 +00006605#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006606#ifdef HAVE_SYS_LOCK_H
6607#include <sys/lock.h>
6608#endif
6609
Larry Hastings2f936352014-08-05 14:04:04 +10006610/*[clinic input]
6611os.plock
6612 op: int
6613 /
6614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006615Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006616[clinic start generated code]*/
6617
Larry Hastings2f936352014-08-05 14:04:04 +10006618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006619os_plock_impl(PyObject *module, int op)
6620/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006621{
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 if (plock(op) == -1)
6623 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006624 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006625}
Larry Hastings2f936352014-08-05 14:04:04 +10006626#endif /* HAVE_PLOCK */
6627
Guido van Rossumc0125471996-06-28 18:55:32 +00006628
Guido van Rossumb6775db1994-08-01 11:34:53 +00006629#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006630/*[clinic input]
6631os.setuid
6632
6633 uid: uid_t
6634 /
6635
6636Set the current process's user id.
6637[clinic start generated code]*/
6638
Larry Hastings2f936352014-08-05 14:04:04 +10006639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006640os_setuid_impl(PyObject *module, uid_t uid)
6641/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006642{
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 if (setuid(uid) < 0)
6644 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006645 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006646}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006647#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006648
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006649
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006650#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006651/*[clinic input]
6652os.seteuid
6653
6654 euid: uid_t
6655 /
6656
6657Set the current process's effective user id.
6658[clinic start generated code]*/
6659
Larry Hastings2f936352014-08-05 14:04:04 +10006660static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006661os_seteuid_impl(PyObject *module, uid_t euid)
6662/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006663{
6664 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006666 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006667}
6668#endif /* HAVE_SETEUID */
6669
Larry Hastings2f936352014-08-05 14:04:04 +10006670
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006671#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006672/*[clinic input]
6673os.setegid
6674
6675 egid: gid_t
6676 /
6677
6678Set the current process's effective group id.
6679[clinic start generated code]*/
6680
Larry Hastings2f936352014-08-05 14:04:04 +10006681static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006682os_setegid_impl(PyObject *module, gid_t egid)
6683/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006684{
6685 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006687 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006688}
6689#endif /* HAVE_SETEGID */
6690
Larry Hastings2f936352014-08-05 14:04:04 +10006691
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006692#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006693/*[clinic input]
6694os.setreuid
6695
6696 ruid: uid_t
6697 euid: uid_t
6698 /
6699
6700Set the current process's real and effective user ids.
6701[clinic start generated code]*/
6702
Larry Hastings2f936352014-08-05 14:04:04 +10006703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006704os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6705/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006706{
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 if (setreuid(ruid, euid) < 0) {
6708 return posix_error();
6709 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006710 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006712}
6713#endif /* HAVE_SETREUID */
6714
Larry Hastings2f936352014-08-05 14:04:04 +10006715
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006716#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006717/*[clinic input]
6718os.setregid
6719
6720 rgid: gid_t
6721 egid: gid_t
6722 /
6723
6724Set the current process's real and effective group ids.
6725[clinic start generated code]*/
6726
Larry Hastings2f936352014-08-05 14:04:04 +10006727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006728os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6729/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006730{
6731 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006733 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006734}
6735#endif /* HAVE_SETREGID */
6736
Larry Hastings2f936352014-08-05 14:04:04 +10006737
Guido van Rossumb6775db1994-08-01 11:34:53 +00006738#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006739/*[clinic input]
6740os.setgid
6741 gid: gid_t
6742 /
6743
6744Set the current process's group id.
6745[clinic start generated code]*/
6746
Larry Hastings2f936352014-08-05 14:04:04 +10006747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006748os_setgid_impl(PyObject *module, gid_t gid)
6749/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006750{
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 if (setgid(gid) < 0)
6752 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006753 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006754}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006755#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006756
Larry Hastings2f936352014-08-05 14:04:04 +10006757
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006758#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006759/*[clinic input]
6760os.setgroups
6761
6762 groups: object
6763 /
6764
6765Set the groups of the current process to list.
6766[clinic start generated code]*/
6767
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006768static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006769os_setgroups(PyObject *module, PyObject *groups)
6770/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006771{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006772 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006774
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 if (!PySequence_Check(groups)) {
6776 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6777 return NULL;
6778 }
6779 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006780 if (len < 0) {
6781 return NULL;
6782 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 if (len > MAX_GROUPS) {
6784 PyErr_SetString(PyExc_ValueError, "too many groups");
6785 return NULL;
6786 }
6787 for(i = 0; i < len; i++) {
6788 PyObject *elem;
6789 elem = PySequence_GetItem(groups, i);
6790 if (!elem)
6791 return NULL;
6792 if (!PyLong_Check(elem)) {
6793 PyErr_SetString(PyExc_TypeError,
6794 "groups must be integers");
6795 Py_DECREF(elem);
6796 return NULL;
6797 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006798 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 Py_DECREF(elem);
6800 return NULL;
6801 }
6802 }
6803 Py_DECREF(elem);
6804 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006805
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 if (setgroups(len, grouplist) < 0)
6807 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006808 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006809}
6810#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006811
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006812#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6813static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006814wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815{
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 PyObject *result;
6817 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006818 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006819
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 if (pid == -1)
6821 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006822
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 if (struct_rusage == NULL) {
6824 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6825 if (m == NULL)
6826 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006827 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 Py_DECREF(m);
6829 if (struct_rusage == NULL)
6830 return NULL;
6831 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6834 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6835 if (!result)
6836 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006837
6838#ifndef doubletime
6839#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6840#endif
6841
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006843 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006845 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6848 SET_INT(result, 2, ru->ru_maxrss);
6849 SET_INT(result, 3, ru->ru_ixrss);
6850 SET_INT(result, 4, ru->ru_idrss);
6851 SET_INT(result, 5, ru->ru_isrss);
6852 SET_INT(result, 6, ru->ru_minflt);
6853 SET_INT(result, 7, ru->ru_majflt);
6854 SET_INT(result, 8, ru->ru_nswap);
6855 SET_INT(result, 9, ru->ru_inblock);
6856 SET_INT(result, 10, ru->ru_oublock);
6857 SET_INT(result, 11, ru->ru_msgsnd);
6858 SET_INT(result, 12, ru->ru_msgrcv);
6859 SET_INT(result, 13, ru->ru_nsignals);
6860 SET_INT(result, 14, ru->ru_nvcsw);
6861 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006862#undef SET_INT
6863
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 if (PyErr_Occurred()) {
6865 Py_DECREF(result);
6866 return NULL;
6867 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006870}
6871#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6872
Larry Hastings2f936352014-08-05 14:04:04 +10006873
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006875/*[clinic input]
6876os.wait3
6877
6878 options: int
6879Wait for completion of a child process.
6880
6881Returns a tuple of information about the child process:
6882 (pid, status, rusage)
6883[clinic start generated code]*/
6884
Larry Hastings2f936352014-08-05 14:04:04 +10006885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006886os_wait3_impl(PyObject *module, int options)
6887/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888{
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006891 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 WAIT_TYPE status;
6893 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006895 do {
6896 Py_BEGIN_ALLOW_THREADS
6897 pid = wait3(&status, options, &ru);
6898 Py_END_ALLOW_THREADS
6899 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6900 if (pid < 0)
6901 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902
Victor Stinner4195b5c2012-02-08 23:03:19 +01006903 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006904}
6905#endif /* HAVE_WAIT3 */
6906
Larry Hastings2f936352014-08-05 14:04:04 +10006907
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006908#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006909/*[clinic input]
6910
6911os.wait4
6912
6913 pid: pid_t
6914 options: int
6915
6916Wait for completion of a specific child process.
6917
6918Returns a tuple of information about the child process:
6919 (pid, status, rusage)
6920[clinic start generated code]*/
6921
Larry Hastings2f936352014-08-05 14:04:04 +10006922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006923os_wait4_impl(PyObject *module, pid_t pid, int options)
6924/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006925{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006926 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006928 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 WAIT_TYPE status;
6930 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006932 do {
6933 Py_BEGIN_ALLOW_THREADS
6934 res = wait4(pid, &status, options, &ru);
6935 Py_END_ALLOW_THREADS
6936 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6937 if (res < 0)
6938 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006939
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006940 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941}
6942#endif /* HAVE_WAIT4 */
6943
Larry Hastings2f936352014-08-05 14:04:04 +10006944
Ross Lagerwall7807c352011-03-17 20:20:30 +02006945#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006946/*[clinic input]
6947os.waitid
6948
6949 idtype: idtype_t
6950 Must be one of be P_PID, P_PGID or P_ALL.
6951 id: id_t
6952 The id to wait on.
6953 options: int
6954 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6955 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6956 /
6957
6958Returns the result of waiting for a process or processes.
6959
6960Returns either waitid_result or None if WNOHANG is specified and there are
6961no children in a waitable state.
6962[clinic start generated code]*/
6963
Larry Hastings2f936352014-08-05 14:04:04 +10006964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006965os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6966/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006967{
6968 PyObject *result;
6969 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006970 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006971 siginfo_t si;
6972 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006973
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006974 do {
6975 Py_BEGIN_ALLOW_THREADS
6976 res = waitid(idtype, id, &si, options);
6977 Py_END_ALLOW_THREADS
6978 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6979 if (res < 0)
6980 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006981
6982 if (si.si_pid == 0)
6983 Py_RETURN_NONE;
6984
6985 result = PyStructSequence_New(&WaitidResultType);
6986 if (!result)
6987 return NULL;
6988
6989 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006990 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006991 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6992 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6993 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6994 if (PyErr_Occurred()) {
6995 Py_DECREF(result);
6996 return NULL;
6997 }
6998
6999 return result;
7000}
Larry Hastings2f936352014-08-05 14:04:04 +10007001#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007002
Larry Hastings2f936352014-08-05 14:04:04 +10007003
7004#if defined(HAVE_WAITPID)
7005/*[clinic input]
7006os.waitpid
7007 pid: pid_t
7008 options: int
7009 /
7010
7011Wait for completion of a given child process.
7012
7013Returns a tuple of information regarding the child process:
7014 (pid, status)
7015
7016The options argument is ignored on Windows.
7017[clinic start generated code]*/
7018
Larry Hastings2f936352014-08-05 14:04:04 +10007019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007020os_waitpid_impl(PyObject *module, pid_t pid, int options)
7021/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007022{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007023 pid_t res;
7024 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 WAIT_TYPE status;
7026 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007027
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007028 do {
7029 Py_BEGIN_ALLOW_THREADS
7030 res = waitpid(pid, &status, options);
7031 Py_END_ALLOW_THREADS
7032 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7033 if (res < 0)
7034 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007035
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007036 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007037}
Tim Petersab034fa2002-02-01 11:27:43 +00007038#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007039/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007040/*[clinic input]
7041os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007042 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007043 options: int
7044 /
7045
7046Wait for completion of a given process.
7047
7048Returns a tuple of information regarding the process:
7049 (pid, status << 8)
7050
7051The options argument is ignored on Windows.
7052[clinic start generated code]*/
7053
Larry Hastings2f936352014-08-05 14:04:04 +10007054static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007055os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007056/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007057{
7058 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007059 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007060 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007061
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007062 do {
7063 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007064 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007065 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007066 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007067 Py_END_ALLOW_THREADS
7068 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007069 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007070 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007071
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007073 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007074}
Larry Hastings2f936352014-08-05 14:04:04 +10007075#endif
7076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007077
Guido van Rossumad0ee831995-03-01 10:34:45 +00007078#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007079/*[clinic input]
7080os.wait
7081
7082Wait for completion of a child process.
7083
7084Returns a tuple of information about the child process:
7085 (pid, status)
7086[clinic start generated code]*/
7087
Larry Hastings2f936352014-08-05 14:04:04 +10007088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007089os_wait_impl(PyObject *module)
7090/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007091{
Victor Stinner8c62be82010-05-06 00:08:46 +00007092 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007093 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 WAIT_TYPE status;
7095 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007096
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007097 do {
7098 Py_BEGIN_ALLOW_THREADS
7099 pid = wait(&status);
7100 Py_END_ALLOW_THREADS
7101 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7102 if (pid < 0)
7103 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007104
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007106}
Larry Hastings2f936352014-08-05 14:04:04 +10007107#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007109
Larry Hastings9cf065c2012-06-22 16:30:09 -07007110#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7111PyDoc_STRVAR(readlink__doc__,
7112"readlink(path, *, dir_fd=None) -> path\n\n\
7113Return a string representing the path to which the symbolic link points.\n\
7114\n\
7115If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7116 and path should be relative; path will then be relative to that directory.\n\
7117dir_fd may not be implemented on your platform.\n\
7118 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007119#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007120
Guido van Rossumb6775db1994-08-01 11:34:53 +00007121#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007122
Larry Hastings2f936352014-08-05 14:04:04 +10007123/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007124static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007126{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007127 path_t path;
7128 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007129 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130 ssize_t length;
7131 PyObject *return_value = NULL;
7132 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007133
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007135 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7137 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007138 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007140
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007142#ifdef HAVE_READLINKAT
7143 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007144 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007145 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007146#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007147 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148 Py_END_ALLOW_THREADS
7149
7150 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007151 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152 goto exit;
7153 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007154 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155
7156 if (PyUnicode_Check(path.object))
7157 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7158 else
7159 return_value = PyBytes_FromStringAndSize(buffer, length);
7160exit:
7161 path_cleanup(&path);
7162 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007163}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164
Guido van Rossumb6775db1994-08-01 11:34:53 +00007165#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007166
Larry Hastings2f936352014-08-05 14:04:04 +10007167#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7168
7169static PyObject *
7170win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7171{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007172 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007173 DWORD n_bytes_returned;
7174 DWORD io_result;
7175 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007176 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007177 HANDLE reparse_point_handle;
7178
Martin Panter70214ad2016-08-04 02:38:59 +00007179 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7180 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007181 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007182
7183 static char *keywords[] = {"path", "dir_fd", NULL};
7184
7185 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7186 &po,
7187 dir_fd_unavailable, &dir_fd
7188 ))
7189 return NULL;
7190
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007191 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007192 if (path == NULL)
7193 return NULL;
7194
7195 /* First get a handle to the reparse point */
7196 Py_BEGIN_ALLOW_THREADS
7197 reparse_point_handle = CreateFileW(
7198 path,
7199 0,
7200 0,
7201 0,
7202 OPEN_EXISTING,
7203 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7204 0);
7205 Py_END_ALLOW_THREADS
7206
7207 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7208 return win32_error_object("readlink", po);
7209
7210 Py_BEGIN_ALLOW_THREADS
7211 /* New call DeviceIoControl to read the reparse point */
7212 io_result = DeviceIoControl(
7213 reparse_point_handle,
7214 FSCTL_GET_REPARSE_POINT,
7215 0, 0, /* in buffer */
7216 target_buffer, sizeof(target_buffer),
7217 &n_bytes_returned,
7218 0 /* we're not using OVERLAPPED_IO */
7219 );
7220 CloseHandle(reparse_point_handle);
7221 Py_END_ALLOW_THREADS
7222
7223 if (io_result==0)
7224 return win32_error_object("readlink", po);
7225
7226 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7227 {
7228 PyErr_SetString(PyExc_ValueError,
7229 "not a symbolic link");
7230 return NULL;
7231 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007232 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7233 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007234
7235 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007236 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007237 return result;
7238}
7239
7240#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7241
7242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007243
Larry Hastings9cf065c2012-06-22 16:30:09 -07007244#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007245
7246#if defined(MS_WINDOWS)
7247
7248/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007249static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007250
Larry Hastings9cf065c2012-06-22 16:30:09 -07007251static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007252check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007253{
7254 HINSTANCE hKernel32;
7255 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007256 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007257 return 1;
7258 hKernel32 = GetModuleHandleW(L"KERNEL32");
7259 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7260 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007261 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262}
7263
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007264/* Remove the last portion of the path - return 0 on success */
7265static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007266_dirnameW(WCHAR *path)
7267{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007268 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007269 size_t length = wcsnlen_s(path, MAX_PATH);
7270 if (length == MAX_PATH) {
7271 return -1;
7272 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007273
7274 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007275 for(ptr = path + length; ptr != path; ptr--) {
7276 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007278 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007279 }
7280 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007281 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007282}
7283
Victor Stinner31b3b922013-06-05 01:49:17 +02007284/* Is this path absolute? */
7285static int
7286_is_absW(const WCHAR *path)
7287{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007288 return path[0] == L'\\' || path[0] == L'/' ||
7289 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007290}
7291
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007292/* join root and rest with a backslash - return 0 on success */
7293static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007294_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7295{
Victor Stinner31b3b922013-06-05 01:49:17 +02007296 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007297 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007298 }
7299
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007300 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7301 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007302 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007303
7304 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7305 return -1;
7306 }
7307
7308 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007309}
7310
Victor Stinner31b3b922013-06-05 01:49:17 +02007311/* Return True if the path at src relative to dest is a directory */
7312static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007313_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007315 WIN32_FILE_ATTRIBUTE_DATA src_info;
7316 WCHAR dest_parent[MAX_PATH];
7317 WCHAR src_resolved[MAX_PATH] = L"";
7318
7319 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007320 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7321 _dirnameW(dest_parent)) {
7322 return 0;
7323 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007324 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007325 if (_joinW(src_resolved, dest_parent, src)) {
7326 return 0;
7327 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007328 return (
7329 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7330 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7331 );
7332}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007333#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007334
Larry Hastings2f936352014-08-05 14:04:04 +10007335
7336/*[clinic input]
7337os.symlink
7338 src: path_t
7339 dst: path_t
7340 target_is_directory: bool = False
7341 *
7342 dir_fd: dir_fd(requires='symlinkat')=None
7343
7344# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7345
7346Create a symbolic link pointing to src named dst.
7347
7348target_is_directory is required on Windows if the target is to be
7349 interpreted as a directory. (On Windows, symlink requires
7350 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7351 target_is_directory is ignored on non-Windows platforms.
7352
7353If dir_fd is not None, it should be a file descriptor open to a directory,
7354 and path should be relative; path will then be relative to that directory.
7355dir_fd may not be implemented on your platform.
7356 If it is unavailable, using it will raise a NotImplementedError.
7357
7358[clinic start generated code]*/
7359
Larry Hastings2f936352014-08-05 14:04:04 +10007360static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007361os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007362 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007363/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007364{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007365#ifdef MS_WINDOWS
7366 DWORD result;
7367#else
7368 int result;
7369#endif
7370
Larry Hastings9cf065c2012-06-22 16:30:09 -07007371#ifdef MS_WINDOWS
7372 if (!check_CreateSymbolicLink()) {
7373 PyErr_SetString(PyExc_NotImplementedError,
7374 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007375 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007376 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007377 if (!win32_can_symlink) {
7378 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007379 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007380 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007381#endif
7382
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007384
Larry Hastings9cf065c2012-06-22 16:30:09 -07007385 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007386 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007387 /* if src is a directory, ensure target_is_directory==1 */
7388 target_is_directory |= _check_dirW(src->wide, dst->wide);
7389 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7390 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007391 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392 Py_END_ALLOW_THREADS
7393
Larry Hastings2f936352014-08-05 14:04:04 +10007394 if (!result)
7395 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396
7397#else
7398
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007399 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7400 PyErr_SetString(PyExc_ValueError,
7401 "symlink: src and dst must be the same type");
7402 return NULL;
7403 }
7404
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405 Py_BEGIN_ALLOW_THREADS
7406#if HAVE_SYMLINKAT
7407 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007408 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409 else
7410#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007411 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007412 Py_END_ALLOW_THREADS
7413
Larry Hastings2f936352014-08-05 14:04:04 +10007414 if (result)
7415 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007416#endif
7417
Larry Hastings2f936352014-08-05 14:04:04 +10007418 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007419}
7420#endif /* HAVE_SYMLINK */
7421
Larry Hastings9cf065c2012-06-22 16:30:09 -07007422
Brian Curtind40e6f72010-07-08 21:39:08 +00007423
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007424
Larry Hastings605a62d2012-06-24 04:33:36 -07007425static PyStructSequence_Field times_result_fields[] = {
7426 {"user", "user time"},
7427 {"system", "system time"},
7428 {"children_user", "user time of children"},
7429 {"children_system", "system time of children"},
7430 {"elapsed", "elapsed time since an arbitrary point in the past"},
7431 {NULL}
7432};
7433
7434PyDoc_STRVAR(times_result__doc__,
7435"times_result: Result from os.times().\n\n\
7436This object may be accessed either as a tuple of\n\
7437 (user, system, children_user, children_system, elapsed),\n\
7438or via the attributes user, system, children_user, children_system,\n\
7439and elapsed.\n\
7440\n\
7441See os.times for more information.");
7442
7443static PyStructSequence_Desc times_result_desc = {
7444 "times_result", /* name */
7445 times_result__doc__, /* doc */
7446 times_result_fields,
7447 5
7448};
7449
7450static PyTypeObject TimesResultType;
7451
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007452#ifdef MS_WINDOWS
7453#define HAVE_TIMES /* mandatory, for the method table */
7454#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007455
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007456#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007457
7458static PyObject *
7459build_times_result(double user, double system,
7460 double children_user, double children_system,
7461 double elapsed)
7462{
7463 PyObject *value = PyStructSequence_New(&TimesResultType);
7464 if (value == NULL)
7465 return NULL;
7466
7467#define SET(i, field) \
7468 { \
7469 PyObject *o = PyFloat_FromDouble(field); \
7470 if (!o) { \
7471 Py_DECREF(value); \
7472 return NULL; \
7473 } \
7474 PyStructSequence_SET_ITEM(value, i, o); \
7475 } \
7476
7477 SET(0, user);
7478 SET(1, system);
7479 SET(2, children_user);
7480 SET(3, children_system);
7481 SET(4, elapsed);
7482
7483#undef SET
7484
7485 return value;
7486}
7487
Larry Hastings605a62d2012-06-24 04:33:36 -07007488
Larry Hastings2f936352014-08-05 14:04:04 +10007489#ifndef MS_WINDOWS
7490#define NEED_TICKS_PER_SECOND
7491static long ticks_per_second = -1;
7492#endif /* MS_WINDOWS */
7493
7494/*[clinic input]
7495os.times
7496
7497Return a collection containing process timing information.
7498
7499The object returned behaves like a named tuple with these fields:
7500 (utime, stime, cutime, cstime, elapsed_time)
7501All fields are floating point numbers.
7502[clinic start generated code]*/
7503
Larry Hastings2f936352014-08-05 14:04:04 +10007504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007505os_times_impl(PyObject *module)
7506/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007507#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007508{
Victor Stinner8c62be82010-05-06 00:08:46 +00007509 FILETIME create, exit, kernel, user;
7510 HANDLE hProc;
7511 hProc = GetCurrentProcess();
7512 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7513 /* The fields of a FILETIME structure are the hi and lo part
7514 of a 64-bit value expressed in 100 nanosecond units.
7515 1e7 is one second in such units; 1e-7 the inverse.
7516 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7517 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007518 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007519 (double)(user.dwHighDateTime*429.4967296 +
7520 user.dwLowDateTime*1e-7),
7521 (double)(kernel.dwHighDateTime*429.4967296 +
7522 kernel.dwLowDateTime*1e-7),
7523 (double)0,
7524 (double)0,
7525 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007526}
Larry Hastings2f936352014-08-05 14:04:04 +10007527#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007528{
Larry Hastings2f936352014-08-05 14:04:04 +10007529
7530
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007531 struct tms t;
7532 clock_t c;
7533 errno = 0;
7534 c = times(&t);
7535 if (c == (clock_t) -1)
7536 return posix_error();
7537 return build_times_result(
7538 (double)t.tms_utime / ticks_per_second,
7539 (double)t.tms_stime / ticks_per_second,
7540 (double)t.tms_cutime / ticks_per_second,
7541 (double)t.tms_cstime / ticks_per_second,
7542 (double)c / ticks_per_second);
7543}
Larry Hastings2f936352014-08-05 14:04:04 +10007544#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007545#endif /* HAVE_TIMES */
7546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007547
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007548#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007549/*[clinic input]
7550os.getsid
7551
7552 pid: pid_t
7553 /
7554
7555Call the system call getsid(pid) and return the result.
7556[clinic start generated code]*/
7557
Larry Hastings2f936352014-08-05 14:04:04 +10007558static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007559os_getsid_impl(PyObject *module, pid_t pid)
7560/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007561{
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 sid = getsid(pid);
7564 if (sid < 0)
7565 return posix_error();
7566 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007567}
7568#endif /* HAVE_GETSID */
7569
7570
Guido van Rossumb6775db1994-08-01 11:34:53 +00007571#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007572/*[clinic input]
7573os.setsid
7574
7575Call the system call setsid().
7576[clinic start generated code]*/
7577
Larry Hastings2f936352014-08-05 14:04:04 +10007578static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007579os_setsid_impl(PyObject *module)
7580/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007581{
Victor Stinner8c62be82010-05-06 00:08:46 +00007582 if (setsid() < 0)
7583 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007584 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007585}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007586#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007587
Larry Hastings2f936352014-08-05 14:04:04 +10007588
Guido van Rossumb6775db1994-08-01 11:34:53 +00007589#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007590/*[clinic input]
7591os.setpgid
7592
7593 pid: pid_t
7594 pgrp: pid_t
7595 /
7596
7597Call the system call setpgid(pid, pgrp).
7598[clinic start generated code]*/
7599
Larry Hastings2f936352014-08-05 14:04:04 +10007600static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007601os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7602/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007603{
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 if (setpgid(pid, pgrp) < 0)
7605 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007606 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007607}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007608#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Guido van Rossumb6775db1994-08-01 11:34:53 +00007611#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007612/*[clinic input]
7613os.tcgetpgrp
7614
7615 fd: int
7616 /
7617
7618Return the process group associated with the terminal specified by fd.
7619[clinic start generated code]*/
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007622os_tcgetpgrp_impl(PyObject *module, int fd)
7623/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007624{
7625 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 if (pgid < 0)
7627 return posix_error();
7628 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007630#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007632
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007634/*[clinic input]
7635os.tcsetpgrp
7636
7637 fd: int
7638 pgid: pid_t
7639 /
7640
7641Set the process group associated with the terminal specified by fd.
7642[clinic start generated code]*/
7643
Larry Hastings2f936352014-08-05 14:04:04 +10007644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007645os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7646/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007647{
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 if (tcsetpgrp(fd, pgid) < 0)
7649 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007650 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007651}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007652#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007653
Guido van Rossum687dd131993-05-17 08:34:16 +00007654/* Functions acting on file descriptors */
7655
Victor Stinnerdaf45552013-08-28 00:53:59 +02007656#ifdef O_CLOEXEC
7657extern int _Py_open_cloexec_works;
7658#endif
7659
Larry Hastings2f936352014-08-05 14:04:04 +10007660
7661/*[clinic input]
7662os.open -> int
7663 path: path_t
7664 flags: int
7665 mode: int = 0o777
7666 *
7667 dir_fd: dir_fd(requires='openat') = None
7668
7669# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7670
7671Open a file for low level IO. Returns a file descriptor (integer).
7672
7673If dir_fd is not None, it should be a file descriptor open to a directory,
7674 and path should be relative; path will then be relative to that directory.
7675dir_fd may not be implemented on your platform.
7676 If it is unavailable, using it will raise a NotImplementedError.
7677[clinic start generated code]*/
7678
Larry Hastings2f936352014-08-05 14:04:04 +10007679static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007680os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7681/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007682{
7683 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007684 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007685
Victor Stinnerdaf45552013-08-28 00:53:59 +02007686#ifdef O_CLOEXEC
7687 int *atomic_flag_works = &_Py_open_cloexec_works;
7688#elif !defined(MS_WINDOWS)
7689 int *atomic_flag_works = NULL;
7690#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007691
Victor Stinnerdaf45552013-08-28 00:53:59 +02007692#ifdef MS_WINDOWS
7693 flags |= O_NOINHERIT;
7694#elif defined(O_CLOEXEC)
7695 flags |= O_CLOEXEC;
7696#endif
7697
Steve Dower8fc89802015-04-12 00:26:27 -04007698 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007699 do {
7700 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007701#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007702 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007703#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007704#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007705 if (dir_fd != DEFAULT_DIR_FD)
7706 fd = openat(dir_fd, path->narrow, flags, mode);
7707 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007708#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007709 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007710#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007711 Py_END_ALLOW_THREADS
7712 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007713 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007714
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007715 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007716 if (!async_err)
7717 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007718 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007719 }
7720
Victor Stinnerdaf45552013-08-28 00:53:59 +02007721#ifndef MS_WINDOWS
7722 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7723 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007724 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007725 }
7726#endif
7727
Larry Hastings2f936352014-08-05 14:04:04 +10007728 return fd;
7729}
7730
7731
7732/*[clinic input]
7733os.close
7734
7735 fd: int
7736
7737Close a file descriptor.
7738[clinic start generated code]*/
7739
Barry Warsaw53699e91996-12-10 23:23:01 +00007740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007741os_close_impl(PyObject *module, int fd)
7742/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007743{
Larry Hastings2f936352014-08-05 14:04:04 +10007744 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007745 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7746 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7747 * for more details.
7748 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007750 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007752 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 Py_END_ALLOW_THREADS
7754 if (res < 0)
7755 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007756 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007757}
7758
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007759
Larry Hastings2f936352014-08-05 14:04:04 +10007760/*[clinic input]
7761os.closerange
7762
7763 fd_low: int
7764 fd_high: int
7765 /
7766
7767Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7768[clinic start generated code]*/
7769
Larry Hastings2f936352014-08-05 14:04:04 +10007770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007771os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7772/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007773{
7774 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007776 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007777 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007778 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007779 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 Py_END_ALLOW_THREADS
7781 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007782}
7783
7784
Larry Hastings2f936352014-08-05 14:04:04 +10007785/*[clinic input]
7786os.dup -> int
7787
7788 fd: int
7789 /
7790
7791Return a duplicate of a file descriptor.
7792[clinic start generated code]*/
7793
Larry Hastings2f936352014-08-05 14:04:04 +10007794static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007795os_dup_impl(PyObject *module, int fd)
7796/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007797{
7798 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007799}
7800
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007801
Larry Hastings2f936352014-08-05 14:04:04 +10007802/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007803os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007804 fd: int
7805 fd2: int
7806 inheritable: bool=True
7807
7808Duplicate file descriptor.
7809[clinic start generated code]*/
7810
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007811static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007812os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007813/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007814{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007815 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007816#if defined(HAVE_DUP3) && \
7817 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7818 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007819 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007820#endif
7821
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007822 if (fd < 0 || fd2 < 0) {
7823 posix_error();
7824 return -1;
7825 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007826
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007827 /* dup2() can fail with EINTR if the target FD is already open, because it
7828 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7829 * upon close(), and therefore below.
7830 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007831#ifdef MS_WINDOWS
7832 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007833 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007834 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007835 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007836 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007837 if (res < 0) {
7838 posix_error();
7839 return -1;
7840 }
7841 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007842
7843 /* Character files like console cannot be make non-inheritable */
7844 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7845 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007846 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007847 }
7848
7849#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7850 Py_BEGIN_ALLOW_THREADS
7851 if (!inheritable)
7852 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7853 else
7854 res = dup2(fd, fd2);
7855 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007856 if (res < 0) {
7857 posix_error();
7858 return -1;
7859 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860
7861#else
7862
7863#ifdef HAVE_DUP3
7864 if (!inheritable && dup3_works != 0) {
7865 Py_BEGIN_ALLOW_THREADS
7866 res = dup3(fd, fd2, O_CLOEXEC);
7867 Py_END_ALLOW_THREADS
7868 if (res < 0) {
7869 if (dup3_works == -1)
7870 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007871 if (dup3_works) {
7872 posix_error();
7873 return -1;
7874 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007875 }
7876 }
7877
7878 if (inheritable || dup3_works == 0)
7879 {
7880#endif
7881 Py_BEGIN_ALLOW_THREADS
7882 res = dup2(fd, fd2);
7883 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007884 if (res < 0) {
7885 posix_error();
7886 return -1;
7887 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007888
7889 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7890 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007891 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007892 }
7893#ifdef HAVE_DUP3
7894 }
7895#endif
7896
7897#endif
7898
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007899 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007900}
7901
Larry Hastings2f936352014-08-05 14:04:04 +10007902
Ross Lagerwall7807c352011-03-17 20:20:30 +02007903#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007904/*[clinic input]
7905os.lockf
7906
7907 fd: int
7908 An open file descriptor.
7909 command: int
7910 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7911 length: Py_off_t
7912 The number of bytes to lock, starting at the current position.
7913 /
7914
7915Apply, test or remove a POSIX lock on an open file descriptor.
7916
7917[clinic start generated code]*/
7918
Larry Hastings2f936352014-08-05 14:04:04 +10007919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007920os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7921/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007922{
7923 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007924
7925 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007926 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007927 Py_END_ALLOW_THREADS
7928
7929 if (res < 0)
7930 return posix_error();
7931
7932 Py_RETURN_NONE;
7933}
Larry Hastings2f936352014-08-05 14:04:04 +10007934#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007936
Larry Hastings2f936352014-08-05 14:04:04 +10007937/*[clinic input]
7938os.lseek -> Py_off_t
7939
7940 fd: int
7941 position: Py_off_t
7942 how: int
7943 /
7944
7945Set the position of a file descriptor. Return the new position.
7946
7947Return the new cursor position in number of bytes
7948relative to the beginning of the file.
7949[clinic start generated code]*/
7950
Larry Hastings2f936352014-08-05 14:04:04 +10007951static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007952os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7953/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007954{
7955 Py_off_t result;
7956
Guido van Rossum687dd131993-05-17 08:34:16 +00007957#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7959 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007960 case 0: how = SEEK_SET; break;
7961 case 1: how = SEEK_CUR; break;
7962 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007964#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007965
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007967 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007968
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007970 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007971#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007972 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007973#else
Larry Hastings2f936352014-08-05 14:04:04 +10007974 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007975#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007976 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007978 if (result < 0)
7979 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007980
Larry Hastings2f936352014-08-05 14:04:04 +10007981 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007982}
7983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007984
Larry Hastings2f936352014-08-05 14:04:04 +10007985/*[clinic input]
7986os.read
7987 fd: int
7988 length: Py_ssize_t
7989 /
7990
7991Read from a file descriptor. Returns a bytes object.
7992[clinic start generated code]*/
7993
Larry Hastings2f936352014-08-05 14:04:04 +10007994static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007995os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7996/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007997{
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 Py_ssize_t n;
7999 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008000
8001 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 errno = EINVAL;
8003 return posix_error();
8004 }
Larry Hastings2f936352014-08-05 14:04:04 +10008005
8006#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008007 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008008 if (length > INT_MAX)
8009 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008010#endif
8011
8012 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 if (buffer == NULL)
8014 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008015
Victor Stinner66aab0c2015-03-19 22:53:20 +01008016 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8017 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008019 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 }
Larry Hastings2f936352014-08-05 14:04:04 +10008021
8022 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008024
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008026}
8027
Ross Lagerwall7807c352011-03-17 20:20:30 +02008028#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008029 || defined(__APPLE__))) \
8030 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8031 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8032static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008033iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008034{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008035 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008036
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008037 *iov = PyMem_New(struct iovec, cnt);
8038 if (*iov == NULL) {
8039 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008040 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008041 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008042
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008043 *buf = PyMem_New(Py_buffer, cnt);
8044 if (*buf == NULL) {
8045 PyMem_Del(*iov);
8046 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008047 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048 }
8049
8050 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008051 PyObject *item = PySequence_GetItem(seq, i);
8052 if (item == NULL)
8053 goto fail;
8054 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8055 Py_DECREF(item);
8056 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008058 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008060 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008062 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008063
8064fail:
8065 PyMem_Del(*iov);
8066 for (j = 0; j < i; j++) {
8067 PyBuffer_Release(&(*buf)[j]);
8068 }
8069 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008070 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071}
8072
8073static void
8074iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8075{
8076 int i;
8077 PyMem_Del(iov);
8078 for (i = 0; i < cnt; i++) {
8079 PyBuffer_Release(&buf[i]);
8080 }
8081 PyMem_Del(buf);
8082}
8083#endif
8084
Larry Hastings2f936352014-08-05 14:04:04 +10008085
Ross Lagerwall7807c352011-03-17 20:20:30 +02008086#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008087/*[clinic input]
8088os.readv -> Py_ssize_t
8089
8090 fd: int
8091 buffers: object
8092 /
8093
8094Read from a file descriptor fd into an iterable of buffers.
8095
8096The buffers should be mutable buffers accepting bytes.
8097readv will transfer data into each buffer until it is full
8098and then move on to the next buffer in the sequence to hold
8099the rest of the data.
8100
8101readv returns the total number of bytes read,
8102which may be less than the total capacity of all the buffers.
8103[clinic start generated code]*/
8104
Larry Hastings2f936352014-08-05 14:04:04 +10008105static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008106os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8107/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008108{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008109 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008110 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008111 struct iovec *iov;
8112 Py_buffer *buf;
8113
Larry Hastings2f936352014-08-05 14:04:04 +10008114 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008115 PyErr_SetString(PyExc_TypeError,
8116 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008117 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008118 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008119
Larry Hastings2f936352014-08-05 14:04:04 +10008120 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008121 if (cnt < 0)
8122 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008123
8124 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8125 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008126
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008127 do {
8128 Py_BEGIN_ALLOW_THREADS
8129 n = readv(fd, iov, cnt);
8130 Py_END_ALLOW_THREADS
8131 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008132
8133 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008134 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008135 if (!async_err)
8136 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008137 return -1;
8138 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008139
Larry Hastings2f936352014-08-05 14:04:04 +10008140 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008141}
Larry Hastings2f936352014-08-05 14:04:04 +10008142#endif /* HAVE_READV */
8143
Ross Lagerwall7807c352011-03-17 20:20:30 +02008144
8145#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008146/*[clinic input]
8147# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8148os.pread
8149
8150 fd: int
8151 length: int
8152 offset: Py_off_t
8153 /
8154
8155Read a number of bytes from a file descriptor starting at a particular offset.
8156
8157Read length bytes from file descriptor fd, starting at offset bytes from
8158the beginning of the file. The file offset remains unchanged.
8159[clinic start generated code]*/
8160
Larry Hastings2f936352014-08-05 14:04:04 +10008161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008162os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8163/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008164{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008165 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008166 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008167 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168
Larry Hastings2f936352014-08-05 14:04:04 +10008169 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008170 errno = EINVAL;
8171 return posix_error();
8172 }
Larry Hastings2f936352014-08-05 14:04:04 +10008173 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008174 if (buffer == NULL)
8175 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008176
8177 do {
8178 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008179 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008180 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008181 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008182 Py_END_ALLOW_THREADS
8183 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8184
Ross Lagerwall7807c352011-03-17 20:20:30 +02008185 if (n < 0) {
8186 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008187 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008188 }
Larry Hastings2f936352014-08-05 14:04:04 +10008189 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008190 _PyBytes_Resize(&buffer, n);
8191 return buffer;
8192}
Larry Hastings2f936352014-08-05 14:04:04 +10008193#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194
Pablo Galindo4defba32018-01-27 16:16:37 +00008195#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8196/*[clinic input]
8197os.preadv -> Py_ssize_t
8198
8199 fd: int
8200 buffers: object
8201 offset: Py_off_t
8202 flags: int = 0
8203 /
8204
8205Reads from a file descriptor into a number of mutable bytes-like objects.
8206
8207Combines the functionality of readv() and pread(). As readv(), it will
8208transfer data into each buffer until it is full and then move on to the next
8209buffer in the sequence to hold the rest of the data. Its fourth argument,
8210specifies the file offset at which the input operation is to be performed. It
8211will return the total number of bytes read (which can be less than the total
8212capacity of all the objects).
8213
8214The flags argument contains a bitwise OR of zero or more of the following flags:
8215
8216- RWF_HIPRI
8217- RWF_NOWAIT
8218
8219Using non-zero flags requires Linux 4.6 or newer.
8220[clinic start generated code]*/
8221
8222static Py_ssize_t
8223os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8224 int flags)
8225/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8226{
8227 Py_ssize_t cnt, n;
8228 int async_err = 0;
8229 struct iovec *iov;
8230 Py_buffer *buf;
8231
8232 if (!PySequence_Check(buffers)) {
8233 PyErr_SetString(PyExc_TypeError,
8234 "preadv2() arg 2 must be a sequence");
8235 return -1;
8236 }
8237
8238 cnt = PySequence_Size(buffers);
8239 if (cnt < 0) {
8240 return -1;
8241 }
8242
8243#ifndef HAVE_PREADV2
8244 if(flags != 0) {
8245 argument_unavailable_error("preadv2", "flags");
8246 return -1;
8247 }
8248#endif
8249
8250 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8251 return -1;
8252 }
8253#ifdef HAVE_PREADV2
8254 do {
8255 Py_BEGIN_ALLOW_THREADS
8256 _Py_BEGIN_SUPPRESS_IPH
8257 n = preadv2(fd, iov, cnt, offset, flags);
8258 _Py_END_SUPPRESS_IPH
8259 Py_END_ALLOW_THREADS
8260 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8261#else
8262 do {
8263 Py_BEGIN_ALLOW_THREADS
8264 _Py_BEGIN_SUPPRESS_IPH
8265 n = preadv(fd, iov, cnt, offset);
8266 _Py_END_SUPPRESS_IPH
8267 Py_END_ALLOW_THREADS
8268 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8269#endif
8270
8271 iov_cleanup(iov, buf, cnt);
8272 if (n < 0) {
8273 if (!async_err) {
8274 posix_error();
8275 }
8276 return -1;
8277 }
8278
8279 return n;
8280}
8281#endif /* HAVE_PREADV */
8282
Larry Hastings2f936352014-08-05 14:04:04 +10008283
8284/*[clinic input]
8285os.write -> Py_ssize_t
8286
8287 fd: int
8288 data: Py_buffer
8289 /
8290
8291Write a bytes object to a file descriptor.
8292[clinic start generated code]*/
8293
Larry Hastings2f936352014-08-05 14:04:04 +10008294static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008295os_write_impl(PyObject *module, int fd, Py_buffer *data)
8296/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008297{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008298 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008299}
8300
8301#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008302PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008303"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008304sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008305 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008306Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307
Larry Hastings2f936352014-08-05 14:04:04 +10008308/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008309static PyObject *
8310posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8311{
8312 int in, out;
8313 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008314 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008315 off_t offset;
8316
8317#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8318#ifndef __APPLE__
8319 Py_ssize_t len;
8320#endif
8321 PyObject *headers = NULL, *trailers = NULL;
8322 Py_buffer *hbuf, *tbuf;
8323 off_t sbytes;
8324 struct sf_hdtr sf;
8325 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008326 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008327 static char *keywords[] = {"out", "in",
8328 "offset", "count",
8329 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008330
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008331 sf.headers = NULL;
8332 sf.trailers = NULL;
8333
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008334#ifdef __APPLE__
8335 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008336 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008337#else
8338 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008339 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008340#endif
8341 &headers, &trailers, &flags))
8342 return NULL;
8343 if (headers != NULL) {
8344 if (!PySequence_Check(headers)) {
8345 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008346 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008347 return NULL;
8348 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008349 Py_ssize_t i = PySequence_Size(headers);
8350 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008351 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008352 if (i > INT_MAX) {
8353 PyErr_SetString(PyExc_OverflowError,
8354 "sendfile() header is too large");
8355 return NULL;
8356 }
8357 if (i > 0) {
8358 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008359 if (iov_setup(&(sf.headers), &hbuf,
8360 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008361 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008362#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008363 for (i = 0; i < sf.hdr_cnt; i++) {
8364 Py_ssize_t blen = sf.headers[i].iov_len;
8365# define OFF_T_MAX 0x7fffffffffffffff
8366 if (sbytes >= OFF_T_MAX - blen) {
8367 PyErr_SetString(PyExc_OverflowError,
8368 "sendfile() header is too large");
8369 return NULL;
8370 }
8371 sbytes += blen;
8372 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008373#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008374 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008375 }
8376 }
8377 if (trailers != NULL) {
8378 if (!PySequence_Check(trailers)) {
8379 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008380 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008381 return NULL;
8382 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008383 Py_ssize_t i = PySequence_Size(trailers);
8384 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008385 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008386 if (i > INT_MAX) {
8387 PyErr_SetString(PyExc_OverflowError,
8388 "sendfile() trailer is too large");
8389 return NULL;
8390 }
8391 if (i > 0) {
8392 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008393 if (iov_setup(&(sf.trailers), &tbuf,
8394 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008395 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008396 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008397 }
8398 }
8399
Steve Dower8fc89802015-04-12 00:26:27 -04008400 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008401 do {
8402 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008403#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008404 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008405#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008406 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008407#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008408 Py_END_ALLOW_THREADS
8409 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008410 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008411
8412 if (sf.headers != NULL)
8413 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8414 if (sf.trailers != NULL)
8415 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8416
8417 if (ret < 0) {
8418 if ((errno == EAGAIN) || (errno == EBUSY)) {
8419 if (sbytes != 0) {
8420 // some data has been sent
8421 goto done;
8422 }
8423 else {
8424 // no data has been sent; upper application is supposed
8425 // to retry on EAGAIN or EBUSY
8426 return posix_error();
8427 }
8428 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008429 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008430 }
8431 goto done;
8432
8433done:
8434 #if !defined(HAVE_LARGEFILE_SUPPORT)
8435 return Py_BuildValue("l", sbytes);
8436 #else
8437 return Py_BuildValue("L", sbytes);
8438 #endif
8439
8440#else
8441 Py_ssize_t count;
8442 PyObject *offobj;
8443 static char *keywords[] = {"out", "in",
8444 "offset", "count", NULL};
8445 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8446 keywords, &out, &in, &offobj, &count))
8447 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008448#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008449 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008450 do {
8451 Py_BEGIN_ALLOW_THREADS
8452 ret = sendfile(out, in, NULL, count);
8453 Py_END_ALLOW_THREADS
8454 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008455 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008456 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008457 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008458 }
8459#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008460 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008461 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008462
8463 do {
8464 Py_BEGIN_ALLOW_THREADS
8465 ret = sendfile(out, in, &offset, count);
8466 Py_END_ALLOW_THREADS
8467 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008468 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008469 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008470 return Py_BuildValue("n", ret);
8471#endif
8472}
Larry Hastings2f936352014-08-05 14:04:04 +10008473#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008474
Larry Hastings2f936352014-08-05 14:04:04 +10008475
8476/*[clinic input]
8477os.fstat
8478
8479 fd : int
8480
8481Perform a stat system call on the given file descriptor.
8482
8483Like stat(), but for an open file descriptor.
8484Equivalent to os.stat(fd).
8485[clinic start generated code]*/
8486
Larry Hastings2f936352014-08-05 14:04:04 +10008487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008488os_fstat_impl(PyObject *module, int fd)
8489/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008490{
Victor Stinner8c62be82010-05-06 00:08:46 +00008491 STRUCT_STAT st;
8492 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008493 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008494
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008495 do {
8496 Py_BEGIN_ALLOW_THREADS
8497 res = FSTAT(fd, &st);
8498 Py_END_ALLOW_THREADS
8499 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008500 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008501#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008502 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008503#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008504 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008505#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008506 }
Tim Peters5aa91602002-01-30 05:46:57 +00008507
Victor Stinner4195b5c2012-02-08 23:03:19 +01008508 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008509}
8510
Larry Hastings2f936352014-08-05 14:04:04 +10008511
8512/*[clinic input]
8513os.isatty -> bool
8514 fd: int
8515 /
8516
8517Return True if the fd is connected to a terminal.
8518
8519Return True if the file descriptor is an open file descriptor
8520connected to the slave end of a terminal.
8521[clinic start generated code]*/
8522
Larry Hastings2f936352014-08-05 14:04:04 +10008523static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008524os_isatty_impl(PyObject *module, int fd)
8525/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008526{
Steve Dower8fc89802015-04-12 00:26:27 -04008527 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008528 _Py_BEGIN_SUPPRESS_IPH
8529 return_value = isatty(fd);
8530 _Py_END_SUPPRESS_IPH
8531 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008532}
8533
8534
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008535#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008536/*[clinic input]
8537os.pipe
8538
8539Create a pipe.
8540
8541Returns a tuple of two file descriptors:
8542 (read_fd, write_fd)
8543[clinic start generated code]*/
8544
Larry Hastings2f936352014-08-05 14:04:04 +10008545static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008546os_pipe_impl(PyObject *module)
8547/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008548{
Victor Stinner8c62be82010-05-06 00:08:46 +00008549 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008550#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008552 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008553 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008554#else
8555 int res;
8556#endif
8557
8558#ifdef MS_WINDOWS
8559 attr.nLength = sizeof(attr);
8560 attr.lpSecurityDescriptor = NULL;
8561 attr.bInheritHandle = FALSE;
8562
8563 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008564 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008565 ok = CreatePipe(&read, &write, &attr, 0);
8566 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008567 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8568 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008569 if (fds[0] == -1 || fds[1] == -1) {
8570 CloseHandle(read);
8571 CloseHandle(write);
8572 ok = 0;
8573 }
8574 }
Steve Dowerc3630612016-11-19 18:41:16 -08008575 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008576 Py_END_ALLOW_THREADS
8577
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008579 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008580#else
8581
8582#ifdef HAVE_PIPE2
8583 Py_BEGIN_ALLOW_THREADS
8584 res = pipe2(fds, O_CLOEXEC);
8585 Py_END_ALLOW_THREADS
8586
8587 if (res != 0 && errno == ENOSYS)
8588 {
8589#endif
8590 Py_BEGIN_ALLOW_THREADS
8591 res = pipe(fds);
8592 Py_END_ALLOW_THREADS
8593
8594 if (res == 0) {
8595 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8596 close(fds[0]);
8597 close(fds[1]);
8598 return NULL;
8599 }
8600 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8601 close(fds[0]);
8602 close(fds[1]);
8603 return NULL;
8604 }
8605 }
8606#ifdef HAVE_PIPE2
8607 }
8608#endif
8609
8610 if (res != 0)
8611 return PyErr_SetFromErrno(PyExc_OSError);
8612#endif /* !MS_WINDOWS */
8613 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008614}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008615#endif /* HAVE_PIPE */
8616
Larry Hastings2f936352014-08-05 14:04:04 +10008617
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008618#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008619/*[clinic input]
8620os.pipe2
8621
8622 flags: int
8623 /
8624
8625Create a pipe with flags set atomically.
8626
8627Returns a tuple of two file descriptors:
8628 (read_fd, write_fd)
8629
8630flags can be constructed by ORing together one or more of these values:
8631O_NONBLOCK, O_CLOEXEC.
8632[clinic start generated code]*/
8633
Larry Hastings2f936352014-08-05 14:04:04 +10008634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008635os_pipe2_impl(PyObject *module, int flags)
8636/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008637{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008638 int fds[2];
8639 int res;
8640
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008641 res = pipe2(fds, flags);
8642 if (res != 0)
8643 return posix_error();
8644 return Py_BuildValue("(ii)", fds[0], fds[1]);
8645}
8646#endif /* HAVE_PIPE2 */
8647
Larry Hastings2f936352014-08-05 14:04:04 +10008648
Ross Lagerwall7807c352011-03-17 20:20:30 +02008649#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008650/*[clinic input]
8651os.writev -> Py_ssize_t
8652 fd: int
8653 buffers: object
8654 /
8655
8656Iterate over buffers, and write the contents of each to a file descriptor.
8657
8658Returns the total number of bytes written.
8659buffers must be a sequence of bytes-like objects.
8660[clinic start generated code]*/
8661
Larry Hastings2f936352014-08-05 14:04:04 +10008662static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008663os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8664/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008665{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008666 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008667 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008668 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008669 struct iovec *iov;
8670 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008671
8672 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008673 PyErr_SetString(PyExc_TypeError,
8674 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008675 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008676 }
Larry Hastings2f936352014-08-05 14:04:04 +10008677 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008678 if (cnt < 0)
8679 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008680
Larry Hastings2f936352014-08-05 14:04:04 +10008681 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8682 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683 }
8684
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008685 do {
8686 Py_BEGIN_ALLOW_THREADS
8687 result = writev(fd, iov, cnt);
8688 Py_END_ALLOW_THREADS
8689 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008690
8691 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008692 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008693 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008694
Georg Brandl306336b2012-06-24 12:55:33 +02008695 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696}
Larry Hastings2f936352014-08-05 14:04:04 +10008697#endif /* HAVE_WRITEV */
8698
8699
8700#ifdef HAVE_PWRITE
8701/*[clinic input]
8702os.pwrite -> Py_ssize_t
8703
8704 fd: int
8705 buffer: Py_buffer
8706 offset: Py_off_t
8707 /
8708
8709Write bytes to a file descriptor starting at a particular offset.
8710
8711Write buffer to fd, starting at offset bytes from the beginning of
8712the file. Returns the number of bytes writte. Does not change the
8713current file offset.
8714[clinic start generated code]*/
8715
Larry Hastings2f936352014-08-05 14:04:04 +10008716static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008717os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8718/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008719{
8720 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008721 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008722
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008723 do {
8724 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008725 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008726 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008727 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008728 Py_END_ALLOW_THREADS
8729 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008730
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008731 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008732 posix_error();
8733 return size;
8734}
8735#endif /* HAVE_PWRITE */
8736
Pablo Galindo4defba32018-01-27 16:16:37 +00008737#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8738/*[clinic input]
8739os.pwritev -> Py_ssize_t
8740
8741 fd: int
8742 buffers: object
8743 offset: Py_off_t
8744 flags: int = 0
8745 /
8746
8747Writes the contents of bytes-like objects to a file descriptor at a given offset.
8748
8749Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8750of bytes-like objects. Buffers are processed in array order. Entire contents of first
8751buffer is written before proceeding to second, and so on. The operating system may
8752set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8753This function writes the contents of each object to the file descriptor and returns
8754the total number of bytes written.
8755
8756The flags argument contains a bitwise OR of zero or more of the following flags:
8757
8758- RWF_DSYNC
8759- RWF_SYNC
8760
8761Using non-zero flags requires Linux 4.7 or newer.
8762[clinic start generated code]*/
8763
8764static Py_ssize_t
8765os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8766 int flags)
8767/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8768{
8769 Py_ssize_t cnt;
8770 Py_ssize_t result;
8771 int async_err = 0;
8772 struct iovec *iov;
8773 Py_buffer *buf;
8774
8775 if (!PySequence_Check(buffers)) {
8776 PyErr_SetString(PyExc_TypeError,
8777 "pwritev() arg 2 must be a sequence");
8778 return -1;
8779 }
8780
8781 cnt = PySequence_Size(buffers);
8782 if (cnt < 0) {
8783 return -1;
8784 }
8785
8786#ifndef HAVE_PWRITEV2
8787 if(flags != 0) {
8788 argument_unavailable_error("pwritev2", "flags");
8789 return -1;
8790 }
8791#endif
8792
8793 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8794 return -1;
8795 }
8796#ifdef HAVE_PWRITEV2
8797 do {
8798 Py_BEGIN_ALLOW_THREADS
8799 _Py_BEGIN_SUPPRESS_IPH
8800 result = pwritev2(fd, iov, cnt, offset, flags);
8801 _Py_END_SUPPRESS_IPH
8802 Py_END_ALLOW_THREADS
8803 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8804#else
8805 do {
8806 Py_BEGIN_ALLOW_THREADS
8807 _Py_BEGIN_SUPPRESS_IPH
8808 result = pwritev(fd, iov, cnt, offset);
8809 _Py_END_SUPPRESS_IPH
8810 Py_END_ALLOW_THREADS
8811 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8812#endif
8813
8814 iov_cleanup(iov, buf, cnt);
8815 if (result < 0) {
8816 if (!async_err) {
8817 posix_error();
8818 }
8819 return -1;
8820 }
8821
8822 return result;
8823}
8824#endif /* HAVE_PWRITEV */
8825
8826
8827
Larry Hastings2f936352014-08-05 14:04:04 +10008828
8829#ifdef HAVE_MKFIFO
8830/*[clinic input]
8831os.mkfifo
8832
8833 path: path_t
8834 mode: int=0o666
8835 *
8836 dir_fd: dir_fd(requires='mkfifoat')=None
8837
8838Create a "fifo" (a POSIX named pipe).
8839
8840If dir_fd is not None, it should be a file descriptor open to a directory,
8841 and path should be relative; path will then be relative to that directory.
8842dir_fd may not be implemented on your platform.
8843 If it is unavailable, using it will raise a NotImplementedError.
8844[clinic start generated code]*/
8845
Larry Hastings2f936352014-08-05 14:04:04 +10008846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008847os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8848/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008849{
8850 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008851 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008852
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008853 do {
8854 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008855#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008856 if (dir_fd != DEFAULT_DIR_FD)
8857 result = mkfifoat(dir_fd, path->narrow, mode);
8858 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008859#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008860 result = mkfifo(path->narrow, mode);
8861 Py_END_ALLOW_THREADS
8862 } while (result != 0 && errno == EINTR &&
8863 !(async_err = PyErr_CheckSignals()));
8864 if (result != 0)
8865 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008866
8867 Py_RETURN_NONE;
8868}
8869#endif /* HAVE_MKFIFO */
8870
8871
8872#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8873/*[clinic input]
8874os.mknod
8875
8876 path: path_t
8877 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008878 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008879 *
8880 dir_fd: dir_fd(requires='mknodat')=None
8881
8882Create a node in the file system.
8883
8884Create a node in the file system (file, device special file or named pipe)
8885at path. mode specifies both the permissions to use and the
8886type of node to be created, being combined (bitwise OR) with one of
8887S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8888device defines the newly created device special file (probably using
8889os.makedev()). Otherwise device is ignored.
8890
8891If dir_fd is not None, it should be a file descriptor open to a directory,
8892 and path should be relative; path will then be relative to that directory.
8893dir_fd may not be implemented on your platform.
8894 If it is unavailable, using it will raise a NotImplementedError.
8895[clinic start generated code]*/
8896
Larry Hastings2f936352014-08-05 14:04:04 +10008897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008898os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008899 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008900/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008901{
8902 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008903 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008904
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008905 do {
8906 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008907#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008908 if (dir_fd != DEFAULT_DIR_FD)
8909 result = mknodat(dir_fd, path->narrow, mode, device);
8910 else
Larry Hastings2f936352014-08-05 14:04:04 +10008911#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008912 result = mknod(path->narrow, mode, device);
8913 Py_END_ALLOW_THREADS
8914 } while (result != 0 && errno == EINTR &&
8915 !(async_err = PyErr_CheckSignals()));
8916 if (result != 0)
8917 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008918
8919 Py_RETURN_NONE;
8920}
8921#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8922
8923
8924#ifdef HAVE_DEVICE_MACROS
8925/*[clinic input]
8926os.major -> unsigned_int
8927
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008928 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008929 /
8930
8931Extracts a device major number from a raw device number.
8932[clinic start generated code]*/
8933
Larry Hastings2f936352014-08-05 14:04:04 +10008934static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008935os_major_impl(PyObject *module, dev_t device)
8936/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008937{
8938 return major(device);
8939}
8940
8941
8942/*[clinic input]
8943os.minor -> unsigned_int
8944
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008945 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008946 /
8947
8948Extracts a device minor number from a raw device number.
8949[clinic start generated code]*/
8950
Larry Hastings2f936352014-08-05 14:04:04 +10008951static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008952os_minor_impl(PyObject *module, dev_t device)
8953/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008954{
8955 return minor(device);
8956}
8957
8958
8959/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008960os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008961
8962 major: int
8963 minor: int
8964 /
8965
8966Composes a raw device number from the major and minor device numbers.
8967[clinic start generated code]*/
8968
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008969static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008970os_makedev_impl(PyObject *module, int major, int minor)
8971/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008972{
8973 return makedev(major, minor);
8974}
8975#endif /* HAVE_DEVICE_MACROS */
8976
8977
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008978#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008979/*[clinic input]
8980os.ftruncate
8981
8982 fd: int
8983 length: Py_off_t
8984 /
8985
8986Truncate a file, specified by file descriptor, to a specific length.
8987[clinic start generated code]*/
8988
Larry Hastings2f936352014-08-05 14:04:04 +10008989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008990os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8991/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008992{
8993 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008994 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008995
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008996 do {
8997 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008998 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008999#ifdef MS_WINDOWS
9000 result = _chsize_s(fd, length);
9001#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009002 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009003#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009004 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009005 Py_END_ALLOW_THREADS
9006 } while (result != 0 && errno == EINTR &&
9007 !(async_err = PyErr_CheckSignals()));
9008 if (result != 0)
9009 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009010 Py_RETURN_NONE;
9011}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009012#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009013
9014
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009015#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009016/*[clinic input]
9017os.truncate
9018 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9019 length: Py_off_t
9020
9021Truncate a file, specified by path, to a specific length.
9022
9023On some platforms, path may also be specified as an open file descriptor.
9024 If this functionality is unavailable, using it raises an exception.
9025[clinic start generated code]*/
9026
Larry Hastings2f936352014-08-05 14:04:04 +10009027static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009028os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9029/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009030{
9031 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009032#ifdef MS_WINDOWS
9033 int fd;
9034#endif
9035
9036 if (path->fd != -1)
9037 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009038
9039 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009040 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009041#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009042 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009043 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009044 result = -1;
9045 else {
9046 result = _chsize_s(fd, length);
9047 close(fd);
9048 if (result < 0)
9049 errno = result;
9050 }
9051#else
9052 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009053#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009054 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009055 Py_END_ALLOW_THREADS
9056 if (result < 0)
9057 return path_error(path);
9058
9059 Py_RETURN_NONE;
9060}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009061#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009062
Ross Lagerwall7807c352011-03-17 20:20:30 +02009063
Victor Stinnerd6b17692014-09-30 12:20:05 +02009064/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9065 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9066 defined, which is the case in Python on AIX. AIX bug report:
9067 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9068#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9069# define POSIX_FADVISE_AIX_BUG
9070#endif
9071
Victor Stinnerec39e262014-09-30 12:35:58 +02009072
Victor Stinnerd6b17692014-09-30 12:20:05 +02009073#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009074/*[clinic input]
9075os.posix_fallocate
9076
9077 fd: int
9078 offset: Py_off_t
9079 length: Py_off_t
9080 /
9081
9082Ensure a file has allocated at least a particular number of bytes on disk.
9083
9084Ensure that the file specified by fd encompasses a range of bytes
9085starting at offset bytes from the beginning and continuing for length bytes.
9086[clinic start generated code]*/
9087
Larry Hastings2f936352014-08-05 14:04:04 +10009088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009089os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009090 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009091/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009092{
9093 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009094 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009095
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009096 do {
9097 Py_BEGIN_ALLOW_THREADS
9098 result = posix_fallocate(fd, offset, length);
9099 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009100 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9101
9102 if (result == 0)
9103 Py_RETURN_NONE;
9104
9105 if (async_err)
9106 return NULL;
9107
9108 errno = result;
9109 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009110}
Victor Stinnerec39e262014-09-30 12:35:58 +02009111#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009112
Ross Lagerwall7807c352011-03-17 20:20:30 +02009113
Victor Stinnerd6b17692014-09-30 12:20:05 +02009114#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009115/*[clinic input]
9116os.posix_fadvise
9117
9118 fd: int
9119 offset: Py_off_t
9120 length: Py_off_t
9121 advice: int
9122 /
9123
9124Announce an intention to access data in a specific pattern.
9125
9126Announce an intention to access data in a specific pattern, thus allowing
9127the kernel to make optimizations.
9128The advice applies to the region of the file specified by fd starting at
9129offset and continuing for length bytes.
9130advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9131POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9132POSIX_FADV_DONTNEED.
9133[clinic start generated code]*/
9134
Larry Hastings2f936352014-08-05 14:04:04 +10009135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009136os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009137 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009138/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009139{
9140 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009141 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009142
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009143 do {
9144 Py_BEGIN_ALLOW_THREADS
9145 result = posix_fadvise(fd, offset, length, advice);
9146 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009147 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9148
9149 if (result == 0)
9150 Py_RETURN_NONE;
9151
9152 if (async_err)
9153 return NULL;
9154
9155 errno = result;
9156 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009157}
Victor Stinnerec39e262014-09-30 12:35:58 +02009158#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009159
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009160#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009161
Fred Drake762e2061999-08-26 17:23:54 +00009162/* Save putenv() parameters as values here, so we can collect them when they
9163 * get re-set with another call for the same key. */
9164static PyObject *posix_putenv_garbage;
9165
Larry Hastings2f936352014-08-05 14:04:04 +10009166static void
9167posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009168{
Larry Hastings2f936352014-08-05 14:04:04 +10009169 /* Install the first arg and newstr in posix_putenv_garbage;
9170 * this will cause previous value to be collected. This has to
9171 * happen after the real putenv() call because the old value
9172 * was still accessible until then. */
9173 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9174 /* really not much we can do; just leak */
9175 PyErr_Clear();
9176 else
9177 Py_DECREF(value);
9178}
9179
9180
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009181#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009182/*[clinic input]
9183os.putenv
9184
9185 name: unicode
9186 value: unicode
9187 /
9188
9189Change or add an environment variable.
9190[clinic start generated code]*/
9191
Larry Hastings2f936352014-08-05 14:04:04 +10009192static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009193os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9194/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009195{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009196 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009197 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009198
Serhiy Storchaka77703942017-06-25 07:33:01 +03009199 /* Search from index 1 because on Windows starting '=' is allowed for
9200 defining hidden environment variables. */
9201 if (PyUnicode_GET_LENGTH(name) == 0 ||
9202 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9203 {
9204 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9205 return NULL;
9206 }
Larry Hastings2f936352014-08-05 14:04:04 +10009207 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9208 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009209 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009210 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009211
9212 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9213 if (env == NULL)
9214 goto error;
9215 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009216 PyErr_Format(PyExc_ValueError,
9217 "the environment variable is longer than %u characters",
9218 _MAX_ENV);
9219 goto error;
9220 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009221 if (wcslen(env) != (size_t)size) {
9222 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009223 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009224 }
9225
Larry Hastings2f936352014-08-05 14:04:04 +10009226 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009228 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009230
Larry Hastings2f936352014-08-05 14:04:04 +10009231 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009232 Py_RETURN_NONE;
9233
9234error:
Larry Hastings2f936352014-08-05 14:04:04 +10009235 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009236 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009237}
Larry Hastings2f936352014-08-05 14:04:04 +10009238#else /* MS_WINDOWS */
9239/*[clinic input]
9240os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009241
Larry Hastings2f936352014-08-05 14:04:04 +10009242 name: FSConverter
9243 value: FSConverter
9244 /
9245
9246Change or add an environment variable.
9247[clinic start generated code]*/
9248
Larry Hastings2f936352014-08-05 14:04:04 +10009249static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009250os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9251/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009252{
9253 PyObject *bytes = NULL;
9254 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009255 const char *name_string = PyBytes_AS_STRING(name);
9256 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009257
Serhiy Storchaka77703942017-06-25 07:33:01 +03009258 if (strchr(name_string, '=') != NULL) {
9259 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9260 return NULL;
9261 }
Larry Hastings2f936352014-08-05 14:04:04 +10009262 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9263 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009264 return NULL;
9265 }
9266
9267 env = PyBytes_AS_STRING(bytes);
9268 if (putenv(env)) {
9269 Py_DECREF(bytes);
9270 return posix_error();
9271 }
9272
9273 posix_putenv_garbage_setitem(name, bytes);
9274 Py_RETURN_NONE;
9275}
9276#endif /* MS_WINDOWS */
9277#endif /* HAVE_PUTENV */
9278
9279
9280#ifdef HAVE_UNSETENV
9281/*[clinic input]
9282os.unsetenv
9283 name: FSConverter
9284 /
9285
9286Delete an environment variable.
9287[clinic start generated code]*/
9288
Larry Hastings2f936352014-08-05 14:04:04 +10009289static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009290os_unsetenv_impl(PyObject *module, PyObject *name)
9291/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009292{
Victor Stinner984890f2011-11-24 13:53:38 +01009293#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009294 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009295#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009296
Victor Stinner984890f2011-11-24 13:53:38 +01009297#ifdef HAVE_BROKEN_UNSETENV
9298 unsetenv(PyBytes_AS_STRING(name));
9299#else
Victor Stinner65170952011-11-22 22:16:17 +01009300 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009301 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009302 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009303#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009304
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 /* Remove the key from posix_putenv_garbage;
9306 * this will cause it to be collected. This has to
9307 * happen after the real unsetenv() call because the
9308 * old value was still accessible until then.
9309 */
Victor Stinner65170952011-11-22 22:16:17 +01009310 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 /* really not much we can do; just leak */
9312 PyErr_Clear();
9313 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009314 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009315}
Larry Hastings2f936352014-08-05 14:04:04 +10009316#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009317
Larry Hastings2f936352014-08-05 14:04:04 +10009318
9319/*[clinic input]
9320os.strerror
9321
9322 code: int
9323 /
9324
9325Translate an error code to a message string.
9326[clinic start generated code]*/
9327
Larry Hastings2f936352014-08-05 14:04:04 +10009328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009329os_strerror_impl(PyObject *module, int code)
9330/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009331{
9332 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 if (message == NULL) {
9334 PyErr_SetString(PyExc_ValueError,
9335 "strerror() argument out of range");
9336 return NULL;
9337 }
Victor Stinner1b579672011-12-17 05:47:23 +01009338 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009339}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009340
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009341
Guido van Rossumc9641791998-08-04 15:26:23 +00009342#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009343#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009344/*[clinic input]
9345os.WCOREDUMP -> bool
9346
9347 status: int
9348 /
9349
9350Return True if the process returning status was dumped to a core file.
9351[clinic start generated code]*/
9352
Larry Hastings2f936352014-08-05 14:04:04 +10009353static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009354os_WCOREDUMP_impl(PyObject *module, int status)
9355/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009356{
9357 WAIT_TYPE wait_status;
9358 WAIT_STATUS_INT(wait_status) = status;
9359 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009360}
9361#endif /* WCOREDUMP */
9362
Larry Hastings2f936352014-08-05 14:04:04 +10009363
Fred Drake106c1a02002-04-23 15:58:02 +00009364#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009365/*[clinic input]
9366os.WIFCONTINUED -> bool
9367
9368 status: int
9369
9370Return True if a particular process was continued from a job control stop.
9371
9372Return True if the process returning status was continued from a
9373job control stop.
9374[clinic start generated code]*/
9375
Larry Hastings2f936352014-08-05 14:04:04 +10009376static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009377os_WIFCONTINUED_impl(PyObject *module, int status)
9378/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009379{
9380 WAIT_TYPE wait_status;
9381 WAIT_STATUS_INT(wait_status) = status;
9382 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009383}
9384#endif /* WIFCONTINUED */
9385
Larry Hastings2f936352014-08-05 14:04:04 +10009386
Guido van Rossumc9641791998-08-04 15:26:23 +00009387#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009388/*[clinic input]
9389os.WIFSTOPPED -> bool
9390
9391 status: int
9392
9393Return True if the process returning status was stopped.
9394[clinic start generated code]*/
9395
Larry Hastings2f936352014-08-05 14:04:04 +10009396static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009397os_WIFSTOPPED_impl(PyObject *module, int status)
9398/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009399{
9400 WAIT_TYPE wait_status;
9401 WAIT_STATUS_INT(wait_status) = status;
9402 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009403}
9404#endif /* WIFSTOPPED */
9405
Larry Hastings2f936352014-08-05 14:04:04 +10009406
Guido van Rossumc9641791998-08-04 15:26:23 +00009407#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009408/*[clinic input]
9409os.WIFSIGNALED -> bool
9410
9411 status: int
9412
9413Return True if the process returning status was terminated by a signal.
9414[clinic start generated code]*/
9415
Larry Hastings2f936352014-08-05 14:04:04 +10009416static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009417os_WIFSIGNALED_impl(PyObject *module, int status)
9418/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009419{
9420 WAIT_TYPE wait_status;
9421 WAIT_STATUS_INT(wait_status) = status;
9422 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009423}
9424#endif /* WIFSIGNALED */
9425
Larry Hastings2f936352014-08-05 14:04:04 +10009426
Guido van Rossumc9641791998-08-04 15:26:23 +00009427#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009428/*[clinic input]
9429os.WIFEXITED -> bool
9430
9431 status: int
9432
9433Return True if the process returning status exited via the exit() system call.
9434[clinic start generated code]*/
9435
Larry Hastings2f936352014-08-05 14:04:04 +10009436static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009437os_WIFEXITED_impl(PyObject *module, int status)
9438/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009439{
9440 WAIT_TYPE wait_status;
9441 WAIT_STATUS_INT(wait_status) = status;
9442 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009443}
9444#endif /* WIFEXITED */
9445
Larry Hastings2f936352014-08-05 14:04:04 +10009446
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009447#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009448/*[clinic input]
9449os.WEXITSTATUS -> int
9450
9451 status: int
9452
9453Return the process return code from status.
9454[clinic start generated code]*/
9455
Larry Hastings2f936352014-08-05 14:04:04 +10009456static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009457os_WEXITSTATUS_impl(PyObject *module, int status)
9458/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009459{
9460 WAIT_TYPE wait_status;
9461 WAIT_STATUS_INT(wait_status) = status;
9462 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009463}
9464#endif /* WEXITSTATUS */
9465
Larry Hastings2f936352014-08-05 14:04:04 +10009466
Guido van Rossumc9641791998-08-04 15:26:23 +00009467#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009468/*[clinic input]
9469os.WTERMSIG -> int
9470
9471 status: int
9472
9473Return the signal that terminated the process that provided the status value.
9474[clinic start generated code]*/
9475
Larry Hastings2f936352014-08-05 14:04:04 +10009476static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009477os_WTERMSIG_impl(PyObject *module, int status)
9478/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009479{
9480 WAIT_TYPE wait_status;
9481 WAIT_STATUS_INT(wait_status) = status;
9482 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009483}
9484#endif /* WTERMSIG */
9485
Larry Hastings2f936352014-08-05 14:04:04 +10009486
Guido van Rossumc9641791998-08-04 15:26:23 +00009487#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009488/*[clinic input]
9489os.WSTOPSIG -> int
9490
9491 status: int
9492
9493Return the signal that stopped the process that provided the status value.
9494[clinic start generated code]*/
9495
Larry Hastings2f936352014-08-05 14:04:04 +10009496static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009497os_WSTOPSIG_impl(PyObject *module, int status)
9498/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009499{
9500 WAIT_TYPE wait_status;
9501 WAIT_STATUS_INT(wait_status) = status;
9502 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009503}
9504#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009505#endif /* HAVE_SYS_WAIT_H */
9506
9507
Thomas Wouters477c8d52006-05-27 19:21:47 +00009508#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009509#ifdef _SCO_DS
9510/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9511 needed definitions in sys/statvfs.h */
9512#define _SVID3
9513#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009514#include <sys/statvfs.h>
9515
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009516static PyObject*
9517_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9519 if (v == NULL)
9520 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009521
9522#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9524 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9525 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9526 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9527 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9528 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9529 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9530 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9531 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9532 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009533#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9535 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9536 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009537 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009539 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009541 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009543 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009545 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009547 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9549 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009550#endif
Michael Felt502d5512018-01-05 13:01:58 +01009551/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9552 * (issue #32390). */
9553#if defined(_AIX) && defined(_ALL_SOURCE)
9554 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9555#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009556 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009557#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009558 if (PyErr_Occurred()) {
9559 Py_DECREF(v);
9560 return NULL;
9561 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009562
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009564}
9565
Larry Hastings2f936352014-08-05 14:04:04 +10009566
9567/*[clinic input]
9568os.fstatvfs
9569 fd: int
9570 /
9571
9572Perform an fstatvfs system call on the given fd.
9573
9574Equivalent to statvfs(fd).
9575[clinic start generated code]*/
9576
Larry Hastings2f936352014-08-05 14:04:04 +10009577static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009578os_fstatvfs_impl(PyObject *module, int fd)
9579/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009580{
9581 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009582 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009584
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009585 do {
9586 Py_BEGIN_ALLOW_THREADS
9587 result = fstatvfs(fd, &st);
9588 Py_END_ALLOW_THREADS
9589 } while (result != 0 && errno == EINTR &&
9590 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009591 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009592 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009593
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009595}
Larry Hastings2f936352014-08-05 14:04:04 +10009596#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009597
9598
Thomas Wouters477c8d52006-05-27 19:21:47 +00009599#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009600#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009601/*[clinic input]
9602os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009603
Larry Hastings2f936352014-08-05 14:04:04 +10009604 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9605
9606Perform a statvfs system call on the given path.
9607
9608path may always be specified as a string.
9609On some platforms, path may also be specified as an open file descriptor.
9610 If this functionality is unavailable, using it raises an exception.
9611[clinic start generated code]*/
9612
Larry Hastings2f936352014-08-05 14:04:04 +10009613static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009614os_statvfs_impl(PyObject *module, path_t *path)
9615/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009616{
9617 int result;
9618 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009619
9620 Py_BEGIN_ALLOW_THREADS
9621#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009622 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009623#ifdef __APPLE__
9624 /* handle weak-linking on Mac OS X 10.3 */
9625 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009626 fd_specified("statvfs", path->fd);
9627 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009628 }
9629#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009630 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009631 }
9632 else
9633#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009634 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009635 Py_END_ALLOW_THREADS
9636
9637 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009638 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009639 }
9640
Larry Hastings2f936352014-08-05 14:04:04 +10009641 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009642}
Larry Hastings2f936352014-08-05 14:04:04 +10009643#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9644
Guido van Rossum94f6f721999-01-06 18:42:14 +00009645
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009646#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009647/*[clinic input]
9648os._getdiskusage
9649
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009650 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009651
9652Return disk usage statistics about the given path as a (total, free) tuple.
9653[clinic start generated code]*/
9654
Larry Hastings2f936352014-08-05 14:04:04 +10009655static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009656os__getdiskusage_impl(PyObject *module, path_t *path)
9657/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009658{
9659 BOOL retval;
9660 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009661
9662 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009663 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009664 Py_END_ALLOW_THREADS
9665 if (retval == 0)
9666 return PyErr_SetFromWindowsErr(0);
9667
9668 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9669}
Larry Hastings2f936352014-08-05 14:04:04 +10009670#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009671
9672
Fred Drakec9680921999-12-13 16:37:25 +00009673/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9674 * It maps strings representing configuration variable names to
9675 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009676 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009677 * rarely-used constants. There are three separate tables that use
9678 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009679 *
9680 * This code is always included, even if none of the interfaces that
9681 * need it are included. The #if hackery needed to avoid it would be
9682 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009683 */
9684struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009685 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009686 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009687};
9688
Fred Drake12c6e2d1999-12-14 21:25:03 +00009689static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009690conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009691 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009692{
Christian Heimes217cfd12007-12-02 14:31:20 +00009693 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009694 int value = _PyLong_AsInt(arg);
9695 if (value == -1 && PyErr_Occurred())
9696 return 0;
9697 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009698 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009699 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009700 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009701 /* look up the value in the table using a binary search */
9702 size_t lo = 0;
9703 size_t mid;
9704 size_t hi = tablesize;
9705 int cmp;
9706 const char *confname;
9707 if (!PyUnicode_Check(arg)) {
9708 PyErr_SetString(PyExc_TypeError,
9709 "configuration names must be strings or integers");
9710 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009712 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009713 if (confname == NULL)
9714 return 0;
9715 while (lo < hi) {
9716 mid = (lo + hi) / 2;
9717 cmp = strcmp(confname, table[mid].name);
9718 if (cmp < 0)
9719 hi = mid;
9720 else if (cmp > 0)
9721 lo = mid + 1;
9722 else {
9723 *valuep = table[mid].value;
9724 return 1;
9725 }
9726 }
9727 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9728 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009730}
9731
9732
9733#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9734static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009735#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009737#endif
9738#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009740#endif
Fred Drakec9680921999-12-13 16:37:25 +00009741#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009786#ifdef _PC_ACL_ENABLED
9787 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9788#endif
9789#ifdef _PC_MIN_HOLE_SIZE
9790 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9791#endif
9792#ifdef _PC_ALLOC_SIZE_MIN
9793 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9794#endif
9795#ifdef _PC_REC_INCR_XFER_SIZE
9796 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9797#endif
9798#ifdef _PC_REC_MAX_XFER_SIZE
9799 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9800#endif
9801#ifdef _PC_REC_MIN_XFER_SIZE
9802 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9803#endif
9804#ifdef _PC_REC_XFER_ALIGN
9805 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9806#endif
9807#ifdef _PC_SYMLINK_MAX
9808 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9809#endif
9810#ifdef _PC_XATTR_ENABLED
9811 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9812#endif
9813#ifdef _PC_XATTR_EXISTS
9814 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9815#endif
9816#ifdef _PC_TIMESTAMP_RESOLUTION
9817 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9818#endif
Fred Drakec9680921999-12-13 16:37:25 +00009819};
9820
Fred Drakec9680921999-12-13 16:37:25 +00009821static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009822conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009823{
9824 return conv_confname(arg, valuep, posix_constants_pathconf,
9825 sizeof(posix_constants_pathconf)
9826 / sizeof(struct constdef));
9827}
9828#endif
9829
Larry Hastings2f936352014-08-05 14:04:04 +10009830
Fred Drakec9680921999-12-13 16:37:25 +00009831#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009832/*[clinic input]
9833os.fpathconf -> long
9834
9835 fd: int
9836 name: path_confname
9837 /
9838
9839Return the configuration limit name for the file descriptor fd.
9840
9841If there is no limit, return -1.
9842[clinic start generated code]*/
9843
Larry Hastings2f936352014-08-05 14:04:04 +10009844static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009845os_fpathconf_impl(PyObject *module, int fd, int name)
9846/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009847{
9848 long limit;
9849
9850 errno = 0;
9851 limit = fpathconf(fd, name);
9852 if (limit == -1 && errno != 0)
9853 posix_error();
9854
9855 return limit;
9856}
9857#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009858
9859
9860#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009861/*[clinic input]
9862os.pathconf -> long
9863 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9864 name: path_confname
9865
9866Return the configuration limit name for the file or directory path.
9867
9868If there is no limit, return -1.
9869On some platforms, path may also be specified as an open file descriptor.
9870 If this functionality is unavailable, using it raises an exception.
9871[clinic start generated code]*/
9872
Larry Hastings2f936352014-08-05 14:04:04 +10009873static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009874os_pathconf_impl(PyObject *module, path_t *path, int name)
9875/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009876{
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009878
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009880#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009881 if (path->fd != -1)
9882 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009883 else
9884#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009885 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 if (limit == -1 && errno != 0) {
9887 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009888 /* could be a path or name problem */
9889 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009890 else
Larry Hastings2f936352014-08-05 14:04:04 +10009891 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 }
Larry Hastings2f936352014-08-05 14:04:04 +10009893
9894 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009895}
Larry Hastings2f936352014-08-05 14:04:04 +10009896#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009897
9898#ifdef HAVE_CONFSTR
9899static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009900#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009902#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009903#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009905#endif
9906#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009908#endif
Fred Draked86ed291999-12-15 15:34:33 +00009909#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009911#endif
9912#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009914#endif
9915#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009917#endif
9918#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009920#endif
Fred Drakec9680921999-12-13 16:37:25 +00009921#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
Fred Draked86ed291999-12-15 15:34:33 +00009945#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009947#endif
Fred Drakec9680921999-12-13 16:37:25 +00009948#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
Fred Draked86ed291999-12-15 15:34:33 +00009951#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009953#endif
9954#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009956#endif
9957#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009959#endif
9960#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009962#endif
Fred Drakec9680921999-12-13 16:37:25 +00009963#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
Fred Draked86ed291999-12-15 15:34:33 +000010011#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010013#endif
10014#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010016#endif
10017#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010019#endif
10020#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010022#endif
10023#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010025#endif
10026#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010028#endif
10029#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010031#endif
10032#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
10035#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010037#endif
10038#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010040#endif
10041#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010043#endif
10044#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010046#endif
10047#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010049#endif
Fred Drakec9680921999-12-13 16:37:25 +000010050};
10051
10052static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010053conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010054{
10055 return conv_confname(arg, valuep, posix_constants_confstr,
10056 sizeof(posix_constants_confstr)
10057 / sizeof(struct constdef));
10058}
10059
Larry Hastings2f936352014-08-05 14:04:04 +100010060
10061/*[clinic input]
10062os.confstr
10063
10064 name: confstr_confname
10065 /
10066
10067Return a string-valued system configuration variable.
10068[clinic start generated code]*/
10069
Larry Hastings2f936352014-08-05 14:04:04 +100010070static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010071os_confstr_impl(PyObject *module, int name)
10072/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010073{
10074 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010075 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010076 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010077
Victor Stinnercb043522010-09-10 23:49:04 +000010078 errno = 0;
10079 len = confstr(name, buffer, sizeof(buffer));
10080 if (len == 0) {
10081 if (errno) {
10082 posix_error();
10083 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010084 }
10085 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010086 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010087 }
10088 }
Victor Stinnercb043522010-09-10 23:49:04 +000010089
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010090 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010091 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010092 char *buf = PyMem_Malloc(len);
10093 if (buf == NULL)
10094 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010095 len2 = confstr(name, buf, len);
10096 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010097 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010098 PyMem_Free(buf);
10099 }
10100 else
10101 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010102 return result;
10103}
Larry Hastings2f936352014-08-05 14:04:04 +100010104#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010105
10106
10107#ifdef HAVE_SYSCONF
10108static struct constdef posix_constants_sysconf[] = {
10109#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
Fred Draked86ed291999-12-15 15:34:33 +000010139#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010141#endif
10142#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010144#endif
Fred Drakec9680921999-12-13 16:37:25 +000010145#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
Fred Drakec9680921999-12-13 16:37:25 +000010148#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
Fred Draked86ed291999-12-15 15:34:33 +000010163#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010165#endif
Fred Drakec9680921999-12-13 16:37:25 +000010166#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
Fred Draked86ed291999-12-15 15:34:33 +000010181#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010183#endif
Fred Drakec9680921999-12-13 16:37:25 +000010184#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
Fred Draked86ed291999-12-15 15:34:33 +000010253#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010255#endif
Fred Drakec9680921999-12-13 16:37:25 +000010256#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
Fred Draked86ed291999-12-15 15:34:33 +000010265#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010267#endif
Fred Drakec9680921999-12-13 16:37:25 +000010268#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
Fred Draked86ed291999-12-15 15:34:33 +000010271#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
10274#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010276#endif
Fred Drakec9680921999-12-13 16:37:25 +000010277#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
Fred Draked86ed291999-12-15 15:34:33 +000010289#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010291#endif
Fred Drakec9680921999-12-13 16:37:25 +000010292#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
Fred Draked86ed291999-12-15 15:34:33 +000010313#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010315#endif
Fred Drakec9680921999-12-13 16:37:25 +000010316#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
Fred Draked86ed291999-12-15 15:34:33 +000010322#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010324#endif
Fred Drakec9680921999-12-13 16:37:25 +000010325#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
Fred Draked86ed291999-12-15 15:34:33 +000010352#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010354#endif
10355#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010357#endif
Fred Drakec9680921999-12-13 16:37:25 +000010358#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
10430#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010432#endif
10433#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
10448#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010450#endif
10451#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010453#endif
10454#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010456#endif
10457#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010459#endif
10460#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010462#endif
Fred Draked86ed291999-12-15 15:34:33 +000010463#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010465#endif
Fred Drakec9680921999-12-13 16:37:25 +000010466#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010468#endif
10469#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010471#endif
10472#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010474#endif
10475#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010477#endif
10478#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010480#endif
10481#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010483#endif
10484#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
10511#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010513#endif
10514#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
10517#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010519#endif
10520#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010522#endif
10523#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010525#endif
10526#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010528#endif
10529#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010531#endif
10532#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010534#endif
10535#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010537#endif
10538#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010540#endif
10541#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010543#endif
10544#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010546#endif
10547#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
10577#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010579#endif
10580#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010582#endif
10583#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010585#endif
10586#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010588#endif
10589#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010591#endif
10592#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010594#endif
10595#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010597#endif
10598#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010600#endif
10601};
10602
10603static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010604conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010605{
10606 return conv_confname(arg, valuep, posix_constants_sysconf,
10607 sizeof(posix_constants_sysconf)
10608 / sizeof(struct constdef));
10609}
10610
Larry Hastings2f936352014-08-05 14:04:04 +100010611
10612/*[clinic input]
10613os.sysconf -> long
10614 name: sysconf_confname
10615 /
10616
10617Return an integer-valued system configuration variable.
10618[clinic start generated code]*/
10619
Larry Hastings2f936352014-08-05 14:04:04 +100010620static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010621os_sysconf_impl(PyObject *module, int name)
10622/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010623{
10624 long value;
10625
10626 errno = 0;
10627 value = sysconf(name);
10628 if (value == -1 && errno != 0)
10629 posix_error();
10630 return value;
10631}
10632#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010633
10634
Fred Drakebec628d1999-12-15 18:31:10 +000010635/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010636 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010637 * the exported dictionaries that are used to publish information about the
10638 * names available on the host platform.
10639 *
10640 * Sorting the table at runtime ensures that the table is properly ordered
10641 * when used, even for platforms we're not able to test on. It also makes
10642 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010643 */
Fred Drakebec628d1999-12-15 18:31:10 +000010644
10645static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010646cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010647{
10648 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010650 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010652
10653 return strcmp(c1->name, c2->name);
10654}
10655
10656static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010657setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010658 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010659{
Fred Drakebec628d1999-12-15 18:31:10 +000010660 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010661 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010662
10663 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10664 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010665 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010667
Barry Warsaw3155db32000-04-13 15:20:40 +000010668 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 PyObject *o = PyLong_FromLong(table[i].value);
10670 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10671 Py_XDECREF(o);
10672 Py_DECREF(d);
10673 return -1;
10674 }
10675 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010676 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010677 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010678}
10679
Fred Drakebec628d1999-12-15 18:31:10 +000010680/* Return -1 on failure, 0 on success. */
10681static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010682setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010683{
10684#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010685 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010686 sizeof(posix_constants_pathconf)
10687 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010688 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010689 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010690#endif
10691#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010692 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010693 sizeof(posix_constants_confstr)
10694 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010695 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010696 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010697#endif
10698#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010699 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010700 sizeof(posix_constants_sysconf)
10701 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010702 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010703 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010704#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010705 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010706}
Fred Draked86ed291999-12-15 15:34:33 +000010707
10708
Larry Hastings2f936352014-08-05 14:04:04 +100010709/*[clinic input]
10710os.abort
10711
10712Abort the interpreter immediately.
10713
10714This function 'dumps core' or otherwise fails in the hardest way possible
10715on the hosting operating system. This function never returns.
10716[clinic start generated code]*/
10717
Larry Hastings2f936352014-08-05 14:04:04 +100010718static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010719os_abort_impl(PyObject *module)
10720/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010721{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010722 abort();
10723 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010724#ifndef __clang__
10725 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10726 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10727 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010728 Py_FatalError("abort() called from Python code didn't abort!");
10729 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010730#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010731}
Fred Drakebec628d1999-12-15 18:31:10 +000010732
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010733#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010734/* Grab ShellExecute dynamically from shell32 */
10735static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010736static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10737 LPCWSTR, INT);
10738static int
10739check_ShellExecute()
10740{
10741 HINSTANCE hShell32;
10742
10743 /* only recheck */
10744 if (-1 == has_ShellExecute) {
10745 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010746 /* Security note: this call is not vulnerable to "DLL hijacking".
10747 SHELL32 is part of "KnownDLLs" and so Windows always load
10748 the system SHELL32.DLL, even if there is another SHELL32.DLL
10749 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010750 hShell32 = LoadLibraryW(L"SHELL32");
10751 Py_END_ALLOW_THREADS
10752 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010753 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10754 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010755 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010756 } else {
10757 has_ShellExecute = 0;
10758 }
10759 }
10760 return has_ShellExecute;
10761}
10762
10763
Steve Dowercc16be82016-09-08 10:35:16 -070010764/*[clinic input]
10765os.startfile
10766 filepath: path_t
10767 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010768
Steve Dowercc16be82016-09-08 10:35:16 -070010769startfile(filepath [, operation])
10770
10771Start a file with its associated application.
10772
10773When "operation" is not specified or "open", this acts like
10774double-clicking the file in Explorer, or giving the file name as an
10775argument to the DOS "start" command: the file is opened with whatever
10776application (if any) its extension is associated.
10777When another "operation" is given, it specifies what should be done with
10778the file. A typical operation is "print".
10779
10780startfile returns as soon as the associated application is launched.
10781There is no option to wait for the application to close, and no way
10782to retrieve the application's exit status.
10783
10784The filepath is relative to the current directory. If you want to use
10785an absolute path, make sure the first character is not a slash ("/");
10786the underlying Win32 ShellExecute function doesn't work if it is.
10787[clinic start generated code]*/
10788
10789static PyObject *
10790os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10791/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10792{
10793 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010794
10795 if(!check_ShellExecute()) {
10796 /* If the OS doesn't have ShellExecute, return a
10797 NotImplementedError. */
10798 return PyErr_Format(PyExc_NotImplementedError,
10799 "startfile not available on this platform");
10800 }
10801
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010803 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010804 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 Py_END_ALLOW_THREADS
10806
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010808 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010809 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 }
Steve Dowercc16be82016-09-08 10:35:16 -070010811 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010812}
Larry Hastings2f936352014-08-05 14:04:04 +100010813#endif /* MS_WINDOWS */
10814
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010815
Martin v. Löwis438b5342002-12-27 10:16:42 +000010816#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010817/*[clinic input]
10818os.getloadavg
10819
10820Return average recent system load information.
10821
10822Return the number of processes in the system run queue averaged over
10823the last 1, 5, and 15 minutes as a tuple of three floats.
10824Raises OSError if the load average was unobtainable.
10825[clinic start generated code]*/
10826
Larry Hastings2f936352014-08-05 14:04:04 +100010827static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010828os_getloadavg_impl(PyObject *module)
10829/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010830{
10831 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010832 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010833 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10834 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010835 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010836 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010837}
Larry Hastings2f936352014-08-05 14:04:04 +100010838#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010839
Larry Hastings2f936352014-08-05 14:04:04 +100010840
10841/*[clinic input]
10842os.device_encoding
10843 fd: int
10844
10845Return a string describing the encoding of a terminal's file descriptor.
10846
10847The file descriptor must be attached to a terminal.
10848If the device is not a terminal, return None.
10849[clinic start generated code]*/
10850
Larry Hastings2f936352014-08-05 14:04:04 +100010851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010852os_device_encoding_impl(PyObject *module, int fd)
10853/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010854{
Brett Cannonefb00c02012-02-29 18:31:31 -050010855 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010856}
10857
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010858
Larry Hastings2f936352014-08-05 14:04:04 +100010859#ifdef HAVE_SETRESUID
10860/*[clinic input]
10861os.setresuid
10862
10863 ruid: uid_t
10864 euid: uid_t
10865 suid: uid_t
10866 /
10867
10868Set the current process's real, effective, and saved user ids.
10869[clinic start generated code]*/
10870
Larry Hastings2f936352014-08-05 14:04:04 +100010871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010872os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10873/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010874{
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 if (setresuid(ruid, euid, suid) < 0)
10876 return posix_error();
10877 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010878}
Larry Hastings2f936352014-08-05 14:04:04 +100010879#endif /* HAVE_SETRESUID */
10880
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010881
10882#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010883/*[clinic input]
10884os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010885
Larry Hastings2f936352014-08-05 14:04:04 +100010886 rgid: gid_t
10887 egid: gid_t
10888 sgid: gid_t
10889 /
10890
10891Set the current process's real, effective, and saved group ids.
10892[clinic start generated code]*/
10893
Larry Hastings2f936352014-08-05 14:04:04 +100010894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010895os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10896/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010897{
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 if (setresgid(rgid, egid, sgid) < 0)
10899 return posix_error();
10900 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010901}
Larry Hastings2f936352014-08-05 14:04:04 +100010902#endif /* HAVE_SETRESGID */
10903
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010904
10905#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010906/*[clinic input]
10907os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010908
Larry Hastings2f936352014-08-05 14:04:04 +100010909Return a tuple of the current process's real, effective, and saved user ids.
10910[clinic start generated code]*/
10911
Larry Hastings2f936352014-08-05 14:04:04 +100010912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010913os_getresuid_impl(PyObject *module)
10914/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010915{
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 if (getresuid(&ruid, &euid, &suid) < 0)
10918 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010919 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10920 _PyLong_FromUid(euid),
10921 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010922}
Larry Hastings2f936352014-08-05 14:04:04 +100010923#endif /* HAVE_GETRESUID */
10924
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010925
10926#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010927/*[clinic input]
10928os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010929
Larry Hastings2f936352014-08-05 14:04:04 +100010930Return a tuple of the current process's real, effective, and saved group ids.
10931[clinic start generated code]*/
10932
Larry Hastings2f936352014-08-05 14:04:04 +100010933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010934os_getresgid_impl(PyObject *module)
10935/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010936{
10937 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 if (getresgid(&rgid, &egid, &sgid) < 0)
10939 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010940 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10941 _PyLong_FromGid(egid),
10942 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010943}
Larry Hastings2f936352014-08-05 14:04:04 +100010944#endif /* HAVE_GETRESGID */
10945
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010946
Benjamin Peterson9428d532011-09-14 11:45:52 -040010947#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010948/*[clinic input]
10949os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010950
Larry Hastings2f936352014-08-05 14:04:04 +100010951 path: path_t(allow_fd=True)
10952 attribute: path_t
10953 *
10954 follow_symlinks: bool = True
10955
10956Return the value of extended attribute attribute on path.
10957
10958path may be either a string or an open file descriptor.
10959If follow_symlinks is False, and the last element of the path is a symbolic
10960 link, getxattr will examine the symbolic link itself instead of the file
10961 the link points to.
10962
10963[clinic start generated code]*/
10964
Larry Hastings2f936352014-08-05 14:04:04 +100010965static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010966os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010967 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010968/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010969{
10970 Py_ssize_t i;
10971 PyObject *buffer = NULL;
10972
10973 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10974 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010975
Larry Hastings9cf065c2012-06-22 16:30:09 -070010976 for (i = 0; ; i++) {
10977 void *ptr;
10978 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010979 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010980 Py_ssize_t buffer_size = buffer_sizes[i];
10981 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010982 path_error(path);
10983 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010984 }
10985 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10986 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010987 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010988 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010989
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010991 if (path->fd >= 0)
10992 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010993 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010994 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 else
Larry Hastings2f936352014-08-05 14:04:04 +100010996 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010997 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010998
Larry Hastings9cf065c2012-06-22 16:30:09 -070010999 if (result < 0) {
11000 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011001 if (errno == ERANGE)
11002 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011003 path_error(path);
11004 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011006
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 if (result != buffer_size) {
11008 /* Can only shrink. */
11009 _PyBytes_Resize(&buffer, result);
11010 }
11011 break;
11012 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011013
Larry Hastings9cf065c2012-06-22 16:30:09 -070011014 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011015}
11016
Larry Hastings2f936352014-08-05 14:04:04 +100011017
11018/*[clinic input]
11019os.setxattr
11020
11021 path: path_t(allow_fd=True)
11022 attribute: path_t
11023 value: Py_buffer
11024 flags: int = 0
11025 *
11026 follow_symlinks: bool = True
11027
11028Set extended attribute attribute on path to value.
11029
11030path may be either a string or an open file descriptor.
11031If follow_symlinks is False, and the last element of the path is a symbolic
11032 link, setxattr will modify the symbolic link itself instead of the file
11033 the link points to.
11034
11035[clinic start generated code]*/
11036
Benjamin Peterson799bd802011-08-31 22:15:17 -040011037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011038os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011039 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011040/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011041{
Larry Hastings2f936352014-08-05 14:04:04 +100011042 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011043
Larry Hastings2f936352014-08-05 14:04:04 +100011044 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011045 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011046
Benjamin Peterson799bd802011-08-31 22:15:17 -040011047 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011048 if (path->fd > -1)
11049 result = fsetxattr(path->fd, attribute->narrow,
11050 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011051 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011052 result = setxattr(path->narrow, attribute->narrow,
11053 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011054 else
Larry Hastings2f936352014-08-05 14:04:04 +100011055 result = lsetxattr(path->narrow, attribute->narrow,
11056 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011057 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011058
Larry Hastings9cf065c2012-06-22 16:30:09 -070011059 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011060 path_error(path);
11061 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011062 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011063
Larry Hastings2f936352014-08-05 14:04:04 +100011064 Py_RETURN_NONE;
11065}
11066
11067
11068/*[clinic input]
11069os.removexattr
11070
11071 path: path_t(allow_fd=True)
11072 attribute: path_t
11073 *
11074 follow_symlinks: bool = True
11075
11076Remove extended attribute attribute on path.
11077
11078path may be either a string or an open file descriptor.
11079If follow_symlinks is False, and the last element of the path is a symbolic
11080 link, removexattr will modify the symbolic link itself instead of the file
11081 the link points to.
11082
11083[clinic start generated code]*/
11084
Larry Hastings2f936352014-08-05 14:04:04 +100011085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011086os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011087 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011088/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011089{
11090 ssize_t result;
11091
11092 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11093 return NULL;
11094
11095 Py_BEGIN_ALLOW_THREADS;
11096 if (path->fd > -1)
11097 result = fremovexattr(path->fd, attribute->narrow);
11098 else if (follow_symlinks)
11099 result = removexattr(path->narrow, attribute->narrow);
11100 else
11101 result = lremovexattr(path->narrow, attribute->narrow);
11102 Py_END_ALLOW_THREADS;
11103
11104 if (result) {
11105 return path_error(path);
11106 }
11107
11108 Py_RETURN_NONE;
11109}
11110
11111
11112/*[clinic input]
11113os.listxattr
11114
11115 path: path_t(allow_fd=True, nullable=True) = None
11116 *
11117 follow_symlinks: bool = True
11118
11119Return a list of extended attributes on path.
11120
11121path may be either None, a string, or an open file descriptor.
11122if path is None, listxattr will examine the current directory.
11123If follow_symlinks is False, and the last element of the path is a symbolic
11124 link, listxattr will examine the symbolic link itself instead of the file
11125 the link points to.
11126[clinic start generated code]*/
11127
Larry Hastings2f936352014-08-05 14:04:04 +100011128static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011129os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11130/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011131{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011132 Py_ssize_t i;
11133 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011134 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011135 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011136
Larry Hastings2f936352014-08-05 14:04:04 +100011137 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011138 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011139
Larry Hastings2f936352014-08-05 14:04:04 +100011140 name = path->narrow ? path->narrow : ".";
11141
Larry Hastings9cf065c2012-06-22 16:30:09 -070011142 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011143 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011144 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011145 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011146 Py_ssize_t buffer_size = buffer_sizes[i];
11147 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011148 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011149 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011150 break;
11151 }
11152 buffer = PyMem_MALLOC(buffer_size);
11153 if (!buffer) {
11154 PyErr_NoMemory();
11155 break;
11156 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011157
Larry Hastings9cf065c2012-06-22 16:30:09 -070011158 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011159 if (path->fd > -1)
11160 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011161 else if (follow_symlinks)
11162 length = listxattr(name, buffer, buffer_size);
11163 else
11164 length = llistxattr(name, buffer, buffer_size);
11165 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011166
Larry Hastings9cf065c2012-06-22 16:30:09 -070011167 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011168 if (errno == ERANGE) {
11169 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011170 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011171 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011172 }
Larry Hastings2f936352014-08-05 14:04:04 +100011173 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011174 break;
11175 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011176
Larry Hastings9cf065c2012-06-22 16:30:09 -070011177 result = PyList_New(0);
11178 if (!result) {
11179 goto exit;
11180 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011181
Larry Hastings9cf065c2012-06-22 16:30:09 -070011182 end = buffer + length;
11183 for (trace = start = buffer; trace != end; trace++) {
11184 if (!*trace) {
11185 int error;
11186 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11187 trace - start);
11188 if (!attribute) {
11189 Py_DECREF(result);
11190 result = NULL;
11191 goto exit;
11192 }
11193 error = PyList_Append(result, attribute);
11194 Py_DECREF(attribute);
11195 if (error) {
11196 Py_DECREF(result);
11197 result = NULL;
11198 goto exit;
11199 }
11200 start = trace + 1;
11201 }
11202 }
11203 break;
11204 }
11205exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011206 if (buffer)
11207 PyMem_FREE(buffer);
11208 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011209}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011210#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011211
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011212
Larry Hastings2f936352014-08-05 14:04:04 +100011213/*[clinic input]
11214os.urandom
11215
11216 size: Py_ssize_t
11217 /
11218
11219Return a bytes object containing random bytes suitable for cryptographic use.
11220[clinic start generated code]*/
11221
Larry Hastings2f936352014-08-05 14:04:04 +100011222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011223os_urandom_impl(PyObject *module, Py_ssize_t size)
11224/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011225{
11226 PyObject *bytes;
11227 int result;
11228
Georg Brandl2fb477c2012-02-21 00:33:36 +010011229 if (size < 0)
11230 return PyErr_Format(PyExc_ValueError,
11231 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011232 bytes = PyBytes_FromStringAndSize(NULL, size);
11233 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011234 return NULL;
11235
Victor Stinnere66987e2016-09-06 16:33:52 -070011236 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011237 if (result == -1) {
11238 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011239 return NULL;
11240 }
Larry Hastings2f936352014-08-05 14:04:04 +100011241 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011242}
11243
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011244/* Terminal size querying */
11245
11246static PyTypeObject TerminalSizeType;
11247
11248PyDoc_STRVAR(TerminalSize_docstring,
11249 "A tuple of (columns, lines) for holding terminal window size");
11250
11251static PyStructSequence_Field TerminalSize_fields[] = {
11252 {"columns", "width of the terminal window in characters"},
11253 {"lines", "height of the terminal window in characters"},
11254 {NULL, NULL}
11255};
11256
11257static PyStructSequence_Desc TerminalSize_desc = {
11258 "os.terminal_size",
11259 TerminalSize_docstring,
11260 TerminalSize_fields,
11261 2,
11262};
11263
11264#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011265/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011266PyDoc_STRVAR(termsize__doc__,
11267 "Return the size of the terminal window as (columns, lines).\n" \
11268 "\n" \
11269 "The optional argument fd (default standard output) specifies\n" \
11270 "which file descriptor should be queried.\n" \
11271 "\n" \
11272 "If the file descriptor is not connected to a terminal, an OSError\n" \
11273 "is thrown.\n" \
11274 "\n" \
11275 "This function will only be defined if an implementation is\n" \
11276 "available for this system.\n" \
11277 "\n" \
11278 "shutil.get_terminal_size is the high-level function which should \n" \
11279 "normally be used, os.get_terminal_size is the low-level implementation.");
11280
11281static PyObject*
11282get_terminal_size(PyObject *self, PyObject *args)
11283{
11284 int columns, lines;
11285 PyObject *termsize;
11286
11287 int fd = fileno(stdout);
11288 /* Under some conditions stdout may not be connected and
11289 * fileno(stdout) may point to an invalid file descriptor. For example
11290 * GUI apps don't have valid standard streams by default.
11291 *
11292 * If this happens, and the optional fd argument is not present,
11293 * the ioctl below will fail returning EBADF. This is what we want.
11294 */
11295
11296 if (!PyArg_ParseTuple(args, "|i", &fd))
11297 return NULL;
11298
11299#ifdef TERMSIZE_USE_IOCTL
11300 {
11301 struct winsize w;
11302 if (ioctl(fd, TIOCGWINSZ, &w))
11303 return PyErr_SetFromErrno(PyExc_OSError);
11304 columns = w.ws_col;
11305 lines = w.ws_row;
11306 }
11307#endif /* TERMSIZE_USE_IOCTL */
11308
11309#ifdef TERMSIZE_USE_CONIO
11310 {
11311 DWORD nhandle;
11312 HANDLE handle;
11313 CONSOLE_SCREEN_BUFFER_INFO csbi;
11314 switch (fd) {
11315 case 0: nhandle = STD_INPUT_HANDLE;
11316 break;
11317 case 1: nhandle = STD_OUTPUT_HANDLE;
11318 break;
11319 case 2: nhandle = STD_ERROR_HANDLE;
11320 break;
11321 default:
11322 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11323 }
11324 handle = GetStdHandle(nhandle);
11325 if (handle == NULL)
11326 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11327 if (handle == INVALID_HANDLE_VALUE)
11328 return PyErr_SetFromWindowsErr(0);
11329
11330 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11331 return PyErr_SetFromWindowsErr(0);
11332
11333 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11334 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11335 }
11336#endif /* TERMSIZE_USE_CONIO */
11337
11338 termsize = PyStructSequence_New(&TerminalSizeType);
11339 if (termsize == NULL)
11340 return NULL;
11341 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11342 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11343 if (PyErr_Occurred()) {
11344 Py_DECREF(termsize);
11345 return NULL;
11346 }
11347 return termsize;
11348}
11349#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11350
Larry Hastings2f936352014-08-05 14:04:04 +100011351
11352/*[clinic input]
11353os.cpu_count
11354
Charles-François Natali80d62e62015-08-13 20:37:08 +010011355Return the number of CPUs in the system; return None if indeterminable.
11356
11357This number is not equivalent to the number of CPUs the current process can
11358use. The number of usable CPUs can be obtained with
11359``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011360[clinic start generated code]*/
11361
Larry Hastings2f936352014-08-05 14:04:04 +100011362static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011363os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011364/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011365{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011366 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011367#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011368 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11369 Need to fallback to Vista behavior if this call isn't present */
11370 HINSTANCE hKernel32;
11371 hKernel32 = GetModuleHandleW(L"KERNEL32");
11372
11373 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11374 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11375 "GetMaximumProcessorCount");
11376 if (_GetMaximumProcessorCount != NULL) {
11377 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11378 }
11379 else {
11380 SYSTEM_INFO sysinfo;
11381 GetSystemInfo(&sysinfo);
11382 ncpu = sysinfo.dwNumberOfProcessors;
11383 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011384#elif defined(__hpux)
11385 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11386#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11387 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011388#elif defined(__DragonFly__) || \
11389 defined(__OpenBSD__) || \
11390 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011391 defined(__NetBSD__) || \
11392 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011393 int mib[2];
11394 size_t len = sizeof(ncpu);
11395 mib[0] = CTL_HW;
11396 mib[1] = HW_NCPU;
11397 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11398 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011399#endif
11400 if (ncpu >= 1)
11401 return PyLong_FromLong(ncpu);
11402 else
11403 Py_RETURN_NONE;
11404}
11405
Victor Stinnerdaf45552013-08-28 00:53:59 +020011406
Larry Hastings2f936352014-08-05 14:04:04 +100011407/*[clinic input]
11408os.get_inheritable -> bool
11409
11410 fd: int
11411 /
11412
11413Get the close-on-exe flag of the specified file descriptor.
11414[clinic start generated code]*/
11415
Larry Hastings2f936352014-08-05 14:04:04 +100011416static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011417os_get_inheritable_impl(PyObject *module, int fd)
11418/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011419{
Steve Dower8fc89802015-04-12 00:26:27 -040011420 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011421 _Py_BEGIN_SUPPRESS_IPH
11422 return_value = _Py_get_inheritable(fd);
11423 _Py_END_SUPPRESS_IPH
11424 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011425}
11426
11427
11428/*[clinic input]
11429os.set_inheritable
11430 fd: int
11431 inheritable: int
11432 /
11433
11434Set the inheritable flag of the specified file descriptor.
11435[clinic start generated code]*/
11436
Larry Hastings2f936352014-08-05 14:04:04 +100011437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011438os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11439/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011440{
Steve Dower8fc89802015-04-12 00:26:27 -040011441 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011442
Steve Dower8fc89802015-04-12 00:26:27 -040011443 _Py_BEGIN_SUPPRESS_IPH
11444 result = _Py_set_inheritable(fd, inheritable, NULL);
11445 _Py_END_SUPPRESS_IPH
11446 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011447 return NULL;
11448 Py_RETURN_NONE;
11449}
11450
11451
11452#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011453/*[clinic input]
11454os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011455 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011456 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011457
Larry Hastings2f936352014-08-05 14:04:04 +100011458Get the close-on-exe flag of the specified file descriptor.
11459[clinic start generated code]*/
11460
Larry Hastings2f936352014-08-05 14:04:04 +100011461static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011462os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011463/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011464{
11465 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011466
11467 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11468 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011469 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011470 }
11471
Larry Hastings2f936352014-08-05 14:04:04 +100011472 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011473}
11474
Victor Stinnerdaf45552013-08-28 00:53:59 +020011475
Larry Hastings2f936352014-08-05 14:04:04 +100011476/*[clinic input]
11477os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011478 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011479 inheritable: bool
11480 /
11481
11482Set the inheritable flag of the specified handle.
11483[clinic start generated code]*/
11484
Larry Hastings2f936352014-08-05 14:04:04 +100011485static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011486os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011487 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011488/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011489{
11490 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011491 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11492 PyErr_SetFromWindowsErr(0);
11493 return NULL;
11494 }
11495 Py_RETURN_NONE;
11496}
Larry Hastings2f936352014-08-05 14:04:04 +100011497#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011498
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011499#ifndef MS_WINDOWS
11500PyDoc_STRVAR(get_blocking__doc__,
11501 "get_blocking(fd) -> bool\n" \
11502 "\n" \
11503 "Get the blocking mode of the file descriptor:\n" \
11504 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11505
11506static PyObject*
11507posix_get_blocking(PyObject *self, PyObject *args)
11508{
11509 int fd;
11510 int blocking;
11511
11512 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11513 return NULL;
11514
Steve Dower8fc89802015-04-12 00:26:27 -040011515 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011516 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011517 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011518 if (blocking < 0)
11519 return NULL;
11520 return PyBool_FromLong(blocking);
11521}
11522
11523PyDoc_STRVAR(set_blocking__doc__,
11524 "set_blocking(fd, blocking)\n" \
11525 "\n" \
11526 "Set the blocking mode of the specified file descriptor.\n" \
11527 "Set the O_NONBLOCK flag if blocking is False,\n" \
11528 "clear the O_NONBLOCK flag otherwise.");
11529
11530static PyObject*
11531posix_set_blocking(PyObject *self, PyObject *args)
11532{
Steve Dower8fc89802015-04-12 00:26:27 -040011533 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011534
11535 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11536 return NULL;
11537
Steve Dower8fc89802015-04-12 00:26:27 -040011538 _Py_BEGIN_SUPPRESS_IPH
11539 result = _Py_set_blocking(fd, blocking);
11540 _Py_END_SUPPRESS_IPH
11541 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011542 return NULL;
11543 Py_RETURN_NONE;
11544}
11545#endif /* !MS_WINDOWS */
11546
11547
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011548/*[clinic input]
11549class os.DirEntry "DirEntry *" "&DirEntryType"
11550[clinic start generated code]*/
11551/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011552
11553typedef struct {
11554 PyObject_HEAD
11555 PyObject *name;
11556 PyObject *path;
11557 PyObject *stat;
11558 PyObject *lstat;
11559#ifdef MS_WINDOWS
11560 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011561 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011562 int got_file_index;
11563#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011564#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011565 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011566#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011567 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011568 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011569#endif
11570} DirEntry;
11571
11572static void
11573DirEntry_dealloc(DirEntry *entry)
11574{
11575 Py_XDECREF(entry->name);
11576 Py_XDECREF(entry->path);
11577 Py_XDECREF(entry->stat);
11578 Py_XDECREF(entry->lstat);
11579 Py_TYPE(entry)->tp_free((PyObject *)entry);
11580}
11581
11582/* Forward reference */
11583static int
11584DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11585
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011586/*[clinic input]
11587os.DirEntry.is_symlink -> bool
11588
11589Return True if the entry is a symbolic link; cached per entry.
11590[clinic start generated code]*/
11591
Victor Stinner6036e442015-03-08 01:58:04 +010011592static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011593os_DirEntry_is_symlink_impl(DirEntry *self)
11594/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011595{
11596#ifdef MS_WINDOWS
11597 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011598#elif defined(HAVE_DIRENT_D_TYPE)
11599 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011600 if (self->d_type != DT_UNKNOWN)
11601 return self->d_type == DT_LNK;
11602 else
11603 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011604#else
11605 /* POSIX without d_type */
11606 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011607#endif
11608}
11609
11610static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011611DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11612{
11613 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011614 STRUCT_STAT st;
11615 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011616
11617#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011618 if (!PyUnicode_FSDecoder(self->path, &ub))
11619 return NULL;
11620 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011621#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011622 if (!PyUnicode_FSConverter(self->path, &ub))
11623 return NULL;
11624 const char *path = PyBytes_AS_STRING(ub);
11625 if (self->dir_fd != DEFAULT_DIR_FD) {
11626#ifdef HAVE_FSTATAT
11627 result = fstatat(self->dir_fd, path, &st,
11628 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11629#else
11630 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11631 return NULL;
11632#endif /* HAVE_FSTATAT */
11633 }
11634 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011635#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011636 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011637 if (follow_symlinks)
11638 result = STAT(path, &st);
11639 else
11640 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011641 }
11642 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011643
11644 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011645 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011646
11647 return _pystat_fromstructstat(&st);
11648}
11649
11650static PyObject *
11651DirEntry_get_lstat(DirEntry *self)
11652{
11653 if (!self->lstat) {
11654#ifdef MS_WINDOWS
11655 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11656#else /* POSIX */
11657 self->lstat = DirEntry_fetch_stat(self, 0);
11658#endif
11659 }
11660 Py_XINCREF(self->lstat);
11661 return self->lstat;
11662}
11663
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011664/*[clinic input]
11665os.DirEntry.stat
11666 *
11667 follow_symlinks: bool = True
11668
11669Return stat_result object for the entry; cached per entry.
11670[clinic start generated code]*/
11671
Victor Stinner6036e442015-03-08 01:58:04 +010011672static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011673os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11674/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011675{
11676 if (!follow_symlinks)
11677 return DirEntry_get_lstat(self);
11678
11679 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011680 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011681 if (result == -1)
11682 return NULL;
11683 else if (result)
11684 self->stat = DirEntry_fetch_stat(self, 1);
11685 else
11686 self->stat = DirEntry_get_lstat(self);
11687 }
11688
11689 Py_XINCREF(self->stat);
11690 return self->stat;
11691}
11692
Victor Stinner6036e442015-03-08 01:58:04 +010011693/* Set exception and return -1 on error, 0 for False, 1 for True */
11694static int
11695DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11696{
11697 PyObject *stat = NULL;
11698 PyObject *st_mode = NULL;
11699 long mode;
11700 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011701#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011702 int is_symlink;
11703 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011704#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011705#ifdef MS_WINDOWS
11706 unsigned long dir_bits;
11707#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011708 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011709
11710#ifdef MS_WINDOWS
11711 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11712 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011713#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011714 is_symlink = self->d_type == DT_LNK;
11715 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11716#endif
11717
Victor Stinner35a97c02015-03-08 02:59:09 +010011718#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011719 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011720#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011721 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011722 if (!stat) {
11723 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11724 /* If file doesn't exist (anymore), then return False
11725 (i.e., say it's not a file/directory) */
11726 PyErr_Clear();
11727 return 0;
11728 }
11729 goto error;
11730 }
11731 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11732 if (!st_mode)
11733 goto error;
11734
11735 mode = PyLong_AsLong(st_mode);
11736 if (mode == -1 && PyErr_Occurred())
11737 goto error;
11738 Py_CLEAR(st_mode);
11739 Py_CLEAR(stat);
11740 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011741#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011742 }
11743 else if (is_symlink) {
11744 assert(mode_bits != S_IFLNK);
11745 result = 0;
11746 }
11747 else {
11748 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11749#ifdef MS_WINDOWS
11750 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11751 if (mode_bits == S_IFDIR)
11752 result = dir_bits != 0;
11753 else
11754 result = dir_bits == 0;
11755#else /* POSIX */
11756 if (mode_bits == S_IFDIR)
11757 result = self->d_type == DT_DIR;
11758 else
11759 result = self->d_type == DT_REG;
11760#endif
11761 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011762#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011763
11764 return result;
11765
11766error:
11767 Py_XDECREF(st_mode);
11768 Py_XDECREF(stat);
11769 return -1;
11770}
11771
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011772/*[clinic input]
11773os.DirEntry.is_dir -> bool
11774 *
11775 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011776
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011777Return True if the entry is a directory; cached per entry.
11778[clinic start generated code]*/
11779
11780static int
11781os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11782/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11783{
11784 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011785}
11786
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011787/*[clinic input]
11788os.DirEntry.is_file -> bool
11789 *
11790 follow_symlinks: bool = True
11791
11792Return True if the entry is a file; cached per entry.
11793[clinic start generated code]*/
11794
11795static int
11796os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11797/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011798{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011799 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011800}
11801
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011802/*[clinic input]
11803os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011804
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011805Return inode of the entry; cached per entry.
11806[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011807
11808static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011809os_DirEntry_inode_impl(DirEntry *self)
11810/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011811{
11812#ifdef MS_WINDOWS
11813 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011814 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011815 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011816 STRUCT_STAT stat;
11817 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011818
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011819 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011820 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011821 path = PyUnicode_AsUnicode(unicode);
11822 result = LSTAT(path, &stat);
11823 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011824
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011825 if (result != 0)
11826 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011827
11828 self->win32_file_index = stat.st_ino;
11829 self->got_file_index = 1;
11830 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011831 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11832 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011833#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011834 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11835 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011836#endif
11837}
11838
11839static PyObject *
11840DirEntry_repr(DirEntry *self)
11841{
11842 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11843}
11844
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011845/*[clinic input]
11846os.DirEntry.__fspath__
11847
11848Returns the path for the entry.
11849[clinic start generated code]*/
11850
Brett Cannon96881cd2016-06-10 14:37:21 -070011851static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011852os_DirEntry___fspath___impl(DirEntry *self)
11853/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011854{
11855 Py_INCREF(self->path);
11856 return self->path;
11857}
11858
Victor Stinner6036e442015-03-08 01:58:04 +010011859static PyMemberDef DirEntry_members[] = {
11860 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11861 "the entry's base filename, relative to scandir() \"path\" argument"},
11862 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11863 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11864 {NULL}
11865};
11866
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011867#include "clinic/posixmodule.c.h"
11868
Victor Stinner6036e442015-03-08 01:58:04 +010011869static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011870 OS_DIRENTRY_IS_DIR_METHODDEF
11871 OS_DIRENTRY_IS_FILE_METHODDEF
11872 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11873 OS_DIRENTRY_STAT_METHODDEF
11874 OS_DIRENTRY_INODE_METHODDEF
11875 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011876 {NULL}
11877};
11878
Benjamin Peterson5646de42015-04-12 17:56:34 -040011879static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011880 PyVarObject_HEAD_INIT(NULL, 0)
11881 MODNAME ".DirEntry", /* tp_name */
11882 sizeof(DirEntry), /* tp_basicsize */
11883 0, /* tp_itemsize */
11884 /* methods */
11885 (destructor)DirEntry_dealloc, /* tp_dealloc */
11886 0, /* tp_print */
11887 0, /* tp_getattr */
11888 0, /* tp_setattr */
11889 0, /* tp_compare */
11890 (reprfunc)DirEntry_repr, /* tp_repr */
11891 0, /* tp_as_number */
11892 0, /* tp_as_sequence */
11893 0, /* tp_as_mapping */
11894 0, /* tp_hash */
11895 0, /* tp_call */
11896 0, /* tp_str */
11897 0, /* tp_getattro */
11898 0, /* tp_setattro */
11899 0, /* tp_as_buffer */
11900 Py_TPFLAGS_DEFAULT, /* tp_flags */
11901 0, /* tp_doc */
11902 0, /* tp_traverse */
11903 0, /* tp_clear */
11904 0, /* tp_richcompare */
11905 0, /* tp_weaklistoffset */
11906 0, /* tp_iter */
11907 0, /* tp_iternext */
11908 DirEntry_methods, /* tp_methods */
11909 DirEntry_members, /* tp_members */
11910};
11911
11912#ifdef MS_WINDOWS
11913
11914static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011915join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011916{
11917 Py_ssize_t path_len;
11918 Py_ssize_t size;
11919 wchar_t *result;
11920 wchar_t ch;
11921
11922 if (!path_wide) { /* Default arg: "." */
11923 path_wide = L".";
11924 path_len = 1;
11925 }
11926 else {
11927 path_len = wcslen(path_wide);
11928 }
11929
11930 /* The +1's are for the path separator and the NUL */
11931 size = path_len + 1 + wcslen(filename) + 1;
11932 result = PyMem_New(wchar_t, size);
11933 if (!result) {
11934 PyErr_NoMemory();
11935 return NULL;
11936 }
11937 wcscpy(result, path_wide);
11938 if (path_len > 0) {
11939 ch = result[path_len - 1];
11940 if (ch != SEP && ch != ALTSEP && ch != L':')
11941 result[path_len++] = SEP;
11942 wcscpy(result + path_len, filename);
11943 }
11944 return result;
11945}
11946
11947static PyObject *
11948DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11949{
11950 DirEntry *entry;
11951 BY_HANDLE_FILE_INFORMATION file_info;
11952 ULONG reparse_tag;
11953 wchar_t *joined_path;
11954
11955 entry = PyObject_New(DirEntry, &DirEntryType);
11956 if (!entry)
11957 return NULL;
11958 entry->name = NULL;
11959 entry->path = NULL;
11960 entry->stat = NULL;
11961 entry->lstat = NULL;
11962 entry->got_file_index = 0;
11963
11964 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11965 if (!entry->name)
11966 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011967 if (path->narrow) {
11968 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11969 if (!entry->name)
11970 goto error;
11971 }
Victor Stinner6036e442015-03-08 01:58:04 +010011972
11973 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11974 if (!joined_path)
11975 goto error;
11976
11977 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11978 PyMem_Free(joined_path);
11979 if (!entry->path)
11980 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011981 if (path->narrow) {
11982 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11983 if (!entry->path)
11984 goto error;
11985 }
Victor Stinner6036e442015-03-08 01:58:04 +010011986
Steve Dowercc16be82016-09-08 10:35:16 -070011987 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011988 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11989
11990 return (PyObject *)entry;
11991
11992error:
11993 Py_DECREF(entry);
11994 return NULL;
11995}
11996
11997#else /* POSIX */
11998
11999static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012000join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012001{
12002 Py_ssize_t path_len;
12003 Py_ssize_t size;
12004 char *result;
12005
12006 if (!path_narrow) { /* Default arg: "." */
12007 path_narrow = ".";
12008 path_len = 1;
12009 }
12010 else {
12011 path_len = strlen(path_narrow);
12012 }
12013
12014 if (filename_len == -1)
12015 filename_len = strlen(filename);
12016
12017 /* The +1's are for the path separator and the NUL */
12018 size = path_len + 1 + filename_len + 1;
12019 result = PyMem_New(char, size);
12020 if (!result) {
12021 PyErr_NoMemory();
12022 return NULL;
12023 }
12024 strcpy(result, path_narrow);
12025 if (path_len > 0 && result[path_len - 1] != '/')
12026 result[path_len++] = '/';
12027 strcpy(result + path_len, filename);
12028 return result;
12029}
12030
12031static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012032DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012033 ino_t d_ino
12034#ifdef HAVE_DIRENT_D_TYPE
12035 , unsigned char d_type
12036#endif
12037 )
Victor Stinner6036e442015-03-08 01:58:04 +010012038{
12039 DirEntry *entry;
12040 char *joined_path;
12041
12042 entry = PyObject_New(DirEntry, &DirEntryType);
12043 if (!entry)
12044 return NULL;
12045 entry->name = NULL;
12046 entry->path = NULL;
12047 entry->stat = NULL;
12048 entry->lstat = NULL;
12049
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012050 if (path->fd != -1) {
12051 entry->dir_fd = path->fd;
12052 joined_path = NULL;
12053 }
12054 else {
12055 entry->dir_fd = DEFAULT_DIR_FD;
12056 joined_path = join_path_filename(path->narrow, name, name_len);
12057 if (!joined_path)
12058 goto error;
12059 }
Victor Stinner6036e442015-03-08 01:58:04 +010012060
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012061 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012062 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012063 if (joined_path)
12064 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012065 }
12066 else {
12067 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012068 if (joined_path)
12069 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012070 }
12071 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012072 if (!entry->name)
12073 goto error;
12074
12075 if (path->fd != -1) {
12076 entry->path = entry->name;
12077 Py_INCREF(entry->path);
12078 }
12079 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012080 goto error;
12081
Victor Stinner35a97c02015-03-08 02:59:09 +010012082#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012083 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012084#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012085 entry->d_ino = d_ino;
12086
12087 return (PyObject *)entry;
12088
12089error:
12090 Py_XDECREF(entry);
12091 return NULL;
12092}
12093
12094#endif
12095
12096
12097typedef struct {
12098 PyObject_HEAD
12099 path_t path;
12100#ifdef MS_WINDOWS
12101 HANDLE handle;
12102 WIN32_FIND_DATAW file_data;
12103 int first_time;
12104#else /* POSIX */
12105 DIR *dirp;
12106#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012107#ifdef HAVE_FDOPENDIR
12108 int fd;
12109#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012110} ScandirIterator;
12111
12112#ifdef MS_WINDOWS
12113
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012114static int
12115ScandirIterator_is_closed(ScandirIterator *iterator)
12116{
12117 return iterator->handle == INVALID_HANDLE_VALUE;
12118}
12119
Victor Stinner6036e442015-03-08 01:58:04 +010012120static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012121ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012122{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012123 HANDLE handle = iterator->handle;
12124
12125 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012126 return;
12127
Victor Stinner6036e442015-03-08 01:58:04 +010012128 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012129 Py_BEGIN_ALLOW_THREADS
12130 FindClose(handle);
12131 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012132}
12133
12134static PyObject *
12135ScandirIterator_iternext(ScandirIterator *iterator)
12136{
12137 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12138 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012139 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012140
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012141 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012142 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012143 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012144
12145 while (1) {
12146 if (!iterator->first_time) {
12147 Py_BEGIN_ALLOW_THREADS
12148 success = FindNextFileW(iterator->handle, file_data);
12149 Py_END_ALLOW_THREADS
12150 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012151 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012152 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012153 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012154 break;
12155 }
12156 }
12157 iterator->first_time = 0;
12158
12159 /* Skip over . and .. */
12160 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012161 wcscmp(file_data->cFileName, L"..") != 0) {
12162 entry = DirEntry_from_find_data(&iterator->path, file_data);
12163 if (!entry)
12164 break;
12165 return entry;
12166 }
Victor Stinner6036e442015-03-08 01:58:04 +010012167
12168 /* Loop till we get a non-dot directory or finish iterating */
12169 }
12170
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012171 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012172 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012173 return NULL;
12174}
12175
12176#else /* POSIX */
12177
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012178static int
12179ScandirIterator_is_closed(ScandirIterator *iterator)
12180{
12181 return !iterator->dirp;
12182}
12183
Victor Stinner6036e442015-03-08 01:58:04 +010012184static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012185ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012186{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012187 DIR *dirp = iterator->dirp;
12188
12189 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012190 return;
12191
Victor Stinner6036e442015-03-08 01:58:04 +010012192 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012193 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012194#ifdef HAVE_FDOPENDIR
12195 if (iterator->path.fd != -1)
12196 rewinddir(dirp);
12197#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012198 closedir(dirp);
12199 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012200 return;
12201}
12202
12203static PyObject *
12204ScandirIterator_iternext(ScandirIterator *iterator)
12205{
12206 struct dirent *direntp;
12207 Py_ssize_t name_len;
12208 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012209 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012210
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012211 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012212 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012213 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012214
12215 while (1) {
12216 errno = 0;
12217 Py_BEGIN_ALLOW_THREADS
12218 direntp = readdir(iterator->dirp);
12219 Py_END_ALLOW_THREADS
12220
12221 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012222 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012223 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012224 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012225 break;
12226 }
12227
12228 /* Skip over . and .. */
12229 name_len = NAMLEN(direntp);
12230 is_dot = direntp->d_name[0] == '.' &&
12231 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12232 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012233 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012234 name_len, direntp->d_ino
12235#ifdef HAVE_DIRENT_D_TYPE
12236 , direntp->d_type
12237#endif
12238 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012239 if (!entry)
12240 break;
12241 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012242 }
12243
12244 /* Loop till we get a non-dot directory or finish iterating */
12245 }
12246
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012247 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012248 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012249 return NULL;
12250}
12251
12252#endif
12253
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012254static PyObject *
12255ScandirIterator_close(ScandirIterator *self, PyObject *args)
12256{
12257 ScandirIterator_closedir(self);
12258 Py_RETURN_NONE;
12259}
12260
12261static PyObject *
12262ScandirIterator_enter(PyObject *self, PyObject *args)
12263{
12264 Py_INCREF(self);
12265 return self;
12266}
12267
12268static PyObject *
12269ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12270{
12271 ScandirIterator_closedir(self);
12272 Py_RETURN_NONE;
12273}
12274
Victor Stinner6036e442015-03-08 01:58:04 +010012275static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012276ScandirIterator_finalize(ScandirIterator *iterator)
12277{
12278 PyObject *error_type, *error_value, *error_traceback;
12279
12280 /* Save the current exception, if any. */
12281 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12282
12283 if (!ScandirIterator_is_closed(iterator)) {
12284 ScandirIterator_closedir(iterator);
12285
12286 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12287 "unclosed scandir iterator %R", iterator)) {
12288 /* Spurious errors can appear at shutdown */
12289 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12290 PyErr_WriteUnraisable((PyObject *) iterator);
12291 }
12292 }
12293 }
12294
Victor Stinner7bfa4092016-03-23 00:43:54 +010012295 path_cleanup(&iterator->path);
12296
12297 /* Restore the saved exception. */
12298 PyErr_Restore(error_type, error_value, error_traceback);
12299}
12300
12301static void
Victor Stinner6036e442015-03-08 01:58:04 +010012302ScandirIterator_dealloc(ScandirIterator *iterator)
12303{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012304 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12305 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012306
Victor Stinner6036e442015-03-08 01:58:04 +010012307 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12308}
12309
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012310static PyMethodDef ScandirIterator_methods[] = {
12311 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12312 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12313 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12314 {NULL}
12315};
12316
Benjamin Peterson5646de42015-04-12 17:56:34 -040012317static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012318 PyVarObject_HEAD_INIT(NULL, 0)
12319 MODNAME ".ScandirIterator", /* tp_name */
12320 sizeof(ScandirIterator), /* tp_basicsize */
12321 0, /* tp_itemsize */
12322 /* methods */
12323 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12324 0, /* tp_print */
12325 0, /* tp_getattr */
12326 0, /* tp_setattr */
12327 0, /* tp_compare */
12328 0, /* tp_repr */
12329 0, /* tp_as_number */
12330 0, /* tp_as_sequence */
12331 0, /* tp_as_mapping */
12332 0, /* tp_hash */
12333 0, /* tp_call */
12334 0, /* tp_str */
12335 0, /* tp_getattro */
12336 0, /* tp_setattro */
12337 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012338 Py_TPFLAGS_DEFAULT
12339 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012340 0, /* tp_doc */
12341 0, /* tp_traverse */
12342 0, /* tp_clear */
12343 0, /* tp_richcompare */
12344 0, /* tp_weaklistoffset */
12345 PyObject_SelfIter, /* tp_iter */
12346 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012347 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012348 0, /* tp_members */
12349 0, /* tp_getset */
12350 0, /* tp_base */
12351 0, /* tp_dict */
12352 0, /* tp_descr_get */
12353 0, /* tp_descr_set */
12354 0, /* tp_dictoffset */
12355 0, /* tp_init */
12356 0, /* tp_alloc */
12357 0, /* tp_new */
12358 0, /* tp_free */
12359 0, /* tp_is_gc */
12360 0, /* tp_bases */
12361 0, /* tp_mro */
12362 0, /* tp_cache */
12363 0, /* tp_subclasses */
12364 0, /* tp_weaklist */
12365 0, /* tp_del */
12366 0, /* tp_version_tag */
12367 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012368};
12369
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012370/*[clinic input]
12371os.scandir
12372
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012373 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012374
12375Return an iterator of DirEntry objects for given path.
12376
12377path can be specified as either str, bytes or path-like object. If path
12378is bytes, the names of yielded DirEntry objects will also be bytes; in
12379all other circumstances they will be str.
12380
12381If path is None, uses the path='.'.
12382[clinic start generated code]*/
12383
Victor Stinner6036e442015-03-08 01:58:04 +010012384static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012385os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012386/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012387{
12388 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012389#ifdef MS_WINDOWS
12390 wchar_t *path_strW;
12391#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012392 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012393#ifdef HAVE_FDOPENDIR
12394 int fd = -1;
12395#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012396#endif
12397
12398 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12399 if (!iterator)
12400 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012401
12402#ifdef MS_WINDOWS
12403 iterator->handle = INVALID_HANDLE_VALUE;
12404#else
12405 iterator->dirp = NULL;
12406#endif
12407
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012408 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012409 /* Move the ownership to iterator->path */
12410 path->object = NULL;
12411 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012412
12413#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012414 iterator->first_time = 1;
12415
12416 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12417 if (!path_strW)
12418 goto error;
12419
12420 Py_BEGIN_ALLOW_THREADS
12421 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12422 Py_END_ALLOW_THREADS
12423
12424 PyMem_Free(path_strW);
12425
12426 if (iterator->handle == INVALID_HANDLE_VALUE) {
12427 path_error(&iterator->path);
12428 goto error;
12429 }
12430#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012431 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012432#ifdef HAVE_FDOPENDIR
12433 if (path->fd != -1) {
12434 /* closedir() closes the FD, so we duplicate it */
12435 fd = _Py_dup(path->fd);
12436 if (fd == -1)
12437 goto error;
12438
12439 Py_BEGIN_ALLOW_THREADS
12440 iterator->dirp = fdopendir(fd);
12441 Py_END_ALLOW_THREADS
12442 }
12443 else
12444#endif
12445 {
12446 if (iterator->path.narrow)
12447 path_str = iterator->path.narrow;
12448 else
12449 path_str = ".";
12450
12451 Py_BEGIN_ALLOW_THREADS
12452 iterator->dirp = opendir(path_str);
12453 Py_END_ALLOW_THREADS
12454 }
Victor Stinner6036e442015-03-08 01:58:04 +010012455
12456 if (!iterator->dirp) {
12457 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012458#ifdef HAVE_FDOPENDIR
12459 if (fd != -1) {
12460 Py_BEGIN_ALLOW_THREADS
12461 close(fd);
12462 Py_END_ALLOW_THREADS
12463 }
12464#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012465 goto error;
12466 }
12467#endif
12468
12469 return (PyObject *)iterator;
12470
12471error:
12472 Py_DECREF(iterator);
12473 return NULL;
12474}
12475
Ethan Furman410ef8e2016-06-04 12:06:26 -070012476/*
12477 Return the file system path representation of the object.
12478
12479 If the object is str or bytes, then allow it to pass through with
12480 an incremented refcount. If the object defines __fspath__(), then
12481 return the result of that method. All other types raise a TypeError.
12482*/
12483PyObject *
12484PyOS_FSPath(PyObject *path)
12485{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012486 /* For error message reasons, this function is manually inlined in
12487 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012488 _Py_IDENTIFIER(__fspath__);
12489 PyObject *func = NULL;
12490 PyObject *path_repr = NULL;
12491
12492 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12493 Py_INCREF(path);
12494 return path;
12495 }
12496
12497 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12498 if (NULL == func) {
12499 return PyErr_Format(PyExc_TypeError,
12500 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012501 "not %.200s",
12502 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012503 }
12504
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012505 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012506 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012507 if (NULL == path_repr) {
12508 return NULL;
12509 }
12510
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012511 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12512 PyErr_Format(PyExc_TypeError,
12513 "expected %.200s.__fspath__() to return str or bytes, "
12514 "not %.200s", Py_TYPE(path)->tp_name,
12515 Py_TYPE(path_repr)->tp_name);
12516 Py_DECREF(path_repr);
12517 return NULL;
12518 }
12519
Ethan Furman410ef8e2016-06-04 12:06:26 -070012520 return path_repr;
12521}
12522
12523/*[clinic input]
12524os.fspath
12525
12526 path: object
12527
12528Return the file system path representation of the object.
12529
Brett Cannonb4f43e92016-06-09 14:32:08 -070012530If the object is str or bytes, then allow it to pass through as-is. If the
12531object defines __fspath__(), then return the result of that method. All other
12532types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012533[clinic start generated code]*/
12534
12535static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012536os_fspath_impl(PyObject *module, PyObject *path)
12537/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012538{
12539 return PyOS_FSPath(path);
12540}
Victor Stinner6036e442015-03-08 01:58:04 +010012541
Victor Stinner9b1f4742016-09-06 16:18:52 -070012542#ifdef HAVE_GETRANDOM_SYSCALL
12543/*[clinic input]
12544os.getrandom
12545
12546 size: Py_ssize_t
12547 flags: int=0
12548
12549Obtain a series of random bytes.
12550[clinic start generated code]*/
12551
12552static PyObject *
12553os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12554/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12555{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012556 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012557 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012558
12559 if (size < 0) {
12560 errno = EINVAL;
12561 return posix_error();
12562 }
12563
Victor Stinnerec2319c2016-09-20 23:00:59 +020012564 bytes = PyBytes_FromStringAndSize(NULL, size);
12565 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012566 PyErr_NoMemory();
12567 return NULL;
12568 }
12569
12570 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012571 n = syscall(SYS_getrandom,
12572 PyBytes_AS_STRING(bytes),
12573 PyBytes_GET_SIZE(bytes),
12574 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012575 if (n < 0 && errno == EINTR) {
12576 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012577 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012578 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012579
12580 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012581 continue;
12582 }
12583 break;
12584 }
12585
12586 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012587 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012588 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012589 }
12590
Victor Stinnerec2319c2016-09-20 23:00:59 +020012591 if (n != size) {
12592 _PyBytes_Resize(&bytes, n);
12593 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012594
12595 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012596
12597error:
12598 Py_DECREF(bytes);
12599 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012600}
12601#endif /* HAVE_GETRANDOM_SYSCALL */
12602
Larry Hastings31826802013-10-19 00:09:25 -070012603
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012604static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012605
12606 OS_STAT_METHODDEF
12607 OS_ACCESS_METHODDEF
12608 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012609 OS_CHDIR_METHODDEF
12610 OS_CHFLAGS_METHODDEF
12611 OS_CHMOD_METHODDEF
12612 OS_FCHMOD_METHODDEF
12613 OS_LCHMOD_METHODDEF
12614 OS_CHOWN_METHODDEF
12615 OS_FCHOWN_METHODDEF
12616 OS_LCHOWN_METHODDEF
12617 OS_LCHFLAGS_METHODDEF
12618 OS_CHROOT_METHODDEF
12619 OS_CTERMID_METHODDEF
12620 OS_GETCWD_METHODDEF
12621 OS_GETCWDB_METHODDEF
12622 OS_LINK_METHODDEF
12623 OS_LISTDIR_METHODDEF
12624 OS_LSTAT_METHODDEF
12625 OS_MKDIR_METHODDEF
12626 OS_NICE_METHODDEF
12627 OS_GETPRIORITY_METHODDEF
12628 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012629#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012630 {"readlink", (PyCFunction)posix_readlink,
12631 METH_VARARGS | METH_KEYWORDS,
12632 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012633#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012634#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012635 {"readlink", (PyCFunction)win_readlink,
12636 METH_VARARGS | METH_KEYWORDS,
12637 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012638#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012639 OS_RENAME_METHODDEF
12640 OS_REPLACE_METHODDEF
12641 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012642 OS_SYMLINK_METHODDEF
12643 OS_SYSTEM_METHODDEF
12644 OS_UMASK_METHODDEF
12645 OS_UNAME_METHODDEF
12646 OS_UNLINK_METHODDEF
12647 OS_REMOVE_METHODDEF
12648 OS_UTIME_METHODDEF
12649 OS_TIMES_METHODDEF
12650 OS__EXIT_METHODDEF
12651 OS_EXECV_METHODDEF
12652 OS_EXECVE_METHODDEF
12653 OS_SPAWNV_METHODDEF
12654 OS_SPAWNVE_METHODDEF
12655 OS_FORK1_METHODDEF
12656 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012657 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012658 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12659 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12660 OS_SCHED_GETPARAM_METHODDEF
12661 OS_SCHED_GETSCHEDULER_METHODDEF
12662 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12663 OS_SCHED_SETPARAM_METHODDEF
12664 OS_SCHED_SETSCHEDULER_METHODDEF
12665 OS_SCHED_YIELD_METHODDEF
12666 OS_SCHED_SETAFFINITY_METHODDEF
12667 OS_SCHED_GETAFFINITY_METHODDEF
12668 OS_OPENPTY_METHODDEF
12669 OS_FORKPTY_METHODDEF
12670 OS_GETEGID_METHODDEF
12671 OS_GETEUID_METHODDEF
12672 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012673#ifdef HAVE_GETGROUPLIST
12674 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12675#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012676 OS_GETGROUPS_METHODDEF
12677 OS_GETPID_METHODDEF
12678 OS_GETPGRP_METHODDEF
12679 OS_GETPPID_METHODDEF
12680 OS_GETUID_METHODDEF
12681 OS_GETLOGIN_METHODDEF
12682 OS_KILL_METHODDEF
12683 OS_KILLPG_METHODDEF
12684 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012685#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012686 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012687#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012688 OS_SETUID_METHODDEF
12689 OS_SETEUID_METHODDEF
12690 OS_SETREUID_METHODDEF
12691 OS_SETGID_METHODDEF
12692 OS_SETEGID_METHODDEF
12693 OS_SETREGID_METHODDEF
12694 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012695#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012696 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012697#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012698 OS_GETPGID_METHODDEF
12699 OS_SETPGRP_METHODDEF
12700 OS_WAIT_METHODDEF
12701 OS_WAIT3_METHODDEF
12702 OS_WAIT4_METHODDEF
12703 OS_WAITID_METHODDEF
12704 OS_WAITPID_METHODDEF
12705 OS_GETSID_METHODDEF
12706 OS_SETSID_METHODDEF
12707 OS_SETPGID_METHODDEF
12708 OS_TCGETPGRP_METHODDEF
12709 OS_TCSETPGRP_METHODDEF
12710 OS_OPEN_METHODDEF
12711 OS_CLOSE_METHODDEF
12712 OS_CLOSERANGE_METHODDEF
12713 OS_DEVICE_ENCODING_METHODDEF
12714 OS_DUP_METHODDEF
12715 OS_DUP2_METHODDEF
12716 OS_LOCKF_METHODDEF
12717 OS_LSEEK_METHODDEF
12718 OS_READ_METHODDEF
12719 OS_READV_METHODDEF
12720 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012721 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012722 OS_WRITE_METHODDEF
12723 OS_WRITEV_METHODDEF
12724 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012725 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012726#ifdef HAVE_SENDFILE
12727 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12728 posix_sendfile__doc__},
12729#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012730 OS_FSTAT_METHODDEF
12731 OS_ISATTY_METHODDEF
12732 OS_PIPE_METHODDEF
12733 OS_PIPE2_METHODDEF
12734 OS_MKFIFO_METHODDEF
12735 OS_MKNOD_METHODDEF
12736 OS_MAJOR_METHODDEF
12737 OS_MINOR_METHODDEF
12738 OS_MAKEDEV_METHODDEF
12739 OS_FTRUNCATE_METHODDEF
12740 OS_TRUNCATE_METHODDEF
12741 OS_POSIX_FALLOCATE_METHODDEF
12742 OS_POSIX_FADVISE_METHODDEF
12743 OS_PUTENV_METHODDEF
12744 OS_UNSETENV_METHODDEF
12745 OS_STRERROR_METHODDEF
12746 OS_FCHDIR_METHODDEF
12747 OS_FSYNC_METHODDEF
12748 OS_SYNC_METHODDEF
12749 OS_FDATASYNC_METHODDEF
12750 OS_WCOREDUMP_METHODDEF
12751 OS_WIFCONTINUED_METHODDEF
12752 OS_WIFSTOPPED_METHODDEF
12753 OS_WIFSIGNALED_METHODDEF
12754 OS_WIFEXITED_METHODDEF
12755 OS_WEXITSTATUS_METHODDEF
12756 OS_WTERMSIG_METHODDEF
12757 OS_WSTOPSIG_METHODDEF
12758 OS_FSTATVFS_METHODDEF
12759 OS_STATVFS_METHODDEF
12760 OS_CONFSTR_METHODDEF
12761 OS_SYSCONF_METHODDEF
12762 OS_FPATHCONF_METHODDEF
12763 OS_PATHCONF_METHODDEF
12764 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012765 OS__GETFULLPATHNAME_METHODDEF
12766 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012767 OS__GETDISKUSAGE_METHODDEF
12768 OS__GETFINALPATHNAME_METHODDEF
12769 OS__GETVOLUMEPATHNAME_METHODDEF
12770 OS_GETLOADAVG_METHODDEF
12771 OS_URANDOM_METHODDEF
12772 OS_SETRESUID_METHODDEF
12773 OS_SETRESGID_METHODDEF
12774 OS_GETRESUID_METHODDEF
12775 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012776
Larry Hastings2f936352014-08-05 14:04:04 +100012777 OS_GETXATTR_METHODDEF
12778 OS_SETXATTR_METHODDEF
12779 OS_REMOVEXATTR_METHODDEF
12780 OS_LISTXATTR_METHODDEF
12781
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012782#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12783 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12784#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012785 OS_CPU_COUNT_METHODDEF
12786 OS_GET_INHERITABLE_METHODDEF
12787 OS_SET_INHERITABLE_METHODDEF
12788 OS_GET_HANDLE_INHERITABLE_METHODDEF
12789 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012790#ifndef MS_WINDOWS
12791 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12792 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12793#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012794 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012795 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012796 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012797 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012798};
12799
12800
Brian Curtin52173d42010-12-02 18:29:18 +000012801#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012802static int
Brian Curtin52173d42010-12-02 18:29:18 +000012803enable_symlink()
12804{
12805 HANDLE tok;
12806 TOKEN_PRIVILEGES tok_priv;
12807 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012808
12809 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012810 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012811
12812 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012813 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012814
12815 tok_priv.PrivilegeCount = 1;
12816 tok_priv.Privileges[0].Luid = luid;
12817 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12818
12819 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12820 sizeof(TOKEN_PRIVILEGES),
12821 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012822 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012823
Brian Curtin3b4499c2010-12-28 14:31:47 +000012824 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12825 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012826}
12827#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12828
Barry Warsaw4a342091996-12-19 23:50:02 +000012829static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012830all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012831{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012832#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012833 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012834#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012835#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012836 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012837#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012838#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012839 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012840#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012841#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012843#endif
Fred Drakec9680921999-12-13 16:37:25 +000012844#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012846#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012847#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012849#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012850#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012852#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012853#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012855#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012856#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012858#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012859#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012861#endif
12862#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012863 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012864#endif
12865#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012867#endif
12868#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012870#endif
12871#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012873#endif
12874#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012876#endif
12877#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012879#endif
12880#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012882#endif
12883#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012885#endif
12886#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012888#endif
12889#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012891#endif
12892#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012894#endif
12895#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012897#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012898#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012900#endif
12901#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012903#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012904#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012906#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012907#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012909#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012910#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012911#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012912 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012913#endif
12914#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012915 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012916#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012917#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012918#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012919 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012920#endif
12921#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012922 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012923#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012924#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012925 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012926#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012927#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012928 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012929#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012930#ifdef O_TMPFILE
12931 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12932#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012933#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012934 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012935#endif
12936#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012937 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012938#endif
12939#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012941#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012942#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012943 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012944#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012945#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012947#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012948
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012949
Jesus Cea94363612012-06-22 18:32:07 +020012950#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012951 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012952#endif
12953#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012954 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012955#endif
12956
Tim Peters5aa91602002-01-30 05:46:57 +000012957/* MS Windows */
12958#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012959 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012961#endif
12962#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012963 /* Optimize for short life (keep in memory). */
12964 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012965 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012966#endif
12967#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012968 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012969 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012970#endif
12971#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012972 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012973 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012974#endif
12975#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012977 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012978#endif
12979
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012980/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012981#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 /* Send a SIGIO signal whenever input or output
12983 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012984 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012985#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012986#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012987 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012988 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012989#endif
12990#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012991 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012992 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012993#endif
12994#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012995 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012996 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012997#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012998#ifdef O_NOLINKS
12999 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013000 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013001#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013002#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013003 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013004 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013005#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013006
Victor Stinner8c62be82010-05-06 00:08:46 +000013007 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013008#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013009 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013010#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013011#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013012 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013013#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013014#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013016#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013017#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013019#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013020#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013022#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013023#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013024 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013025#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013026#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013027 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013028#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013029#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013030 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013031#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013032#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013033 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013034#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013035#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013036 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013037#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013038#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013039 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013040#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013041#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013042 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013043#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013044#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013046#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013047#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013048 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013049#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013050#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013051 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013052#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013053#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013054 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013055#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013056#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013057 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013058#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013059
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013060 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013061#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013062 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013063#endif /* ST_RDONLY */
13064#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013065 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013066#endif /* ST_NOSUID */
13067
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013068 /* GNU extensions */
13069#ifdef ST_NODEV
13070 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13071#endif /* ST_NODEV */
13072#ifdef ST_NOEXEC
13073 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13074#endif /* ST_NOEXEC */
13075#ifdef ST_SYNCHRONOUS
13076 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13077#endif /* ST_SYNCHRONOUS */
13078#ifdef ST_MANDLOCK
13079 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13080#endif /* ST_MANDLOCK */
13081#ifdef ST_WRITE
13082 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13083#endif /* ST_WRITE */
13084#ifdef ST_APPEND
13085 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13086#endif /* ST_APPEND */
13087#ifdef ST_NOATIME
13088 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13089#endif /* ST_NOATIME */
13090#ifdef ST_NODIRATIME
13091 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13092#endif /* ST_NODIRATIME */
13093#ifdef ST_RELATIME
13094 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13095#endif /* ST_RELATIME */
13096
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013097 /* FreeBSD sendfile() constants */
13098#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013099 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013100#endif
13101#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013102 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013103#endif
13104#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013105 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013106#endif
13107
Ross Lagerwall7807c352011-03-17 20:20:30 +020013108 /* constants for posix_fadvise */
13109#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013110 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013111#endif
13112#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013113 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013114#endif
13115#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013116 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013117#endif
13118#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013119 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013120#endif
13121#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013122 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013123#endif
13124#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013125 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013126#endif
13127
13128 /* constants for waitid */
13129#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013130 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13131 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13132 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013133#endif
13134#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013135 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013136#endif
13137#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013138 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013139#endif
13140#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013141 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013142#endif
13143#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013144 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013145#endif
13146#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013147 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013148#endif
13149#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013150 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013151#endif
13152#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013153 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013154#endif
13155
13156 /* constants for lockf */
13157#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013158 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013159#endif
13160#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013161 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013162#endif
13163#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013164 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013165#endif
13166#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013167 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013168#endif
13169
Pablo Galindo4defba32018-01-27 16:16:37 +000013170#ifdef RWF_DSYNC
13171 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13172#endif
13173#ifdef RWF_HIPRI
13174 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13175#endif
13176#ifdef RWF_SYNC
13177 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13178#endif
13179#ifdef RWF_NOWAIT
13180 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13181#endif
13182
Guido van Rossum246bc171999-02-01 23:54:31 +000013183#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013184 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13185 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13186 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13187 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13188 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013189#endif
13190
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013191#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013192#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013193 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013194#endif
13195#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013196 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013197#endif
13198#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013199 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013200#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013201#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013202 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013203#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013204#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013205 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013206#endif
13207#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013208 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013209#endif
13210#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013211 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013212#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013213#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013214 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013215#endif
13216#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013217 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013218#endif
13219#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013220 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013221#endif
13222#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013223 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013224#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013225#endif
13226
Benjamin Peterson9428d532011-09-14 11:45:52 -040013227#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013228 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13229 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13230 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013231#endif
13232
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013233#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013234 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013235#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013236#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013237 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013238#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013239#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013240 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013241#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013242#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013243 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013244#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013245#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013246 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013247#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013248#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013249 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013250#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013251#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013252 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013253#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013254#if HAVE_DECL_RTLD_MEMBER
13255 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13256#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013257
Victor Stinner9b1f4742016-09-06 16:18:52 -070013258#ifdef HAVE_GETRANDOM_SYSCALL
13259 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13260 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13261#endif
13262
Victor Stinner8c62be82010-05-06 00:08:46 +000013263 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013264}
13265
13266
Martin v. Löwis1a214512008-06-11 05:26:20 +000013267static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013268 PyModuleDef_HEAD_INIT,
13269 MODNAME,
13270 posix__doc__,
13271 -1,
13272 posix_methods,
13273 NULL,
13274 NULL,
13275 NULL,
13276 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013277};
13278
13279
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013280static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013281
13282#ifdef HAVE_FACCESSAT
13283 "HAVE_FACCESSAT",
13284#endif
13285
13286#ifdef HAVE_FCHDIR
13287 "HAVE_FCHDIR",
13288#endif
13289
13290#ifdef HAVE_FCHMOD
13291 "HAVE_FCHMOD",
13292#endif
13293
13294#ifdef HAVE_FCHMODAT
13295 "HAVE_FCHMODAT",
13296#endif
13297
13298#ifdef HAVE_FCHOWN
13299 "HAVE_FCHOWN",
13300#endif
13301
Larry Hastings00964ed2013-08-12 13:49:30 -040013302#ifdef HAVE_FCHOWNAT
13303 "HAVE_FCHOWNAT",
13304#endif
13305
Larry Hastings9cf065c2012-06-22 16:30:09 -070013306#ifdef HAVE_FEXECVE
13307 "HAVE_FEXECVE",
13308#endif
13309
13310#ifdef HAVE_FDOPENDIR
13311 "HAVE_FDOPENDIR",
13312#endif
13313
Georg Brandl306336b2012-06-24 12:55:33 +020013314#ifdef HAVE_FPATHCONF
13315 "HAVE_FPATHCONF",
13316#endif
13317
Larry Hastings9cf065c2012-06-22 16:30:09 -070013318#ifdef HAVE_FSTATAT
13319 "HAVE_FSTATAT",
13320#endif
13321
13322#ifdef HAVE_FSTATVFS
13323 "HAVE_FSTATVFS",
13324#endif
13325
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013326#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013327 "HAVE_FTRUNCATE",
13328#endif
13329
Larry Hastings9cf065c2012-06-22 16:30:09 -070013330#ifdef HAVE_FUTIMENS
13331 "HAVE_FUTIMENS",
13332#endif
13333
13334#ifdef HAVE_FUTIMES
13335 "HAVE_FUTIMES",
13336#endif
13337
13338#ifdef HAVE_FUTIMESAT
13339 "HAVE_FUTIMESAT",
13340#endif
13341
13342#ifdef HAVE_LINKAT
13343 "HAVE_LINKAT",
13344#endif
13345
13346#ifdef HAVE_LCHFLAGS
13347 "HAVE_LCHFLAGS",
13348#endif
13349
13350#ifdef HAVE_LCHMOD
13351 "HAVE_LCHMOD",
13352#endif
13353
13354#ifdef HAVE_LCHOWN
13355 "HAVE_LCHOWN",
13356#endif
13357
13358#ifdef HAVE_LSTAT
13359 "HAVE_LSTAT",
13360#endif
13361
13362#ifdef HAVE_LUTIMES
13363 "HAVE_LUTIMES",
13364#endif
13365
13366#ifdef HAVE_MKDIRAT
13367 "HAVE_MKDIRAT",
13368#endif
13369
13370#ifdef HAVE_MKFIFOAT
13371 "HAVE_MKFIFOAT",
13372#endif
13373
13374#ifdef HAVE_MKNODAT
13375 "HAVE_MKNODAT",
13376#endif
13377
13378#ifdef HAVE_OPENAT
13379 "HAVE_OPENAT",
13380#endif
13381
13382#ifdef HAVE_READLINKAT
13383 "HAVE_READLINKAT",
13384#endif
13385
13386#ifdef HAVE_RENAMEAT
13387 "HAVE_RENAMEAT",
13388#endif
13389
13390#ifdef HAVE_SYMLINKAT
13391 "HAVE_SYMLINKAT",
13392#endif
13393
13394#ifdef HAVE_UNLINKAT
13395 "HAVE_UNLINKAT",
13396#endif
13397
13398#ifdef HAVE_UTIMENSAT
13399 "HAVE_UTIMENSAT",
13400#endif
13401
13402#ifdef MS_WINDOWS
13403 "MS_WINDOWS",
13404#endif
13405
13406 NULL
13407};
13408
13409
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013410PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013411INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013412{
Victor Stinner8c62be82010-05-06 00:08:46 +000013413 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013414 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013415 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013416
Brian Curtin52173d42010-12-02 18:29:18 +000013417#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013418 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013419#endif
13420
Victor Stinner8c62be82010-05-06 00:08:46 +000013421 m = PyModule_Create(&posixmodule);
13422 if (m == NULL)
13423 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013424
Victor Stinner8c62be82010-05-06 00:08:46 +000013425 /* Initialize environ dictionary */
13426 v = convertenviron();
13427 Py_XINCREF(v);
13428 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13429 return NULL;
13430 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013431
Victor Stinner8c62be82010-05-06 00:08:46 +000013432 if (all_ins(m))
13433 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013434
Victor Stinner8c62be82010-05-06 00:08:46 +000013435 if (setup_confname_tables(m))
13436 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013437
Victor Stinner8c62be82010-05-06 00:08:46 +000013438 Py_INCREF(PyExc_OSError);
13439 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013440
Guido van Rossumb3d39562000-01-31 18:41:26 +000013441#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013442 if (posix_putenv_garbage == NULL)
13443 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013444#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013445
Victor Stinner8c62be82010-05-06 00:08:46 +000013446 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013447#if defined(HAVE_WAITID) && !defined(__APPLE__)
13448 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013449 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13450 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013451#endif
13452
Christian Heimes25827622013-10-12 01:27:08 +020013453 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013454 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13455 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13456 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013457 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13458 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013459 structseq_new = StatResultType.tp_new;
13460 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013461
Christian Heimes25827622013-10-12 01:27:08 +020013462 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013463 if (PyStructSequence_InitType2(&StatVFSResultType,
13464 &statvfs_result_desc) < 0)
13465 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013466#ifdef NEED_TICKS_PER_SECOND
13467# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013468 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013469# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013470 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013471# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013472 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013473# endif
13474#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013475
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013476#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013477 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013478 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13479 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013480 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013481#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013482
13483 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013484 if (PyStructSequence_InitType2(&TerminalSizeType,
13485 &TerminalSize_desc) < 0)
13486 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013487
13488 /* initialize scandir types */
13489 if (PyType_Ready(&ScandirIteratorType) < 0)
13490 return NULL;
13491 if (PyType_Ready(&DirEntryType) < 0)
13492 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013493 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013494#if defined(HAVE_WAITID) && !defined(__APPLE__)
13495 Py_INCREF((PyObject*) &WaitidResultType);
13496 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13497#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013498 Py_INCREF((PyObject*) &StatResultType);
13499 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13500 Py_INCREF((PyObject*) &StatVFSResultType);
13501 PyModule_AddObject(m, "statvfs_result",
13502 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013503
13504#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013505 Py_INCREF(&SchedParamType);
13506 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013507#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013508
Larry Hastings605a62d2012-06-24 04:33:36 -070013509 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013510 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13511 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013512 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13513
13514 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013515 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13516 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013517 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13518
Thomas Wouters477c8d52006-05-27 19:21:47 +000013519#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013520 /*
13521 * Step 2 of weak-linking support on Mac OS X.
13522 *
13523 * The code below removes functions that are not available on the
13524 * currently active platform.
13525 *
13526 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013527 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013528 * OSX 10.4.
13529 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013530#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013531 if (fstatvfs == NULL) {
13532 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13533 return NULL;
13534 }
13535 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013536#endif /* HAVE_FSTATVFS */
13537
13538#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013539 if (statvfs == NULL) {
13540 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13541 return NULL;
13542 }
13543 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013544#endif /* HAVE_STATVFS */
13545
13546# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013547 if (lchown == NULL) {
13548 if (PyObject_DelAttrString(m, "lchown") == -1) {
13549 return NULL;
13550 }
13551 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013552#endif /* HAVE_LCHOWN */
13553
13554
13555#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013556
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013557 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013558 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13559
Larry Hastings6fe20b32012-04-19 15:07:49 -070013560 billion = PyLong_FromLong(1000000000);
13561 if (!billion)
13562 return NULL;
13563
Larry Hastings9cf065c2012-06-22 16:30:09 -070013564 /* suppress "function not used" warnings */
13565 {
13566 int ignored;
13567 fd_specified("", -1);
13568 follow_symlinks_specified("", 1);
13569 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13570 dir_fd_converter(Py_None, &ignored);
13571 dir_fd_unavailable(Py_None, &ignored);
13572 }
13573
13574 /*
13575 * provide list of locally available functions
13576 * so os.py can populate support_* lists
13577 */
13578 list = PyList_New(0);
13579 if (!list)
13580 return NULL;
13581 for (trace = have_functions; *trace; trace++) {
13582 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13583 if (!unicode)
13584 return NULL;
13585 if (PyList_Append(list, unicode))
13586 return NULL;
13587 Py_DECREF(unicode);
13588 }
13589 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013590
13591 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013592 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013593
13594 initialized = 1;
13595
Victor Stinner8c62be82010-05-06 00:08:46 +000013596 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013597}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013598
13599#ifdef __cplusplus
13600}
13601#endif