blob: c3682b4a0fd5f9864ec89d44bfd1d70028490238 [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__) \
8029 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008030static Py_ssize_t
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008031iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008033 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008034 Py_ssize_t blen, total = 0;
8035
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008036 *iov = PyMem_New(struct iovec, cnt);
8037 if (*iov == NULL) {
8038 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008039 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008040 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008041
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 *buf = PyMem_New(Py_buffer, cnt);
8043 if (*buf == NULL) {
8044 PyMem_Del(*iov);
8045 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008046 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008047 }
8048
8049 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008050 PyObject *item = PySequence_GetItem(seq, i);
8051 if (item == NULL)
8052 goto fail;
8053 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8054 Py_DECREF(item);
8055 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008056 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008057 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008058 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008059 blen = (*buf)[i].len;
8060 (*iov)[i].iov_len = blen;
8061 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008062 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008063 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008064
8065fail:
8066 PyMem_Del(*iov);
8067 for (j = 0; j < i; j++) {
8068 PyBuffer_Release(&(*buf)[j]);
8069 }
8070 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008071 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072}
8073
8074static void
8075iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8076{
8077 int i;
8078 PyMem_Del(iov);
8079 for (i = 0; i < cnt; i++) {
8080 PyBuffer_Release(&buf[i]);
8081 }
8082 PyMem_Del(buf);
8083}
8084#endif
8085
Larry Hastings2f936352014-08-05 14:04:04 +10008086
Ross Lagerwall7807c352011-03-17 20:20:30 +02008087#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008088/*[clinic input]
8089os.readv -> Py_ssize_t
8090
8091 fd: int
8092 buffers: object
8093 /
8094
8095Read from a file descriptor fd into an iterable of buffers.
8096
8097The buffers should be mutable buffers accepting bytes.
8098readv will transfer data into each buffer until it is full
8099and then move on to the next buffer in the sequence to hold
8100the rest of the data.
8101
8102readv returns the total number of bytes read,
8103which may be less than the total capacity of all the buffers.
8104[clinic start generated code]*/
8105
Larry Hastings2f936352014-08-05 14:04:04 +10008106static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008107os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8108/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008109{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008110 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008111 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008112 struct iovec *iov;
8113 Py_buffer *buf;
8114
Larry Hastings2f936352014-08-05 14:04:04 +10008115 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008116 PyErr_SetString(PyExc_TypeError,
8117 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008118 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008119 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008120
Larry Hastings2f936352014-08-05 14:04:04 +10008121 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008122 if (cnt < 0)
8123 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008124
8125 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8126 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008127
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008128 do {
8129 Py_BEGIN_ALLOW_THREADS
8130 n = readv(fd, iov, cnt);
8131 Py_END_ALLOW_THREADS
8132 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133
8134 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008135 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008136 if (!async_err)
8137 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008138 return -1;
8139 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008140
Larry Hastings2f936352014-08-05 14:04:04 +10008141 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008142}
Larry Hastings2f936352014-08-05 14:04:04 +10008143#endif /* HAVE_READV */
8144
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145
8146#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008147/*[clinic input]
8148# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8149os.pread
8150
8151 fd: int
8152 length: int
8153 offset: Py_off_t
8154 /
8155
8156Read a number of bytes from a file descriptor starting at a particular offset.
8157
8158Read length bytes from file descriptor fd, starting at offset bytes from
8159the beginning of the file. The file offset remains unchanged.
8160[clinic start generated code]*/
8161
Larry Hastings2f936352014-08-05 14:04:04 +10008162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008163os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8164/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008165{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008166 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008167 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169
Larry Hastings2f936352014-08-05 14:04:04 +10008170 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171 errno = EINVAL;
8172 return posix_error();
8173 }
Larry Hastings2f936352014-08-05 14:04:04 +10008174 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175 if (buffer == NULL)
8176 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008177
8178 do {
8179 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008180 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008181 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008182 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008183 Py_END_ALLOW_THREADS
8184 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8185
Ross Lagerwall7807c352011-03-17 20:20:30 +02008186 if (n < 0) {
8187 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008188 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189 }
Larry Hastings2f936352014-08-05 14:04:04 +10008190 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191 _PyBytes_Resize(&buffer, n);
8192 return buffer;
8193}
Larry Hastings2f936352014-08-05 14:04:04 +10008194#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008195
Pablo Galindo4defba32018-01-27 16:16:37 +00008196#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8197/*[clinic input]
8198os.preadv -> Py_ssize_t
8199
8200 fd: int
8201 buffers: object
8202 offset: Py_off_t
8203 flags: int = 0
8204 /
8205
8206Reads from a file descriptor into a number of mutable bytes-like objects.
8207
8208Combines the functionality of readv() and pread(). As readv(), it will
8209transfer data into each buffer until it is full and then move on to the next
8210buffer in the sequence to hold the rest of the data. Its fourth argument,
8211specifies the file offset at which the input operation is to be performed. It
8212will return the total number of bytes read (which can be less than the total
8213capacity of all the objects).
8214
8215The flags argument contains a bitwise OR of zero or more of the following flags:
8216
8217- RWF_HIPRI
8218- RWF_NOWAIT
8219
8220Using non-zero flags requires Linux 4.6 or newer.
8221[clinic start generated code]*/
8222
8223static Py_ssize_t
8224os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8225 int flags)
8226/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8227{
8228 Py_ssize_t cnt, n;
8229 int async_err = 0;
8230 struct iovec *iov;
8231 Py_buffer *buf;
8232
8233 if (!PySequence_Check(buffers)) {
8234 PyErr_SetString(PyExc_TypeError,
8235 "preadv2() arg 2 must be a sequence");
8236 return -1;
8237 }
8238
8239 cnt = PySequence_Size(buffers);
8240 if (cnt < 0) {
8241 return -1;
8242 }
8243
8244#ifndef HAVE_PREADV2
8245 if(flags != 0) {
8246 argument_unavailable_error("preadv2", "flags");
8247 return -1;
8248 }
8249#endif
8250
8251 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8252 return -1;
8253 }
8254#ifdef HAVE_PREADV2
8255 do {
8256 Py_BEGIN_ALLOW_THREADS
8257 _Py_BEGIN_SUPPRESS_IPH
8258 n = preadv2(fd, iov, cnt, offset, flags);
8259 _Py_END_SUPPRESS_IPH
8260 Py_END_ALLOW_THREADS
8261 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8262#else
8263 do {
8264 Py_BEGIN_ALLOW_THREADS
8265 _Py_BEGIN_SUPPRESS_IPH
8266 n = preadv(fd, iov, cnt, offset);
8267 _Py_END_SUPPRESS_IPH
8268 Py_END_ALLOW_THREADS
8269 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8270#endif
8271
8272 iov_cleanup(iov, buf, cnt);
8273 if (n < 0) {
8274 if (!async_err) {
8275 posix_error();
8276 }
8277 return -1;
8278 }
8279
8280 return n;
8281}
8282#endif /* HAVE_PREADV */
8283
Larry Hastings2f936352014-08-05 14:04:04 +10008284
8285/*[clinic input]
8286os.write -> Py_ssize_t
8287
8288 fd: int
8289 data: Py_buffer
8290 /
8291
8292Write a bytes object to a file descriptor.
8293[clinic start generated code]*/
8294
Larry Hastings2f936352014-08-05 14:04:04 +10008295static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008296os_write_impl(PyObject *module, int fd, Py_buffer *data)
8297/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008298{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008299 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008300}
8301
8302#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008303PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008304"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008305sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008306 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008307Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308
Larry Hastings2f936352014-08-05 14:04:04 +10008309/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008310static PyObject *
8311posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8312{
8313 int in, out;
8314 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008315 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008316 off_t offset;
8317
8318#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8319#ifndef __APPLE__
8320 Py_ssize_t len;
8321#endif
8322 PyObject *headers = NULL, *trailers = NULL;
8323 Py_buffer *hbuf, *tbuf;
8324 off_t sbytes;
8325 struct sf_hdtr sf;
8326 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008327 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008328 static char *keywords[] = {"out", "in",
8329 "offset", "count",
8330 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008332 sf.headers = NULL;
8333 sf.trailers = NULL;
8334
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335#ifdef __APPLE__
8336 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008337 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008338#else
8339 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008340 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008341#endif
8342 &headers, &trailers, &flags))
8343 return NULL;
8344 if (headers != NULL) {
8345 if (!PySequence_Check(headers)) {
8346 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008347 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008348 return NULL;
8349 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008350 Py_ssize_t i = PySequence_Size(headers);
8351 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008352 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008353 if (i > INT_MAX) {
8354 PyErr_SetString(PyExc_OverflowError,
8355 "sendfile() header is too large");
8356 return NULL;
8357 }
8358 if (i > 0) {
8359 sf.hdr_cnt = (int)i;
8360 i = iov_setup(&(sf.headers), &hbuf,
8361 headers, sf.hdr_cnt, PyBUF_SIMPLE);
8362 if (i < 0)
8363 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008364#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008365 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008366#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008367 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008368 }
8369 }
8370 if (trailers != NULL) {
8371 if (!PySequence_Check(trailers)) {
8372 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008373 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008374 return NULL;
8375 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008376 Py_ssize_t i = PySequence_Size(trailers);
8377 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008378 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008379 if (i > INT_MAX) {
8380 PyErr_SetString(PyExc_OverflowError,
8381 "sendfile() trailer is too large");
8382 return NULL;
8383 }
8384 if (i > 0) {
8385 sf.trl_cnt = (int)i;
8386 i = iov_setup(&(sf.trailers), &tbuf,
8387 trailers, sf.trl_cnt, PyBUF_SIMPLE);
8388 if (i < 0)
8389 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008390#ifdef __APPLE__
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008391 sbytes += i;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008392#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008393 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008394 }
8395 }
8396
Steve Dower8fc89802015-04-12 00:26:27 -04008397 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008398 do {
8399 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008400#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008401 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008402#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008403 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008404#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008405 Py_END_ALLOW_THREADS
8406 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008407 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008408
8409 if (sf.headers != NULL)
8410 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8411 if (sf.trailers != NULL)
8412 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8413
8414 if (ret < 0) {
8415 if ((errno == EAGAIN) || (errno == EBUSY)) {
8416 if (sbytes != 0) {
8417 // some data has been sent
8418 goto done;
8419 }
8420 else {
8421 // no data has been sent; upper application is supposed
8422 // to retry on EAGAIN or EBUSY
8423 return posix_error();
8424 }
8425 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008426 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008427 }
8428 goto done;
8429
8430done:
8431 #if !defined(HAVE_LARGEFILE_SUPPORT)
8432 return Py_BuildValue("l", sbytes);
8433 #else
8434 return Py_BuildValue("L", sbytes);
8435 #endif
8436
8437#else
8438 Py_ssize_t count;
8439 PyObject *offobj;
8440 static char *keywords[] = {"out", "in",
8441 "offset", "count", NULL};
8442 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8443 keywords, &out, &in, &offobj, &count))
8444 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008445#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008446 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008447 do {
8448 Py_BEGIN_ALLOW_THREADS
8449 ret = sendfile(out, in, NULL, count);
8450 Py_END_ALLOW_THREADS
8451 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008452 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008453 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008454 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008455 }
8456#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008457 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008458 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008459
8460 do {
8461 Py_BEGIN_ALLOW_THREADS
8462 ret = sendfile(out, in, &offset, count);
8463 Py_END_ALLOW_THREADS
8464 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008465 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008466 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008467 return Py_BuildValue("n", ret);
8468#endif
8469}
Larry Hastings2f936352014-08-05 14:04:04 +10008470#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008471
Larry Hastings2f936352014-08-05 14:04:04 +10008472
8473/*[clinic input]
8474os.fstat
8475
8476 fd : int
8477
8478Perform a stat system call on the given file descriptor.
8479
8480Like stat(), but for an open file descriptor.
8481Equivalent to os.stat(fd).
8482[clinic start generated code]*/
8483
Larry Hastings2f936352014-08-05 14:04:04 +10008484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008485os_fstat_impl(PyObject *module, int fd)
8486/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008487{
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 STRUCT_STAT st;
8489 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008490 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008491
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008492 do {
8493 Py_BEGIN_ALLOW_THREADS
8494 res = FSTAT(fd, &st);
8495 Py_END_ALLOW_THREADS
8496 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008498#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008499 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008500#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008501 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008502#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008503 }
Tim Peters5aa91602002-01-30 05:46:57 +00008504
Victor Stinner4195b5c2012-02-08 23:03:19 +01008505 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008506}
8507
Larry Hastings2f936352014-08-05 14:04:04 +10008508
8509/*[clinic input]
8510os.isatty -> bool
8511 fd: int
8512 /
8513
8514Return True if the fd is connected to a terminal.
8515
8516Return True if the file descriptor is an open file descriptor
8517connected to the slave end of a terminal.
8518[clinic start generated code]*/
8519
Larry Hastings2f936352014-08-05 14:04:04 +10008520static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008521os_isatty_impl(PyObject *module, int fd)
8522/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008523{
Steve Dower8fc89802015-04-12 00:26:27 -04008524 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008525 _Py_BEGIN_SUPPRESS_IPH
8526 return_value = isatty(fd);
8527 _Py_END_SUPPRESS_IPH
8528 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008529}
8530
8531
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008532#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008533/*[clinic input]
8534os.pipe
8535
8536Create a pipe.
8537
8538Returns a tuple of two file descriptors:
8539 (read_fd, write_fd)
8540[clinic start generated code]*/
8541
Larry Hastings2f936352014-08-05 14:04:04 +10008542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008543os_pipe_impl(PyObject *module)
8544/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008545{
Victor Stinner8c62be82010-05-06 00:08:46 +00008546 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008547#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008548 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008549 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008550 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008551#else
8552 int res;
8553#endif
8554
8555#ifdef MS_WINDOWS
8556 attr.nLength = sizeof(attr);
8557 attr.lpSecurityDescriptor = NULL;
8558 attr.bInheritHandle = FALSE;
8559
8560 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008561 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008562 ok = CreatePipe(&read, &write, &attr, 0);
8563 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008564 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8565 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008566 if (fds[0] == -1 || fds[1] == -1) {
8567 CloseHandle(read);
8568 CloseHandle(write);
8569 ok = 0;
8570 }
8571 }
Steve Dowerc3630612016-11-19 18:41:16 -08008572 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008573 Py_END_ALLOW_THREADS
8574
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008576 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008577#else
8578
8579#ifdef HAVE_PIPE2
8580 Py_BEGIN_ALLOW_THREADS
8581 res = pipe2(fds, O_CLOEXEC);
8582 Py_END_ALLOW_THREADS
8583
8584 if (res != 0 && errno == ENOSYS)
8585 {
8586#endif
8587 Py_BEGIN_ALLOW_THREADS
8588 res = pipe(fds);
8589 Py_END_ALLOW_THREADS
8590
8591 if (res == 0) {
8592 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8593 close(fds[0]);
8594 close(fds[1]);
8595 return NULL;
8596 }
8597 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8598 close(fds[0]);
8599 close(fds[1]);
8600 return NULL;
8601 }
8602 }
8603#ifdef HAVE_PIPE2
8604 }
8605#endif
8606
8607 if (res != 0)
8608 return PyErr_SetFromErrno(PyExc_OSError);
8609#endif /* !MS_WINDOWS */
8610 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008611}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008612#endif /* HAVE_PIPE */
8613
Larry Hastings2f936352014-08-05 14:04:04 +10008614
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008615#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008616/*[clinic input]
8617os.pipe2
8618
8619 flags: int
8620 /
8621
8622Create a pipe with flags set atomically.
8623
8624Returns a tuple of two file descriptors:
8625 (read_fd, write_fd)
8626
8627flags can be constructed by ORing together one or more of these values:
8628O_NONBLOCK, O_CLOEXEC.
8629[clinic start generated code]*/
8630
Larry Hastings2f936352014-08-05 14:04:04 +10008631static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008632os_pipe2_impl(PyObject *module, int flags)
8633/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008634{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008635 int fds[2];
8636 int res;
8637
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008638 res = pipe2(fds, flags);
8639 if (res != 0)
8640 return posix_error();
8641 return Py_BuildValue("(ii)", fds[0], fds[1]);
8642}
8643#endif /* HAVE_PIPE2 */
8644
Larry Hastings2f936352014-08-05 14:04:04 +10008645
Ross Lagerwall7807c352011-03-17 20:20:30 +02008646#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008647/*[clinic input]
8648os.writev -> Py_ssize_t
8649 fd: int
8650 buffers: object
8651 /
8652
8653Iterate over buffers, and write the contents of each to a file descriptor.
8654
8655Returns the total number of bytes written.
8656buffers must be a sequence of bytes-like objects.
8657[clinic start generated code]*/
8658
Larry Hastings2f936352014-08-05 14:04:04 +10008659static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008660os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8661/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008662{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008663 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008664 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008665 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008666 struct iovec *iov;
8667 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008668
8669 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008670 PyErr_SetString(PyExc_TypeError,
8671 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008672 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008673 }
Larry Hastings2f936352014-08-05 14:04:04 +10008674 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008675 if (cnt < 0)
8676 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008677
Larry Hastings2f936352014-08-05 14:04:04 +10008678 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8679 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008680 }
8681
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008682 do {
8683 Py_BEGIN_ALLOW_THREADS
8684 result = writev(fd, iov, cnt);
8685 Py_END_ALLOW_THREADS
8686 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008687
8688 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008689 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008690 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008691
Georg Brandl306336b2012-06-24 12:55:33 +02008692 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008693}
Larry Hastings2f936352014-08-05 14:04:04 +10008694#endif /* HAVE_WRITEV */
8695
8696
8697#ifdef HAVE_PWRITE
8698/*[clinic input]
8699os.pwrite -> Py_ssize_t
8700
8701 fd: int
8702 buffer: Py_buffer
8703 offset: Py_off_t
8704 /
8705
8706Write bytes to a file descriptor starting at a particular offset.
8707
8708Write buffer to fd, starting at offset bytes from the beginning of
8709the file. Returns the number of bytes writte. Does not change the
8710current file offset.
8711[clinic start generated code]*/
8712
Larry Hastings2f936352014-08-05 14:04:04 +10008713static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008714os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8715/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008716{
8717 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008718 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008719
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008720 do {
8721 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008722 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008723 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008724 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008725 Py_END_ALLOW_THREADS
8726 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008727
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008728 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008729 posix_error();
8730 return size;
8731}
8732#endif /* HAVE_PWRITE */
8733
Pablo Galindo4defba32018-01-27 16:16:37 +00008734#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8735/*[clinic input]
8736os.pwritev -> Py_ssize_t
8737
8738 fd: int
8739 buffers: object
8740 offset: Py_off_t
8741 flags: int = 0
8742 /
8743
8744Writes the contents of bytes-like objects to a file descriptor at a given offset.
8745
8746Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8747of bytes-like objects. Buffers are processed in array order. Entire contents of first
8748buffer is written before proceeding to second, and so on. The operating system may
8749set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8750This function writes the contents of each object to the file descriptor and returns
8751the total number of bytes written.
8752
8753The flags argument contains a bitwise OR of zero or more of the following flags:
8754
8755- RWF_DSYNC
8756- RWF_SYNC
8757
8758Using non-zero flags requires Linux 4.7 or newer.
8759[clinic start generated code]*/
8760
8761static Py_ssize_t
8762os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8763 int flags)
8764/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8765{
8766 Py_ssize_t cnt;
8767 Py_ssize_t result;
8768 int async_err = 0;
8769 struct iovec *iov;
8770 Py_buffer *buf;
8771
8772 if (!PySequence_Check(buffers)) {
8773 PyErr_SetString(PyExc_TypeError,
8774 "pwritev() arg 2 must be a sequence");
8775 return -1;
8776 }
8777
8778 cnt = PySequence_Size(buffers);
8779 if (cnt < 0) {
8780 return -1;
8781 }
8782
8783#ifndef HAVE_PWRITEV2
8784 if(flags != 0) {
8785 argument_unavailable_error("pwritev2", "flags");
8786 return -1;
8787 }
8788#endif
8789
8790 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8791 return -1;
8792 }
8793#ifdef HAVE_PWRITEV2
8794 do {
8795 Py_BEGIN_ALLOW_THREADS
8796 _Py_BEGIN_SUPPRESS_IPH
8797 result = pwritev2(fd, iov, cnt, offset, flags);
8798 _Py_END_SUPPRESS_IPH
8799 Py_END_ALLOW_THREADS
8800 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8801#else
8802 do {
8803 Py_BEGIN_ALLOW_THREADS
8804 _Py_BEGIN_SUPPRESS_IPH
8805 result = pwritev(fd, iov, cnt, offset);
8806 _Py_END_SUPPRESS_IPH
8807 Py_END_ALLOW_THREADS
8808 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8809#endif
8810
8811 iov_cleanup(iov, buf, cnt);
8812 if (result < 0) {
8813 if (!async_err) {
8814 posix_error();
8815 }
8816 return -1;
8817 }
8818
8819 return result;
8820}
8821#endif /* HAVE_PWRITEV */
8822
8823
8824
Larry Hastings2f936352014-08-05 14:04:04 +10008825
8826#ifdef HAVE_MKFIFO
8827/*[clinic input]
8828os.mkfifo
8829
8830 path: path_t
8831 mode: int=0o666
8832 *
8833 dir_fd: dir_fd(requires='mkfifoat')=None
8834
8835Create a "fifo" (a POSIX named pipe).
8836
8837If dir_fd is not None, it should be a file descriptor open to a directory,
8838 and path should be relative; path will then be relative to that directory.
8839dir_fd may not be implemented on your platform.
8840 If it is unavailable, using it will raise a NotImplementedError.
8841[clinic start generated code]*/
8842
Larry Hastings2f936352014-08-05 14:04:04 +10008843static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008844os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8845/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008846{
8847 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008848 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008849
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008850 do {
8851 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008852#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008853 if (dir_fd != DEFAULT_DIR_FD)
8854 result = mkfifoat(dir_fd, path->narrow, mode);
8855 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008856#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008857 result = mkfifo(path->narrow, mode);
8858 Py_END_ALLOW_THREADS
8859 } while (result != 0 && errno == EINTR &&
8860 !(async_err = PyErr_CheckSignals()));
8861 if (result != 0)
8862 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008863
8864 Py_RETURN_NONE;
8865}
8866#endif /* HAVE_MKFIFO */
8867
8868
8869#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8870/*[clinic input]
8871os.mknod
8872
8873 path: path_t
8874 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008875 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008876 *
8877 dir_fd: dir_fd(requires='mknodat')=None
8878
8879Create a node in the file system.
8880
8881Create a node in the file system (file, device special file or named pipe)
8882at path. mode specifies both the permissions to use and the
8883type of node to be created, being combined (bitwise OR) with one of
8884S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8885device defines the newly created device special file (probably using
8886os.makedev()). Otherwise device is ignored.
8887
8888If dir_fd is not None, it should be a file descriptor open to a directory,
8889 and path should be relative; path will then be relative to that directory.
8890dir_fd may not be implemented on your platform.
8891 If it is unavailable, using it will raise a NotImplementedError.
8892[clinic start generated code]*/
8893
Larry Hastings2f936352014-08-05 14:04:04 +10008894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008895os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008896 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008897/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008898{
8899 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008900 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008901
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008902 do {
8903 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008904#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008905 if (dir_fd != DEFAULT_DIR_FD)
8906 result = mknodat(dir_fd, path->narrow, mode, device);
8907 else
Larry Hastings2f936352014-08-05 14:04:04 +10008908#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008909 result = mknod(path->narrow, mode, device);
8910 Py_END_ALLOW_THREADS
8911 } while (result != 0 && errno == EINTR &&
8912 !(async_err = PyErr_CheckSignals()));
8913 if (result != 0)
8914 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008915
8916 Py_RETURN_NONE;
8917}
8918#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8919
8920
8921#ifdef HAVE_DEVICE_MACROS
8922/*[clinic input]
8923os.major -> unsigned_int
8924
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008925 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008926 /
8927
8928Extracts a device major number from a raw device number.
8929[clinic start generated code]*/
8930
Larry Hastings2f936352014-08-05 14:04:04 +10008931static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008932os_major_impl(PyObject *module, dev_t device)
8933/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008934{
8935 return major(device);
8936}
8937
8938
8939/*[clinic input]
8940os.minor -> unsigned_int
8941
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008942 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008943 /
8944
8945Extracts a device minor number from a raw device number.
8946[clinic start generated code]*/
8947
Larry Hastings2f936352014-08-05 14:04:04 +10008948static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008949os_minor_impl(PyObject *module, dev_t device)
8950/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008951{
8952 return minor(device);
8953}
8954
8955
8956/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008957os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008958
8959 major: int
8960 minor: int
8961 /
8962
8963Composes a raw device number from the major and minor device numbers.
8964[clinic start generated code]*/
8965
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008966static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008967os_makedev_impl(PyObject *module, int major, int minor)
8968/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008969{
8970 return makedev(major, minor);
8971}
8972#endif /* HAVE_DEVICE_MACROS */
8973
8974
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008975#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008976/*[clinic input]
8977os.ftruncate
8978
8979 fd: int
8980 length: Py_off_t
8981 /
8982
8983Truncate a file, specified by file descriptor, to a specific length.
8984[clinic start generated code]*/
8985
Larry Hastings2f936352014-08-05 14:04:04 +10008986static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008987os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8988/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008989{
8990 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008991 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008992
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008993 do {
8994 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008995 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008996#ifdef MS_WINDOWS
8997 result = _chsize_s(fd, length);
8998#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008999 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009000#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009001 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009002 Py_END_ALLOW_THREADS
9003 } while (result != 0 && errno == EINTR &&
9004 !(async_err = PyErr_CheckSignals()));
9005 if (result != 0)
9006 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009007 Py_RETURN_NONE;
9008}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009009#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009010
9011
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009012#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009013/*[clinic input]
9014os.truncate
9015 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9016 length: Py_off_t
9017
9018Truncate a file, specified by path, to a specific length.
9019
9020On some platforms, path may also be specified as an open file descriptor.
9021 If this functionality is unavailable, using it raises an exception.
9022[clinic start generated code]*/
9023
Larry Hastings2f936352014-08-05 14:04:04 +10009024static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009025os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9026/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009027{
9028 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009029#ifdef MS_WINDOWS
9030 int fd;
9031#endif
9032
9033 if (path->fd != -1)
9034 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009035
9036 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009037 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009038#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009039 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009040 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009041 result = -1;
9042 else {
9043 result = _chsize_s(fd, length);
9044 close(fd);
9045 if (result < 0)
9046 errno = result;
9047 }
9048#else
9049 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009050#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009051 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009052 Py_END_ALLOW_THREADS
9053 if (result < 0)
9054 return path_error(path);
9055
9056 Py_RETURN_NONE;
9057}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009058#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009059
Ross Lagerwall7807c352011-03-17 20:20:30 +02009060
Victor Stinnerd6b17692014-09-30 12:20:05 +02009061/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9062 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9063 defined, which is the case in Python on AIX. AIX bug report:
9064 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9065#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9066# define POSIX_FADVISE_AIX_BUG
9067#endif
9068
Victor Stinnerec39e262014-09-30 12:35:58 +02009069
Victor Stinnerd6b17692014-09-30 12:20:05 +02009070#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009071/*[clinic input]
9072os.posix_fallocate
9073
9074 fd: int
9075 offset: Py_off_t
9076 length: Py_off_t
9077 /
9078
9079Ensure a file has allocated at least a particular number of bytes on disk.
9080
9081Ensure that the file specified by fd encompasses a range of bytes
9082starting at offset bytes from the beginning and continuing for length bytes.
9083[clinic start generated code]*/
9084
Larry Hastings2f936352014-08-05 14:04:04 +10009085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009086os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009087 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009088/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009089{
9090 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009091 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009092
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009093 do {
9094 Py_BEGIN_ALLOW_THREADS
9095 result = posix_fallocate(fd, offset, length);
9096 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009097 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9098
9099 if (result == 0)
9100 Py_RETURN_NONE;
9101
9102 if (async_err)
9103 return NULL;
9104
9105 errno = result;
9106 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009107}
Victor Stinnerec39e262014-09-30 12:35:58 +02009108#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009109
Ross Lagerwall7807c352011-03-17 20:20:30 +02009110
Victor Stinnerd6b17692014-09-30 12:20:05 +02009111#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009112/*[clinic input]
9113os.posix_fadvise
9114
9115 fd: int
9116 offset: Py_off_t
9117 length: Py_off_t
9118 advice: int
9119 /
9120
9121Announce an intention to access data in a specific pattern.
9122
9123Announce an intention to access data in a specific pattern, thus allowing
9124the kernel to make optimizations.
9125The advice applies to the region of the file specified by fd starting at
9126offset and continuing for length bytes.
9127advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9128POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9129POSIX_FADV_DONTNEED.
9130[clinic start generated code]*/
9131
Larry Hastings2f936352014-08-05 14:04:04 +10009132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009133os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009134 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009135/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009136{
9137 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009138 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009139
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009140 do {
9141 Py_BEGIN_ALLOW_THREADS
9142 result = posix_fadvise(fd, offset, length, advice);
9143 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009144 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9145
9146 if (result == 0)
9147 Py_RETURN_NONE;
9148
9149 if (async_err)
9150 return NULL;
9151
9152 errno = result;
9153 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009154}
Victor Stinnerec39e262014-09-30 12:35:58 +02009155#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009156
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009157#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009158
Fred Drake762e2061999-08-26 17:23:54 +00009159/* Save putenv() parameters as values here, so we can collect them when they
9160 * get re-set with another call for the same key. */
9161static PyObject *posix_putenv_garbage;
9162
Larry Hastings2f936352014-08-05 14:04:04 +10009163static void
9164posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009165{
Larry Hastings2f936352014-08-05 14:04:04 +10009166 /* Install the first arg and newstr in posix_putenv_garbage;
9167 * this will cause previous value to be collected. This has to
9168 * happen after the real putenv() call because the old value
9169 * was still accessible until then. */
9170 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9171 /* really not much we can do; just leak */
9172 PyErr_Clear();
9173 else
9174 Py_DECREF(value);
9175}
9176
9177
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009178#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009179/*[clinic input]
9180os.putenv
9181
9182 name: unicode
9183 value: unicode
9184 /
9185
9186Change or add an environment variable.
9187[clinic start generated code]*/
9188
Larry Hastings2f936352014-08-05 14:04:04 +10009189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009190os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9191/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009192{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009193 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009194 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009195
Serhiy Storchaka77703942017-06-25 07:33:01 +03009196 /* Search from index 1 because on Windows starting '=' is allowed for
9197 defining hidden environment variables. */
9198 if (PyUnicode_GET_LENGTH(name) == 0 ||
9199 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9200 {
9201 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9202 return NULL;
9203 }
Larry Hastings2f936352014-08-05 14:04:04 +10009204 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9205 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009206 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009207 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009208
9209 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9210 if (env == NULL)
9211 goto error;
9212 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009213 PyErr_Format(PyExc_ValueError,
9214 "the environment variable is longer than %u characters",
9215 _MAX_ENV);
9216 goto error;
9217 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009218 if (wcslen(env) != (size_t)size) {
9219 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009220 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009221 }
9222
Larry Hastings2f936352014-08-05 14:04:04 +10009223 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009225 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009227
Larry Hastings2f936352014-08-05 14:04:04 +10009228 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009229 Py_RETURN_NONE;
9230
9231error:
Larry Hastings2f936352014-08-05 14:04:04 +10009232 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009233 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009234}
Larry Hastings2f936352014-08-05 14:04:04 +10009235#else /* MS_WINDOWS */
9236/*[clinic input]
9237os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009238
Larry Hastings2f936352014-08-05 14:04:04 +10009239 name: FSConverter
9240 value: FSConverter
9241 /
9242
9243Change or add an environment variable.
9244[clinic start generated code]*/
9245
Larry Hastings2f936352014-08-05 14:04:04 +10009246static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009247os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9248/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009249{
9250 PyObject *bytes = NULL;
9251 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009252 const char *name_string = PyBytes_AS_STRING(name);
9253 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009254
Serhiy Storchaka77703942017-06-25 07:33:01 +03009255 if (strchr(name_string, '=') != NULL) {
9256 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9257 return NULL;
9258 }
Larry Hastings2f936352014-08-05 14:04:04 +10009259 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9260 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009261 return NULL;
9262 }
9263
9264 env = PyBytes_AS_STRING(bytes);
9265 if (putenv(env)) {
9266 Py_DECREF(bytes);
9267 return posix_error();
9268 }
9269
9270 posix_putenv_garbage_setitem(name, bytes);
9271 Py_RETURN_NONE;
9272}
9273#endif /* MS_WINDOWS */
9274#endif /* HAVE_PUTENV */
9275
9276
9277#ifdef HAVE_UNSETENV
9278/*[clinic input]
9279os.unsetenv
9280 name: FSConverter
9281 /
9282
9283Delete an environment variable.
9284[clinic start generated code]*/
9285
Larry Hastings2f936352014-08-05 14:04:04 +10009286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009287os_unsetenv_impl(PyObject *module, PyObject *name)
9288/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009289{
Victor Stinner984890f2011-11-24 13:53:38 +01009290#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009291 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009292#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009293
Victor Stinner984890f2011-11-24 13:53:38 +01009294#ifdef HAVE_BROKEN_UNSETENV
9295 unsetenv(PyBytes_AS_STRING(name));
9296#else
Victor Stinner65170952011-11-22 22:16:17 +01009297 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009298 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009299 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009300#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009301
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 /* Remove the key from posix_putenv_garbage;
9303 * this will cause it to be collected. This has to
9304 * happen after the real unsetenv() call because the
9305 * old value was still accessible until then.
9306 */
Victor Stinner65170952011-11-22 22:16:17 +01009307 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 /* really not much we can do; just leak */
9309 PyErr_Clear();
9310 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009311 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009312}
Larry Hastings2f936352014-08-05 14:04:04 +10009313#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009314
Larry Hastings2f936352014-08-05 14:04:04 +10009315
9316/*[clinic input]
9317os.strerror
9318
9319 code: int
9320 /
9321
9322Translate an error code to a message string.
9323[clinic start generated code]*/
9324
Larry Hastings2f936352014-08-05 14:04:04 +10009325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009326os_strerror_impl(PyObject *module, int code)
9327/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009328{
9329 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 if (message == NULL) {
9331 PyErr_SetString(PyExc_ValueError,
9332 "strerror() argument out of range");
9333 return NULL;
9334 }
Victor Stinner1b579672011-12-17 05:47:23 +01009335 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009336}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009337
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009338
Guido van Rossumc9641791998-08-04 15:26:23 +00009339#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009340#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009341/*[clinic input]
9342os.WCOREDUMP -> bool
9343
9344 status: int
9345 /
9346
9347Return True if the process returning status was dumped to a core file.
9348[clinic start generated code]*/
9349
Larry Hastings2f936352014-08-05 14:04:04 +10009350static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009351os_WCOREDUMP_impl(PyObject *module, int status)
9352/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009353{
9354 WAIT_TYPE wait_status;
9355 WAIT_STATUS_INT(wait_status) = status;
9356 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009357}
9358#endif /* WCOREDUMP */
9359
Larry Hastings2f936352014-08-05 14:04:04 +10009360
Fred Drake106c1a02002-04-23 15:58:02 +00009361#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009362/*[clinic input]
9363os.WIFCONTINUED -> bool
9364
9365 status: int
9366
9367Return True if a particular process was continued from a job control stop.
9368
9369Return True if the process returning status was continued from a
9370job control stop.
9371[clinic start generated code]*/
9372
Larry Hastings2f936352014-08-05 14:04:04 +10009373static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009374os_WIFCONTINUED_impl(PyObject *module, int status)
9375/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009376{
9377 WAIT_TYPE wait_status;
9378 WAIT_STATUS_INT(wait_status) = status;
9379 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009380}
9381#endif /* WIFCONTINUED */
9382
Larry Hastings2f936352014-08-05 14:04:04 +10009383
Guido van Rossumc9641791998-08-04 15:26:23 +00009384#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009385/*[clinic input]
9386os.WIFSTOPPED -> bool
9387
9388 status: int
9389
9390Return True if the process returning status was stopped.
9391[clinic start generated code]*/
9392
Larry Hastings2f936352014-08-05 14:04:04 +10009393static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009394os_WIFSTOPPED_impl(PyObject *module, int status)
9395/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009396{
9397 WAIT_TYPE wait_status;
9398 WAIT_STATUS_INT(wait_status) = status;
9399 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009400}
9401#endif /* WIFSTOPPED */
9402
Larry Hastings2f936352014-08-05 14:04:04 +10009403
Guido van Rossumc9641791998-08-04 15:26:23 +00009404#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009405/*[clinic input]
9406os.WIFSIGNALED -> bool
9407
9408 status: int
9409
9410Return True if the process returning status was terminated by a signal.
9411[clinic start generated code]*/
9412
Larry Hastings2f936352014-08-05 14:04:04 +10009413static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009414os_WIFSIGNALED_impl(PyObject *module, int status)
9415/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009416{
9417 WAIT_TYPE wait_status;
9418 WAIT_STATUS_INT(wait_status) = status;
9419 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009420}
9421#endif /* WIFSIGNALED */
9422
Larry Hastings2f936352014-08-05 14:04:04 +10009423
Guido van Rossumc9641791998-08-04 15:26:23 +00009424#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009425/*[clinic input]
9426os.WIFEXITED -> bool
9427
9428 status: int
9429
9430Return True if the process returning status exited via the exit() system call.
9431[clinic start generated code]*/
9432
Larry Hastings2f936352014-08-05 14:04:04 +10009433static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009434os_WIFEXITED_impl(PyObject *module, int status)
9435/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009436{
9437 WAIT_TYPE wait_status;
9438 WAIT_STATUS_INT(wait_status) = status;
9439 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009440}
9441#endif /* WIFEXITED */
9442
Larry Hastings2f936352014-08-05 14:04:04 +10009443
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009444#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009445/*[clinic input]
9446os.WEXITSTATUS -> int
9447
9448 status: int
9449
9450Return the process return code from status.
9451[clinic start generated code]*/
9452
Larry Hastings2f936352014-08-05 14:04:04 +10009453static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009454os_WEXITSTATUS_impl(PyObject *module, int status)
9455/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009456{
9457 WAIT_TYPE wait_status;
9458 WAIT_STATUS_INT(wait_status) = status;
9459 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009460}
9461#endif /* WEXITSTATUS */
9462
Larry Hastings2f936352014-08-05 14:04:04 +10009463
Guido van Rossumc9641791998-08-04 15:26:23 +00009464#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009465/*[clinic input]
9466os.WTERMSIG -> int
9467
9468 status: int
9469
9470Return the signal that terminated the process that provided the status value.
9471[clinic start generated code]*/
9472
Larry Hastings2f936352014-08-05 14:04:04 +10009473static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009474os_WTERMSIG_impl(PyObject *module, int status)
9475/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009476{
9477 WAIT_TYPE wait_status;
9478 WAIT_STATUS_INT(wait_status) = status;
9479 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009480}
9481#endif /* WTERMSIG */
9482
Larry Hastings2f936352014-08-05 14:04:04 +10009483
Guido van Rossumc9641791998-08-04 15:26:23 +00009484#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009485/*[clinic input]
9486os.WSTOPSIG -> int
9487
9488 status: int
9489
9490Return the signal that stopped the process that provided the status value.
9491[clinic start generated code]*/
9492
Larry Hastings2f936352014-08-05 14:04:04 +10009493static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009494os_WSTOPSIG_impl(PyObject *module, int status)
9495/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009496{
9497 WAIT_TYPE wait_status;
9498 WAIT_STATUS_INT(wait_status) = status;
9499 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009500}
9501#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009502#endif /* HAVE_SYS_WAIT_H */
9503
9504
Thomas Wouters477c8d52006-05-27 19:21:47 +00009505#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009506#ifdef _SCO_DS
9507/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9508 needed definitions in sys/statvfs.h */
9509#define _SVID3
9510#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009511#include <sys/statvfs.h>
9512
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009513static PyObject*
9514_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9516 if (v == NULL)
9517 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009518
9519#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9521 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9522 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9523 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9524 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9525 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9526 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9527 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9528 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9529 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009530#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9532 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9533 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009534 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009536 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009538 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009540 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009542 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009544 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9546 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009547#endif
Michael Felt502d5512018-01-05 13:01:58 +01009548/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9549 * (issue #32390). */
9550#if defined(_AIX) && defined(_ALL_SOURCE)
9551 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9552#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009553 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009554#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009555 if (PyErr_Occurred()) {
9556 Py_DECREF(v);
9557 return NULL;
9558 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009559
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009561}
9562
Larry Hastings2f936352014-08-05 14:04:04 +10009563
9564/*[clinic input]
9565os.fstatvfs
9566 fd: int
9567 /
9568
9569Perform an fstatvfs system call on the given fd.
9570
9571Equivalent to statvfs(fd).
9572[clinic start generated code]*/
9573
Larry Hastings2f936352014-08-05 14:04:04 +10009574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009575os_fstatvfs_impl(PyObject *module, int fd)
9576/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009577{
9578 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009579 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009581
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009582 do {
9583 Py_BEGIN_ALLOW_THREADS
9584 result = fstatvfs(fd, &st);
9585 Py_END_ALLOW_THREADS
9586 } while (result != 0 && errno == EINTR &&
9587 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009588 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009589 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009590
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009592}
Larry Hastings2f936352014-08-05 14:04:04 +10009593#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009594
9595
Thomas Wouters477c8d52006-05-27 19:21:47 +00009596#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009597#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009598/*[clinic input]
9599os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009600
Larry Hastings2f936352014-08-05 14:04:04 +10009601 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9602
9603Perform a statvfs system call on the given path.
9604
9605path may always be specified as a string.
9606On some platforms, path may also be specified as an open file descriptor.
9607 If this functionality is unavailable, using it raises an exception.
9608[clinic start generated code]*/
9609
Larry Hastings2f936352014-08-05 14:04:04 +10009610static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009611os_statvfs_impl(PyObject *module, path_t *path)
9612/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009613{
9614 int result;
9615 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009616
9617 Py_BEGIN_ALLOW_THREADS
9618#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009619 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009620#ifdef __APPLE__
9621 /* handle weak-linking on Mac OS X 10.3 */
9622 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009623 fd_specified("statvfs", path->fd);
9624 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009625 }
9626#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009627 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009628 }
9629 else
9630#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009631 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009632 Py_END_ALLOW_THREADS
9633
9634 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009635 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009636 }
9637
Larry Hastings2f936352014-08-05 14:04:04 +10009638 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009639}
Larry Hastings2f936352014-08-05 14:04:04 +10009640#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9641
Guido van Rossum94f6f721999-01-06 18:42:14 +00009642
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009643#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009644/*[clinic input]
9645os._getdiskusage
9646
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009647 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009648
9649Return disk usage statistics about the given path as a (total, free) tuple.
9650[clinic start generated code]*/
9651
Larry Hastings2f936352014-08-05 14:04:04 +10009652static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009653os__getdiskusage_impl(PyObject *module, path_t *path)
9654/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009655{
9656 BOOL retval;
9657 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009658
9659 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009660 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009661 Py_END_ALLOW_THREADS
9662 if (retval == 0)
9663 return PyErr_SetFromWindowsErr(0);
9664
9665 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9666}
Larry Hastings2f936352014-08-05 14:04:04 +10009667#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009668
9669
Fred Drakec9680921999-12-13 16:37:25 +00009670/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9671 * It maps strings representing configuration variable names to
9672 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009673 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009674 * rarely-used constants. There are three separate tables that use
9675 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009676 *
9677 * This code is always included, even if none of the interfaces that
9678 * need it are included. The #if hackery needed to avoid it would be
9679 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009680 */
9681struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009682 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009683 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009684};
9685
Fred Drake12c6e2d1999-12-14 21:25:03 +00009686static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009687conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009688 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009689{
Christian Heimes217cfd12007-12-02 14:31:20 +00009690 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009691 int value = _PyLong_AsInt(arg);
9692 if (value == -1 && PyErr_Occurred())
9693 return 0;
9694 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009695 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009696 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009697 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009698 /* look up the value in the table using a binary search */
9699 size_t lo = 0;
9700 size_t mid;
9701 size_t hi = tablesize;
9702 int cmp;
9703 const char *confname;
9704 if (!PyUnicode_Check(arg)) {
9705 PyErr_SetString(PyExc_TypeError,
9706 "configuration names must be strings or integers");
9707 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009709 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009710 if (confname == NULL)
9711 return 0;
9712 while (lo < hi) {
9713 mid = (lo + hi) / 2;
9714 cmp = strcmp(confname, table[mid].name);
9715 if (cmp < 0)
9716 hi = mid;
9717 else if (cmp > 0)
9718 lo = mid + 1;
9719 else {
9720 *valuep = table[mid].value;
9721 return 1;
9722 }
9723 }
9724 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9725 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009727}
9728
9729
9730#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9731static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009732#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009734#endif
9735#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009737#endif
Fred Drakec9680921999-12-13 16:37:25 +00009738#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009783#ifdef _PC_ACL_ENABLED
9784 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9785#endif
9786#ifdef _PC_MIN_HOLE_SIZE
9787 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9788#endif
9789#ifdef _PC_ALLOC_SIZE_MIN
9790 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9791#endif
9792#ifdef _PC_REC_INCR_XFER_SIZE
9793 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9794#endif
9795#ifdef _PC_REC_MAX_XFER_SIZE
9796 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9797#endif
9798#ifdef _PC_REC_MIN_XFER_SIZE
9799 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9800#endif
9801#ifdef _PC_REC_XFER_ALIGN
9802 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9803#endif
9804#ifdef _PC_SYMLINK_MAX
9805 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9806#endif
9807#ifdef _PC_XATTR_ENABLED
9808 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9809#endif
9810#ifdef _PC_XATTR_EXISTS
9811 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9812#endif
9813#ifdef _PC_TIMESTAMP_RESOLUTION
9814 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9815#endif
Fred Drakec9680921999-12-13 16:37:25 +00009816};
9817
Fred Drakec9680921999-12-13 16:37:25 +00009818static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009819conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009820{
9821 return conv_confname(arg, valuep, posix_constants_pathconf,
9822 sizeof(posix_constants_pathconf)
9823 / sizeof(struct constdef));
9824}
9825#endif
9826
Larry Hastings2f936352014-08-05 14:04:04 +10009827
Fred Drakec9680921999-12-13 16:37:25 +00009828#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009829/*[clinic input]
9830os.fpathconf -> long
9831
9832 fd: int
9833 name: path_confname
9834 /
9835
9836Return the configuration limit name for the file descriptor fd.
9837
9838If there is no limit, return -1.
9839[clinic start generated code]*/
9840
Larry Hastings2f936352014-08-05 14:04:04 +10009841static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009842os_fpathconf_impl(PyObject *module, int fd, int name)
9843/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009844{
9845 long limit;
9846
9847 errno = 0;
9848 limit = fpathconf(fd, name);
9849 if (limit == -1 && errno != 0)
9850 posix_error();
9851
9852 return limit;
9853}
9854#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009855
9856
9857#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009858/*[clinic input]
9859os.pathconf -> long
9860 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9861 name: path_confname
9862
9863Return the configuration limit name for the file or directory path.
9864
9865If there is no limit, return -1.
9866On some platforms, path may also be specified as an open file descriptor.
9867 If this functionality is unavailable, using it raises an exception.
9868[clinic start generated code]*/
9869
Larry Hastings2f936352014-08-05 14:04:04 +10009870static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009871os_pathconf_impl(PyObject *module, path_t *path, int name)
9872/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009873{
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009875
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009877#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009878 if (path->fd != -1)
9879 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009880 else
9881#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009882 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 if (limit == -1 && errno != 0) {
9884 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009885 /* could be a path or name problem */
9886 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009887 else
Larry Hastings2f936352014-08-05 14:04:04 +10009888 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 }
Larry Hastings2f936352014-08-05 14:04:04 +10009890
9891 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009892}
Larry Hastings2f936352014-08-05 14:04:04 +10009893#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009894
9895#ifdef HAVE_CONFSTR
9896static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009897#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009899#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009900#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009902#endif
9903#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009905#endif
Fred Draked86ed291999-12-15 15:34:33 +00009906#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009908#endif
9909#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009911#endif
9912#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009914#endif
9915#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009917#endif
Fred Drakec9680921999-12-13 16:37:25 +00009918#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
Fred Draked86ed291999-12-15 15:34:33 +00009942#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009944#endif
Fred Drakec9680921999-12-13 16:37:25 +00009945#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
Fred Draked86ed291999-12-15 15:34:33 +00009948#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009950#endif
9951#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009953#endif
9954#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009956#endif
9957#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009959#endif
Fred Drakec9680921999-12-13 16:37:25 +00009960#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
Fred Draked86ed291999-12-15 15:34:33 +000010008#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010010#endif
10011#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010013#endif
10014#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010016#endif
10017#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010019#endif
10020#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010022#endif
10023#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010025#endif
10026#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010028#endif
10029#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010031#endif
10032#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
10035#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010037#endif
10038#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010040#endif
10041#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010043#endif
10044#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010046#endif
Fred Drakec9680921999-12-13 16:37:25 +000010047};
10048
10049static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010050conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010051{
10052 return conv_confname(arg, valuep, posix_constants_confstr,
10053 sizeof(posix_constants_confstr)
10054 / sizeof(struct constdef));
10055}
10056
Larry Hastings2f936352014-08-05 14:04:04 +100010057
10058/*[clinic input]
10059os.confstr
10060
10061 name: confstr_confname
10062 /
10063
10064Return a string-valued system configuration variable.
10065[clinic start generated code]*/
10066
Larry Hastings2f936352014-08-05 14:04:04 +100010067static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010068os_confstr_impl(PyObject *module, int name)
10069/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010070{
10071 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010072 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010073 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010074
Victor Stinnercb043522010-09-10 23:49:04 +000010075 errno = 0;
10076 len = confstr(name, buffer, sizeof(buffer));
10077 if (len == 0) {
10078 if (errno) {
10079 posix_error();
10080 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010081 }
10082 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010083 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010084 }
10085 }
Victor Stinnercb043522010-09-10 23:49:04 +000010086
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010087 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010088 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010089 char *buf = PyMem_Malloc(len);
10090 if (buf == NULL)
10091 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010092 len2 = confstr(name, buf, len);
10093 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010094 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010095 PyMem_Free(buf);
10096 }
10097 else
10098 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010099 return result;
10100}
Larry Hastings2f936352014-08-05 14:04:04 +100010101#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010102
10103
10104#ifdef HAVE_SYSCONF
10105static struct constdef posix_constants_sysconf[] = {
10106#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
Fred Draked86ed291999-12-15 15:34:33 +000010136#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010138#endif
10139#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010141#endif
Fred Drakec9680921999-12-13 16:37:25 +000010142#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
Fred Drakec9680921999-12-13 16:37:25 +000010145#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
Fred Draked86ed291999-12-15 15:34:33 +000010160#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010162#endif
Fred Drakec9680921999-12-13 16:37:25 +000010163#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
Fred Draked86ed291999-12-15 15:34:33 +000010178#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010180#endif
Fred Drakec9680921999-12-13 16:37:25 +000010181#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
Fred Draked86ed291999-12-15 15:34:33 +000010250#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010252#endif
Fred Drakec9680921999-12-13 16:37:25 +000010253#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
Fred Draked86ed291999-12-15 15:34:33 +000010262#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010264#endif
Fred Drakec9680921999-12-13 16:37:25 +000010265#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
Fred Draked86ed291999-12-15 15:34:33 +000010268#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010270#endif
10271#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
Fred Drakec9680921999-12-13 16:37:25 +000010274#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
Fred Draked86ed291999-12-15 15:34:33 +000010286#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010288#endif
Fred Drakec9680921999-12-13 16:37:25 +000010289#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
Fred Draked86ed291999-12-15 15:34:33 +000010310#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010312#endif
Fred Drakec9680921999-12-13 16:37:25 +000010313#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
Fred Draked86ed291999-12-15 15:34:33 +000010319#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010321#endif
Fred Drakec9680921999-12-13 16:37:25 +000010322#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
Fred Draked86ed291999-12-15 15:34:33 +000010349#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010351#endif
10352#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010354#endif
Fred Drakec9680921999-12-13 16:37:25 +000010355#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
10430#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010432#endif
10433#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
10448#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010450#endif
10451#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010453#endif
10454#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010456#endif
10457#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010459#endif
Fred Draked86ed291999-12-15 15:34:33 +000010460#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010462#endif
Fred Drakec9680921999-12-13 16:37:25 +000010463#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010465#endif
10466#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010468#endif
10469#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010471#endif
10472#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010474#endif
10475#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010477#endif
10478#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010480#endif
10481#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010483#endif
10484#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
10511#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010513#endif
10514#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
10517#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010519#endif
10520#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010522#endif
10523#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010525#endif
10526#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010528#endif
10529#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010531#endif
10532#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010534#endif
10535#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010537#endif
10538#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010540#endif
10541#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010543#endif
10544#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010546#endif
10547#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
10577#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010579#endif
10580#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010582#endif
10583#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010585#endif
10586#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010588#endif
10589#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010591#endif
10592#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010594#endif
10595#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010597#endif
10598};
10599
10600static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010601conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010602{
10603 return conv_confname(arg, valuep, posix_constants_sysconf,
10604 sizeof(posix_constants_sysconf)
10605 / sizeof(struct constdef));
10606}
10607
Larry Hastings2f936352014-08-05 14:04:04 +100010608
10609/*[clinic input]
10610os.sysconf -> long
10611 name: sysconf_confname
10612 /
10613
10614Return an integer-valued system configuration variable.
10615[clinic start generated code]*/
10616
Larry Hastings2f936352014-08-05 14:04:04 +100010617static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010618os_sysconf_impl(PyObject *module, int name)
10619/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010620{
10621 long value;
10622
10623 errno = 0;
10624 value = sysconf(name);
10625 if (value == -1 && errno != 0)
10626 posix_error();
10627 return value;
10628}
10629#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010630
10631
Fred Drakebec628d1999-12-15 18:31:10 +000010632/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010633 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010634 * the exported dictionaries that are used to publish information about the
10635 * names available on the host platform.
10636 *
10637 * Sorting the table at runtime ensures that the table is properly ordered
10638 * when used, even for platforms we're not able to test on. It also makes
10639 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010640 */
Fred Drakebec628d1999-12-15 18:31:10 +000010641
10642static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010643cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010644{
10645 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010647 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010649
10650 return strcmp(c1->name, c2->name);
10651}
10652
10653static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010654setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010655 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010656{
Fred Drakebec628d1999-12-15 18:31:10 +000010657 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010658 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010659
10660 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10661 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010662 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010664
Barry Warsaw3155db32000-04-13 15:20:40 +000010665 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 PyObject *o = PyLong_FromLong(table[i].value);
10667 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10668 Py_XDECREF(o);
10669 Py_DECREF(d);
10670 return -1;
10671 }
10672 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010673 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010674 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010675}
10676
Fred Drakebec628d1999-12-15 18:31:10 +000010677/* Return -1 on failure, 0 on success. */
10678static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010679setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010680{
10681#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010682 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010683 sizeof(posix_constants_pathconf)
10684 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010685 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010686 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010687#endif
10688#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010689 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010690 sizeof(posix_constants_confstr)
10691 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010692 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010693 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010694#endif
10695#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010696 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010697 sizeof(posix_constants_sysconf)
10698 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010699 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010700 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010701#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010702 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010703}
Fred Draked86ed291999-12-15 15:34:33 +000010704
10705
Larry Hastings2f936352014-08-05 14:04:04 +100010706/*[clinic input]
10707os.abort
10708
10709Abort the interpreter immediately.
10710
10711This function 'dumps core' or otherwise fails in the hardest way possible
10712on the hosting operating system. This function never returns.
10713[clinic start generated code]*/
10714
Larry Hastings2f936352014-08-05 14:04:04 +100010715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010716os_abort_impl(PyObject *module)
10717/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010718{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010719 abort();
10720 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010721#ifndef __clang__
10722 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10723 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10724 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010725 Py_FatalError("abort() called from Python code didn't abort!");
10726 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010727#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010728}
Fred Drakebec628d1999-12-15 18:31:10 +000010729
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010730#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010731/* Grab ShellExecute dynamically from shell32 */
10732static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010733static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10734 LPCWSTR, INT);
10735static int
10736check_ShellExecute()
10737{
10738 HINSTANCE hShell32;
10739
10740 /* only recheck */
10741 if (-1 == has_ShellExecute) {
10742 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010743 /* Security note: this call is not vulnerable to "DLL hijacking".
10744 SHELL32 is part of "KnownDLLs" and so Windows always load
10745 the system SHELL32.DLL, even if there is another SHELL32.DLL
10746 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010747 hShell32 = LoadLibraryW(L"SHELL32");
10748 Py_END_ALLOW_THREADS
10749 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010750 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10751 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010752 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010753 } else {
10754 has_ShellExecute = 0;
10755 }
10756 }
10757 return has_ShellExecute;
10758}
10759
10760
Steve Dowercc16be82016-09-08 10:35:16 -070010761/*[clinic input]
10762os.startfile
10763 filepath: path_t
10764 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010765
Steve Dowercc16be82016-09-08 10:35:16 -070010766startfile(filepath [, operation])
10767
10768Start a file with its associated application.
10769
10770When "operation" is not specified or "open", this acts like
10771double-clicking the file in Explorer, or giving the file name as an
10772argument to the DOS "start" command: the file is opened with whatever
10773application (if any) its extension is associated.
10774When another "operation" is given, it specifies what should be done with
10775the file. A typical operation is "print".
10776
10777startfile returns as soon as the associated application is launched.
10778There is no option to wait for the application to close, and no way
10779to retrieve the application's exit status.
10780
10781The filepath is relative to the current directory. If you want to use
10782an absolute path, make sure the first character is not a slash ("/");
10783the underlying Win32 ShellExecute function doesn't work if it is.
10784[clinic start generated code]*/
10785
10786static PyObject *
10787os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10788/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10789{
10790 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010791
10792 if(!check_ShellExecute()) {
10793 /* If the OS doesn't have ShellExecute, return a
10794 NotImplementedError. */
10795 return PyErr_Format(PyExc_NotImplementedError,
10796 "startfile not available on this platform");
10797 }
10798
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010800 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010801 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 Py_END_ALLOW_THREADS
10803
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010805 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010806 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 }
Steve Dowercc16be82016-09-08 10:35:16 -070010808 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010809}
Larry Hastings2f936352014-08-05 14:04:04 +100010810#endif /* MS_WINDOWS */
10811
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010812
Martin v. Löwis438b5342002-12-27 10:16:42 +000010813#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010814/*[clinic input]
10815os.getloadavg
10816
10817Return average recent system load information.
10818
10819Return the number of processes in the system run queue averaged over
10820the last 1, 5, and 15 minutes as a tuple of three floats.
10821Raises OSError if the load average was unobtainable.
10822[clinic start generated code]*/
10823
Larry Hastings2f936352014-08-05 14:04:04 +100010824static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010825os_getloadavg_impl(PyObject *module)
10826/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010827{
10828 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010829 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010830 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10831 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010832 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010833 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010834}
Larry Hastings2f936352014-08-05 14:04:04 +100010835#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010836
Larry Hastings2f936352014-08-05 14:04:04 +100010837
10838/*[clinic input]
10839os.device_encoding
10840 fd: int
10841
10842Return a string describing the encoding of a terminal's file descriptor.
10843
10844The file descriptor must be attached to a terminal.
10845If the device is not a terminal, return None.
10846[clinic start generated code]*/
10847
Larry Hastings2f936352014-08-05 14:04:04 +100010848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010849os_device_encoding_impl(PyObject *module, int fd)
10850/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010851{
Brett Cannonefb00c02012-02-29 18:31:31 -050010852 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010853}
10854
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010855
Larry Hastings2f936352014-08-05 14:04:04 +100010856#ifdef HAVE_SETRESUID
10857/*[clinic input]
10858os.setresuid
10859
10860 ruid: uid_t
10861 euid: uid_t
10862 suid: uid_t
10863 /
10864
10865Set the current process's real, effective, and saved user ids.
10866[clinic start generated code]*/
10867
Larry Hastings2f936352014-08-05 14:04:04 +100010868static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010869os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10870/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010871{
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 if (setresuid(ruid, euid, suid) < 0)
10873 return posix_error();
10874 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010875}
Larry Hastings2f936352014-08-05 14:04:04 +100010876#endif /* HAVE_SETRESUID */
10877
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010878
10879#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010880/*[clinic input]
10881os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010882
Larry Hastings2f936352014-08-05 14:04:04 +100010883 rgid: gid_t
10884 egid: gid_t
10885 sgid: gid_t
10886 /
10887
10888Set the current process's real, effective, and saved group ids.
10889[clinic start generated code]*/
10890
Larry Hastings2f936352014-08-05 14:04:04 +100010891static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010892os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10893/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010894{
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 if (setresgid(rgid, egid, sgid) < 0)
10896 return posix_error();
10897 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010898}
Larry Hastings2f936352014-08-05 14:04:04 +100010899#endif /* HAVE_SETRESGID */
10900
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010901
10902#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010903/*[clinic input]
10904os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010905
Larry Hastings2f936352014-08-05 14:04:04 +100010906Return a tuple of the current process's real, effective, and saved user ids.
10907[clinic start generated code]*/
10908
Larry Hastings2f936352014-08-05 14:04:04 +100010909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010910os_getresuid_impl(PyObject *module)
10911/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010912{
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 if (getresuid(&ruid, &euid, &suid) < 0)
10915 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010916 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10917 _PyLong_FromUid(euid),
10918 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010919}
Larry Hastings2f936352014-08-05 14:04:04 +100010920#endif /* HAVE_GETRESUID */
10921
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010922
10923#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010924/*[clinic input]
10925os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010926
Larry Hastings2f936352014-08-05 14:04:04 +100010927Return a tuple of the current process's real, effective, and saved group ids.
10928[clinic start generated code]*/
10929
Larry Hastings2f936352014-08-05 14:04:04 +100010930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010931os_getresgid_impl(PyObject *module)
10932/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010933{
10934 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 if (getresgid(&rgid, &egid, &sgid) < 0)
10936 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010937 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10938 _PyLong_FromGid(egid),
10939 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010940}
Larry Hastings2f936352014-08-05 14:04:04 +100010941#endif /* HAVE_GETRESGID */
10942
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010943
Benjamin Peterson9428d532011-09-14 11:45:52 -040010944#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010945/*[clinic input]
10946os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010947
Larry Hastings2f936352014-08-05 14:04:04 +100010948 path: path_t(allow_fd=True)
10949 attribute: path_t
10950 *
10951 follow_symlinks: bool = True
10952
10953Return the value of extended attribute attribute on path.
10954
10955path may be either a string or an open file descriptor.
10956If follow_symlinks is False, and the last element of the path is a symbolic
10957 link, getxattr will examine the symbolic link itself instead of the file
10958 the link points to.
10959
10960[clinic start generated code]*/
10961
Larry Hastings2f936352014-08-05 14:04:04 +100010962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010963os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010964 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010965/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010966{
10967 Py_ssize_t i;
10968 PyObject *buffer = NULL;
10969
10970 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10971 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010972
Larry Hastings9cf065c2012-06-22 16:30:09 -070010973 for (i = 0; ; i++) {
10974 void *ptr;
10975 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010976 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010977 Py_ssize_t buffer_size = buffer_sizes[i];
10978 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010979 path_error(path);
10980 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010981 }
10982 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10983 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010984 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010985 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010986
Larry Hastings9cf065c2012-06-22 16:30:09 -070010987 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010988 if (path->fd >= 0)
10989 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010991 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010992 else
Larry Hastings2f936352014-08-05 14:04:04 +100010993 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010994 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010995
Larry Hastings9cf065c2012-06-22 16:30:09 -070010996 if (result < 0) {
10997 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010998 if (errno == ERANGE)
10999 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011000 path_error(path);
11001 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011002 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011003
Larry Hastings9cf065c2012-06-22 16:30:09 -070011004 if (result != buffer_size) {
11005 /* Can only shrink. */
11006 _PyBytes_Resize(&buffer, result);
11007 }
11008 break;
11009 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011010
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012}
11013
Larry Hastings2f936352014-08-05 14:04:04 +100011014
11015/*[clinic input]
11016os.setxattr
11017
11018 path: path_t(allow_fd=True)
11019 attribute: path_t
11020 value: Py_buffer
11021 flags: int = 0
11022 *
11023 follow_symlinks: bool = True
11024
11025Set extended attribute attribute on path to value.
11026
11027path may be either a string or an open file descriptor.
11028If follow_symlinks is False, and the last element of the path is a symbolic
11029 link, setxattr will modify the symbolic link itself instead of the file
11030 the link points to.
11031
11032[clinic start generated code]*/
11033
Benjamin Peterson799bd802011-08-31 22:15:17 -040011034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011035os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011036 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011037/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011038{
Larry Hastings2f936352014-08-05 14:04:04 +100011039 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011040
Larry Hastings2f936352014-08-05 14:04:04 +100011041 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011042 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011043
Benjamin Peterson799bd802011-08-31 22:15:17 -040011044 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011045 if (path->fd > -1)
11046 result = fsetxattr(path->fd, attribute->narrow,
11047 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011048 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011049 result = setxattr(path->narrow, attribute->narrow,
11050 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011051 else
Larry Hastings2f936352014-08-05 14:04:04 +100011052 result = lsetxattr(path->narrow, attribute->narrow,
11053 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011054 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011055
Larry Hastings9cf065c2012-06-22 16:30:09 -070011056 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011057 path_error(path);
11058 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011059 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011060
Larry Hastings2f936352014-08-05 14:04:04 +100011061 Py_RETURN_NONE;
11062}
11063
11064
11065/*[clinic input]
11066os.removexattr
11067
11068 path: path_t(allow_fd=True)
11069 attribute: path_t
11070 *
11071 follow_symlinks: bool = True
11072
11073Remove extended attribute attribute on path.
11074
11075path may be either a string or an open file descriptor.
11076If follow_symlinks is False, and the last element of the path is a symbolic
11077 link, removexattr will modify the symbolic link itself instead of the file
11078 the link points to.
11079
11080[clinic start generated code]*/
11081
Larry Hastings2f936352014-08-05 14:04:04 +100011082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011083os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011084 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011085/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011086{
11087 ssize_t result;
11088
11089 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11090 return NULL;
11091
11092 Py_BEGIN_ALLOW_THREADS;
11093 if (path->fd > -1)
11094 result = fremovexattr(path->fd, attribute->narrow);
11095 else if (follow_symlinks)
11096 result = removexattr(path->narrow, attribute->narrow);
11097 else
11098 result = lremovexattr(path->narrow, attribute->narrow);
11099 Py_END_ALLOW_THREADS;
11100
11101 if (result) {
11102 return path_error(path);
11103 }
11104
11105 Py_RETURN_NONE;
11106}
11107
11108
11109/*[clinic input]
11110os.listxattr
11111
11112 path: path_t(allow_fd=True, nullable=True) = None
11113 *
11114 follow_symlinks: bool = True
11115
11116Return a list of extended attributes on path.
11117
11118path may be either None, a string, or an open file descriptor.
11119if path is None, listxattr will examine the current directory.
11120If follow_symlinks is False, and the last element of the path is a symbolic
11121 link, listxattr will examine the symbolic link itself instead of the file
11122 the link points to.
11123[clinic start generated code]*/
11124
Larry Hastings2f936352014-08-05 14:04:04 +100011125static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011126os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11127/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011128{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011129 Py_ssize_t i;
11130 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011131 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011132 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011133
Larry Hastings2f936352014-08-05 14:04:04 +100011134 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011135 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011136
Larry Hastings2f936352014-08-05 14:04:04 +100011137 name = path->narrow ? path->narrow : ".";
11138
Larry Hastings9cf065c2012-06-22 16:30:09 -070011139 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011140 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011141 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011142 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011143 Py_ssize_t buffer_size = buffer_sizes[i];
11144 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011145 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011146 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011147 break;
11148 }
11149 buffer = PyMem_MALLOC(buffer_size);
11150 if (!buffer) {
11151 PyErr_NoMemory();
11152 break;
11153 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011154
Larry Hastings9cf065c2012-06-22 16:30:09 -070011155 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011156 if (path->fd > -1)
11157 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011158 else if (follow_symlinks)
11159 length = listxattr(name, buffer, buffer_size);
11160 else
11161 length = llistxattr(name, buffer, buffer_size);
11162 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011163
Larry Hastings9cf065c2012-06-22 16:30:09 -070011164 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011165 if (errno == ERANGE) {
11166 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011167 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011168 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011169 }
Larry Hastings2f936352014-08-05 14:04:04 +100011170 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011171 break;
11172 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011173
Larry Hastings9cf065c2012-06-22 16:30:09 -070011174 result = PyList_New(0);
11175 if (!result) {
11176 goto exit;
11177 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011178
Larry Hastings9cf065c2012-06-22 16:30:09 -070011179 end = buffer + length;
11180 for (trace = start = buffer; trace != end; trace++) {
11181 if (!*trace) {
11182 int error;
11183 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11184 trace - start);
11185 if (!attribute) {
11186 Py_DECREF(result);
11187 result = NULL;
11188 goto exit;
11189 }
11190 error = PyList_Append(result, attribute);
11191 Py_DECREF(attribute);
11192 if (error) {
11193 Py_DECREF(result);
11194 result = NULL;
11195 goto exit;
11196 }
11197 start = trace + 1;
11198 }
11199 }
11200 break;
11201 }
11202exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011203 if (buffer)
11204 PyMem_FREE(buffer);
11205 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011206}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011207#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011208
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011209
Larry Hastings2f936352014-08-05 14:04:04 +100011210/*[clinic input]
11211os.urandom
11212
11213 size: Py_ssize_t
11214 /
11215
11216Return a bytes object containing random bytes suitable for cryptographic use.
11217[clinic start generated code]*/
11218
Larry Hastings2f936352014-08-05 14:04:04 +100011219static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011220os_urandom_impl(PyObject *module, Py_ssize_t size)
11221/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011222{
11223 PyObject *bytes;
11224 int result;
11225
Georg Brandl2fb477c2012-02-21 00:33:36 +010011226 if (size < 0)
11227 return PyErr_Format(PyExc_ValueError,
11228 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011229 bytes = PyBytes_FromStringAndSize(NULL, size);
11230 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011231 return NULL;
11232
Victor Stinnere66987e2016-09-06 16:33:52 -070011233 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011234 if (result == -1) {
11235 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011236 return NULL;
11237 }
Larry Hastings2f936352014-08-05 14:04:04 +100011238 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011239}
11240
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011241/* Terminal size querying */
11242
11243static PyTypeObject TerminalSizeType;
11244
11245PyDoc_STRVAR(TerminalSize_docstring,
11246 "A tuple of (columns, lines) for holding terminal window size");
11247
11248static PyStructSequence_Field TerminalSize_fields[] = {
11249 {"columns", "width of the terminal window in characters"},
11250 {"lines", "height of the terminal window in characters"},
11251 {NULL, NULL}
11252};
11253
11254static PyStructSequence_Desc TerminalSize_desc = {
11255 "os.terminal_size",
11256 TerminalSize_docstring,
11257 TerminalSize_fields,
11258 2,
11259};
11260
11261#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011262/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011263PyDoc_STRVAR(termsize__doc__,
11264 "Return the size of the terminal window as (columns, lines).\n" \
11265 "\n" \
11266 "The optional argument fd (default standard output) specifies\n" \
11267 "which file descriptor should be queried.\n" \
11268 "\n" \
11269 "If the file descriptor is not connected to a terminal, an OSError\n" \
11270 "is thrown.\n" \
11271 "\n" \
11272 "This function will only be defined if an implementation is\n" \
11273 "available for this system.\n" \
11274 "\n" \
11275 "shutil.get_terminal_size is the high-level function which should \n" \
11276 "normally be used, os.get_terminal_size is the low-level implementation.");
11277
11278static PyObject*
11279get_terminal_size(PyObject *self, PyObject *args)
11280{
11281 int columns, lines;
11282 PyObject *termsize;
11283
11284 int fd = fileno(stdout);
11285 /* Under some conditions stdout may not be connected and
11286 * fileno(stdout) may point to an invalid file descriptor. For example
11287 * GUI apps don't have valid standard streams by default.
11288 *
11289 * If this happens, and the optional fd argument is not present,
11290 * the ioctl below will fail returning EBADF. This is what we want.
11291 */
11292
11293 if (!PyArg_ParseTuple(args, "|i", &fd))
11294 return NULL;
11295
11296#ifdef TERMSIZE_USE_IOCTL
11297 {
11298 struct winsize w;
11299 if (ioctl(fd, TIOCGWINSZ, &w))
11300 return PyErr_SetFromErrno(PyExc_OSError);
11301 columns = w.ws_col;
11302 lines = w.ws_row;
11303 }
11304#endif /* TERMSIZE_USE_IOCTL */
11305
11306#ifdef TERMSIZE_USE_CONIO
11307 {
11308 DWORD nhandle;
11309 HANDLE handle;
11310 CONSOLE_SCREEN_BUFFER_INFO csbi;
11311 switch (fd) {
11312 case 0: nhandle = STD_INPUT_HANDLE;
11313 break;
11314 case 1: nhandle = STD_OUTPUT_HANDLE;
11315 break;
11316 case 2: nhandle = STD_ERROR_HANDLE;
11317 break;
11318 default:
11319 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11320 }
11321 handle = GetStdHandle(nhandle);
11322 if (handle == NULL)
11323 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11324 if (handle == INVALID_HANDLE_VALUE)
11325 return PyErr_SetFromWindowsErr(0);
11326
11327 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11328 return PyErr_SetFromWindowsErr(0);
11329
11330 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11331 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11332 }
11333#endif /* TERMSIZE_USE_CONIO */
11334
11335 termsize = PyStructSequence_New(&TerminalSizeType);
11336 if (termsize == NULL)
11337 return NULL;
11338 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11339 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11340 if (PyErr_Occurred()) {
11341 Py_DECREF(termsize);
11342 return NULL;
11343 }
11344 return termsize;
11345}
11346#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11347
Larry Hastings2f936352014-08-05 14:04:04 +100011348
11349/*[clinic input]
11350os.cpu_count
11351
Charles-François Natali80d62e62015-08-13 20:37:08 +010011352Return the number of CPUs in the system; return None if indeterminable.
11353
11354This number is not equivalent to the number of CPUs the current process can
11355use. The number of usable CPUs can be obtained with
11356``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011357[clinic start generated code]*/
11358
Larry Hastings2f936352014-08-05 14:04:04 +100011359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011360os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011361/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011362{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011363 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011364#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011365 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11366 Need to fallback to Vista behavior if this call isn't present */
11367 HINSTANCE hKernel32;
11368 hKernel32 = GetModuleHandleW(L"KERNEL32");
11369
11370 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11371 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11372 "GetMaximumProcessorCount");
11373 if (_GetMaximumProcessorCount != NULL) {
11374 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11375 }
11376 else {
11377 SYSTEM_INFO sysinfo;
11378 GetSystemInfo(&sysinfo);
11379 ncpu = sysinfo.dwNumberOfProcessors;
11380 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011381#elif defined(__hpux)
11382 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11383#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11384 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011385#elif defined(__DragonFly__) || \
11386 defined(__OpenBSD__) || \
11387 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011388 defined(__NetBSD__) || \
11389 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011390 int mib[2];
11391 size_t len = sizeof(ncpu);
11392 mib[0] = CTL_HW;
11393 mib[1] = HW_NCPU;
11394 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11395 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011396#endif
11397 if (ncpu >= 1)
11398 return PyLong_FromLong(ncpu);
11399 else
11400 Py_RETURN_NONE;
11401}
11402
Victor Stinnerdaf45552013-08-28 00:53:59 +020011403
Larry Hastings2f936352014-08-05 14:04:04 +100011404/*[clinic input]
11405os.get_inheritable -> bool
11406
11407 fd: int
11408 /
11409
11410Get the close-on-exe flag of the specified file descriptor.
11411[clinic start generated code]*/
11412
Larry Hastings2f936352014-08-05 14:04:04 +100011413static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011414os_get_inheritable_impl(PyObject *module, int fd)
11415/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011416{
Steve Dower8fc89802015-04-12 00:26:27 -040011417 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011418 _Py_BEGIN_SUPPRESS_IPH
11419 return_value = _Py_get_inheritable(fd);
11420 _Py_END_SUPPRESS_IPH
11421 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011422}
11423
11424
11425/*[clinic input]
11426os.set_inheritable
11427 fd: int
11428 inheritable: int
11429 /
11430
11431Set the inheritable flag of the specified file descriptor.
11432[clinic start generated code]*/
11433
Larry Hastings2f936352014-08-05 14:04:04 +100011434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011435os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11436/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011437{
Steve Dower8fc89802015-04-12 00:26:27 -040011438 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011439
Steve Dower8fc89802015-04-12 00:26:27 -040011440 _Py_BEGIN_SUPPRESS_IPH
11441 result = _Py_set_inheritable(fd, inheritable, NULL);
11442 _Py_END_SUPPRESS_IPH
11443 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011444 return NULL;
11445 Py_RETURN_NONE;
11446}
11447
11448
11449#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011450/*[clinic input]
11451os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011452 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011453 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011454
Larry Hastings2f936352014-08-05 14:04:04 +100011455Get the close-on-exe flag of the specified file descriptor.
11456[clinic start generated code]*/
11457
Larry Hastings2f936352014-08-05 14:04:04 +100011458static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011459os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011460/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011461{
11462 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011463
11464 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11465 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011466 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011467 }
11468
Larry Hastings2f936352014-08-05 14:04:04 +100011469 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011470}
11471
Victor Stinnerdaf45552013-08-28 00:53:59 +020011472
Larry Hastings2f936352014-08-05 14:04:04 +100011473/*[clinic input]
11474os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011475 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011476 inheritable: bool
11477 /
11478
11479Set the inheritable flag of the specified handle.
11480[clinic start generated code]*/
11481
Larry Hastings2f936352014-08-05 14:04:04 +100011482static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011483os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011484 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011485/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011486{
11487 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011488 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11489 PyErr_SetFromWindowsErr(0);
11490 return NULL;
11491 }
11492 Py_RETURN_NONE;
11493}
Larry Hastings2f936352014-08-05 14:04:04 +100011494#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011495
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011496#ifndef MS_WINDOWS
11497PyDoc_STRVAR(get_blocking__doc__,
11498 "get_blocking(fd) -> bool\n" \
11499 "\n" \
11500 "Get the blocking mode of the file descriptor:\n" \
11501 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11502
11503static PyObject*
11504posix_get_blocking(PyObject *self, PyObject *args)
11505{
11506 int fd;
11507 int blocking;
11508
11509 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11510 return NULL;
11511
Steve Dower8fc89802015-04-12 00:26:27 -040011512 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011513 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011514 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011515 if (blocking < 0)
11516 return NULL;
11517 return PyBool_FromLong(blocking);
11518}
11519
11520PyDoc_STRVAR(set_blocking__doc__,
11521 "set_blocking(fd, blocking)\n" \
11522 "\n" \
11523 "Set the blocking mode of the specified file descriptor.\n" \
11524 "Set the O_NONBLOCK flag if blocking is False,\n" \
11525 "clear the O_NONBLOCK flag otherwise.");
11526
11527static PyObject*
11528posix_set_blocking(PyObject *self, PyObject *args)
11529{
Steve Dower8fc89802015-04-12 00:26:27 -040011530 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011531
11532 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11533 return NULL;
11534
Steve Dower8fc89802015-04-12 00:26:27 -040011535 _Py_BEGIN_SUPPRESS_IPH
11536 result = _Py_set_blocking(fd, blocking);
11537 _Py_END_SUPPRESS_IPH
11538 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011539 return NULL;
11540 Py_RETURN_NONE;
11541}
11542#endif /* !MS_WINDOWS */
11543
11544
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011545/*[clinic input]
11546class os.DirEntry "DirEntry *" "&DirEntryType"
11547[clinic start generated code]*/
11548/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011549
11550typedef struct {
11551 PyObject_HEAD
11552 PyObject *name;
11553 PyObject *path;
11554 PyObject *stat;
11555 PyObject *lstat;
11556#ifdef MS_WINDOWS
11557 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011558 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011559 int got_file_index;
11560#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011561#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011562 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011563#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011564 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011565 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011566#endif
11567} DirEntry;
11568
11569static void
11570DirEntry_dealloc(DirEntry *entry)
11571{
11572 Py_XDECREF(entry->name);
11573 Py_XDECREF(entry->path);
11574 Py_XDECREF(entry->stat);
11575 Py_XDECREF(entry->lstat);
11576 Py_TYPE(entry)->tp_free((PyObject *)entry);
11577}
11578
11579/* Forward reference */
11580static int
11581DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11582
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011583/*[clinic input]
11584os.DirEntry.is_symlink -> bool
11585
11586Return True if the entry is a symbolic link; cached per entry.
11587[clinic start generated code]*/
11588
Victor Stinner6036e442015-03-08 01:58:04 +010011589static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011590os_DirEntry_is_symlink_impl(DirEntry *self)
11591/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011592{
11593#ifdef MS_WINDOWS
11594 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011595#elif defined(HAVE_DIRENT_D_TYPE)
11596 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011597 if (self->d_type != DT_UNKNOWN)
11598 return self->d_type == DT_LNK;
11599 else
11600 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011601#else
11602 /* POSIX without d_type */
11603 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011604#endif
11605}
11606
11607static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011608DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11609{
11610 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011611 STRUCT_STAT st;
11612 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011613
11614#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011615 if (!PyUnicode_FSDecoder(self->path, &ub))
11616 return NULL;
11617 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011618#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011619 if (!PyUnicode_FSConverter(self->path, &ub))
11620 return NULL;
11621 const char *path = PyBytes_AS_STRING(ub);
11622 if (self->dir_fd != DEFAULT_DIR_FD) {
11623#ifdef HAVE_FSTATAT
11624 result = fstatat(self->dir_fd, path, &st,
11625 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11626#else
11627 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11628 return NULL;
11629#endif /* HAVE_FSTATAT */
11630 }
11631 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011632#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011633 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011634 if (follow_symlinks)
11635 result = STAT(path, &st);
11636 else
11637 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011638 }
11639 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011640
11641 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011642 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011643
11644 return _pystat_fromstructstat(&st);
11645}
11646
11647static PyObject *
11648DirEntry_get_lstat(DirEntry *self)
11649{
11650 if (!self->lstat) {
11651#ifdef MS_WINDOWS
11652 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11653#else /* POSIX */
11654 self->lstat = DirEntry_fetch_stat(self, 0);
11655#endif
11656 }
11657 Py_XINCREF(self->lstat);
11658 return self->lstat;
11659}
11660
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011661/*[clinic input]
11662os.DirEntry.stat
11663 *
11664 follow_symlinks: bool = True
11665
11666Return stat_result object for the entry; cached per entry.
11667[clinic start generated code]*/
11668
Victor Stinner6036e442015-03-08 01:58:04 +010011669static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011670os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11671/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011672{
11673 if (!follow_symlinks)
11674 return DirEntry_get_lstat(self);
11675
11676 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011677 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011678 if (result == -1)
11679 return NULL;
11680 else if (result)
11681 self->stat = DirEntry_fetch_stat(self, 1);
11682 else
11683 self->stat = DirEntry_get_lstat(self);
11684 }
11685
11686 Py_XINCREF(self->stat);
11687 return self->stat;
11688}
11689
Victor Stinner6036e442015-03-08 01:58:04 +010011690/* Set exception and return -1 on error, 0 for False, 1 for True */
11691static int
11692DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11693{
11694 PyObject *stat = NULL;
11695 PyObject *st_mode = NULL;
11696 long mode;
11697 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011698#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011699 int is_symlink;
11700 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011701#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011702#ifdef MS_WINDOWS
11703 unsigned long dir_bits;
11704#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011705 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011706
11707#ifdef MS_WINDOWS
11708 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11709 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011710#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011711 is_symlink = self->d_type == DT_LNK;
11712 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11713#endif
11714
Victor Stinner35a97c02015-03-08 02:59:09 +010011715#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011716 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011717#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011718 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011719 if (!stat) {
11720 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11721 /* If file doesn't exist (anymore), then return False
11722 (i.e., say it's not a file/directory) */
11723 PyErr_Clear();
11724 return 0;
11725 }
11726 goto error;
11727 }
11728 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11729 if (!st_mode)
11730 goto error;
11731
11732 mode = PyLong_AsLong(st_mode);
11733 if (mode == -1 && PyErr_Occurred())
11734 goto error;
11735 Py_CLEAR(st_mode);
11736 Py_CLEAR(stat);
11737 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011738#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011739 }
11740 else if (is_symlink) {
11741 assert(mode_bits != S_IFLNK);
11742 result = 0;
11743 }
11744 else {
11745 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11746#ifdef MS_WINDOWS
11747 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11748 if (mode_bits == S_IFDIR)
11749 result = dir_bits != 0;
11750 else
11751 result = dir_bits == 0;
11752#else /* POSIX */
11753 if (mode_bits == S_IFDIR)
11754 result = self->d_type == DT_DIR;
11755 else
11756 result = self->d_type == DT_REG;
11757#endif
11758 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011759#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011760
11761 return result;
11762
11763error:
11764 Py_XDECREF(st_mode);
11765 Py_XDECREF(stat);
11766 return -1;
11767}
11768
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011769/*[clinic input]
11770os.DirEntry.is_dir -> bool
11771 *
11772 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011773
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011774Return True if the entry is a directory; cached per entry.
11775[clinic start generated code]*/
11776
11777static int
11778os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11779/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11780{
11781 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011782}
11783
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011784/*[clinic input]
11785os.DirEntry.is_file -> bool
11786 *
11787 follow_symlinks: bool = True
11788
11789Return True if the entry is a file; cached per entry.
11790[clinic start generated code]*/
11791
11792static int
11793os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11794/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011795{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011796 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011797}
11798
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011799/*[clinic input]
11800os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011801
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011802Return inode of the entry; cached per entry.
11803[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011804
11805static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011806os_DirEntry_inode_impl(DirEntry *self)
11807/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011808{
11809#ifdef MS_WINDOWS
11810 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011811 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011812 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011813 STRUCT_STAT stat;
11814 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011815
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011816 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011817 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011818 path = PyUnicode_AsUnicode(unicode);
11819 result = LSTAT(path, &stat);
11820 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011821
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011822 if (result != 0)
11823 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011824
11825 self->win32_file_index = stat.st_ino;
11826 self->got_file_index = 1;
11827 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011828 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11829 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011830#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011831 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11832 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011833#endif
11834}
11835
11836static PyObject *
11837DirEntry_repr(DirEntry *self)
11838{
11839 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11840}
11841
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011842/*[clinic input]
11843os.DirEntry.__fspath__
11844
11845Returns the path for the entry.
11846[clinic start generated code]*/
11847
Brett Cannon96881cd2016-06-10 14:37:21 -070011848static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011849os_DirEntry___fspath___impl(DirEntry *self)
11850/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011851{
11852 Py_INCREF(self->path);
11853 return self->path;
11854}
11855
Victor Stinner6036e442015-03-08 01:58:04 +010011856static PyMemberDef DirEntry_members[] = {
11857 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11858 "the entry's base filename, relative to scandir() \"path\" argument"},
11859 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11860 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11861 {NULL}
11862};
11863
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011864#include "clinic/posixmodule.c.h"
11865
Victor Stinner6036e442015-03-08 01:58:04 +010011866static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011867 OS_DIRENTRY_IS_DIR_METHODDEF
11868 OS_DIRENTRY_IS_FILE_METHODDEF
11869 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11870 OS_DIRENTRY_STAT_METHODDEF
11871 OS_DIRENTRY_INODE_METHODDEF
11872 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011873 {NULL}
11874};
11875
Benjamin Peterson5646de42015-04-12 17:56:34 -040011876static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011877 PyVarObject_HEAD_INIT(NULL, 0)
11878 MODNAME ".DirEntry", /* tp_name */
11879 sizeof(DirEntry), /* tp_basicsize */
11880 0, /* tp_itemsize */
11881 /* methods */
11882 (destructor)DirEntry_dealloc, /* tp_dealloc */
11883 0, /* tp_print */
11884 0, /* tp_getattr */
11885 0, /* tp_setattr */
11886 0, /* tp_compare */
11887 (reprfunc)DirEntry_repr, /* tp_repr */
11888 0, /* tp_as_number */
11889 0, /* tp_as_sequence */
11890 0, /* tp_as_mapping */
11891 0, /* tp_hash */
11892 0, /* tp_call */
11893 0, /* tp_str */
11894 0, /* tp_getattro */
11895 0, /* tp_setattro */
11896 0, /* tp_as_buffer */
11897 Py_TPFLAGS_DEFAULT, /* tp_flags */
11898 0, /* tp_doc */
11899 0, /* tp_traverse */
11900 0, /* tp_clear */
11901 0, /* tp_richcompare */
11902 0, /* tp_weaklistoffset */
11903 0, /* tp_iter */
11904 0, /* tp_iternext */
11905 DirEntry_methods, /* tp_methods */
11906 DirEntry_members, /* tp_members */
11907};
11908
11909#ifdef MS_WINDOWS
11910
11911static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011912join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011913{
11914 Py_ssize_t path_len;
11915 Py_ssize_t size;
11916 wchar_t *result;
11917 wchar_t ch;
11918
11919 if (!path_wide) { /* Default arg: "." */
11920 path_wide = L".";
11921 path_len = 1;
11922 }
11923 else {
11924 path_len = wcslen(path_wide);
11925 }
11926
11927 /* The +1's are for the path separator and the NUL */
11928 size = path_len + 1 + wcslen(filename) + 1;
11929 result = PyMem_New(wchar_t, size);
11930 if (!result) {
11931 PyErr_NoMemory();
11932 return NULL;
11933 }
11934 wcscpy(result, path_wide);
11935 if (path_len > 0) {
11936 ch = result[path_len - 1];
11937 if (ch != SEP && ch != ALTSEP && ch != L':')
11938 result[path_len++] = SEP;
11939 wcscpy(result + path_len, filename);
11940 }
11941 return result;
11942}
11943
11944static PyObject *
11945DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11946{
11947 DirEntry *entry;
11948 BY_HANDLE_FILE_INFORMATION file_info;
11949 ULONG reparse_tag;
11950 wchar_t *joined_path;
11951
11952 entry = PyObject_New(DirEntry, &DirEntryType);
11953 if (!entry)
11954 return NULL;
11955 entry->name = NULL;
11956 entry->path = NULL;
11957 entry->stat = NULL;
11958 entry->lstat = NULL;
11959 entry->got_file_index = 0;
11960
11961 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11962 if (!entry->name)
11963 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011964 if (path->narrow) {
11965 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11966 if (!entry->name)
11967 goto error;
11968 }
Victor Stinner6036e442015-03-08 01:58:04 +010011969
11970 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11971 if (!joined_path)
11972 goto error;
11973
11974 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11975 PyMem_Free(joined_path);
11976 if (!entry->path)
11977 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011978 if (path->narrow) {
11979 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11980 if (!entry->path)
11981 goto error;
11982 }
Victor Stinner6036e442015-03-08 01:58:04 +010011983
Steve Dowercc16be82016-09-08 10:35:16 -070011984 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011985 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11986
11987 return (PyObject *)entry;
11988
11989error:
11990 Py_DECREF(entry);
11991 return NULL;
11992}
11993
11994#else /* POSIX */
11995
11996static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011997join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011998{
11999 Py_ssize_t path_len;
12000 Py_ssize_t size;
12001 char *result;
12002
12003 if (!path_narrow) { /* Default arg: "." */
12004 path_narrow = ".";
12005 path_len = 1;
12006 }
12007 else {
12008 path_len = strlen(path_narrow);
12009 }
12010
12011 if (filename_len == -1)
12012 filename_len = strlen(filename);
12013
12014 /* The +1's are for the path separator and the NUL */
12015 size = path_len + 1 + filename_len + 1;
12016 result = PyMem_New(char, size);
12017 if (!result) {
12018 PyErr_NoMemory();
12019 return NULL;
12020 }
12021 strcpy(result, path_narrow);
12022 if (path_len > 0 && result[path_len - 1] != '/')
12023 result[path_len++] = '/';
12024 strcpy(result + path_len, filename);
12025 return result;
12026}
12027
12028static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012029DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012030 ino_t d_ino
12031#ifdef HAVE_DIRENT_D_TYPE
12032 , unsigned char d_type
12033#endif
12034 )
Victor Stinner6036e442015-03-08 01:58:04 +010012035{
12036 DirEntry *entry;
12037 char *joined_path;
12038
12039 entry = PyObject_New(DirEntry, &DirEntryType);
12040 if (!entry)
12041 return NULL;
12042 entry->name = NULL;
12043 entry->path = NULL;
12044 entry->stat = NULL;
12045 entry->lstat = NULL;
12046
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012047 if (path->fd != -1) {
12048 entry->dir_fd = path->fd;
12049 joined_path = NULL;
12050 }
12051 else {
12052 entry->dir_fd = DEFAULT_DIR_FD;
12053 joined_path = join_path_filename(path->narrow, name, name_len);
12054 if (!joined_path)
12055 goto error;
12056 }
Victor Stinner6036e442015-03-08 01:58:04 +010012057
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012058 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012059 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012060 if (joined_path)
12061 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012062 }
12063 else {
12064 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012065 if (joined_path)
12066 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012067 }
12068 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012069 if (!entry->name)
12070 goto error;
12071
12072 if (path->fd != -1) {
12073 entry->path = entry->name;
12074 Py_INCREF(entry->path);
12075 }
12076 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012077 goto error;
12078
Victor Stinner35a97c02015-03-08 02:59:09 +010012079#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012080 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012081#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012082 entry->d_ino = d_ino;
12083
12084 return (PyObject *)entry;
12085
12086error:
12087 Py_XDECREF(entry);
12088 return NULL;
12089}
12090
12091#endif
12092
12093
12094typedef struct {
12095 PyObject_HEAD
12096 path_t path;
12097#ifdef MS_WINDOWS
12098 HANDLE handle;
12099 WIN32_FIND_DATAW file_data;
12100 int first_time;
12101#else /* POSIX */
12102 DIR *dirp;
12103#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012104#ifdef HAVE_FDOPENDIR
12105 int fd;
12106#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012107} ScandirIterator;
12108
12109#ifdef MS_WINDOWS
12110
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012111static int
12112ScandirIterator_is_closed(ScandirIterator *iterator)
12113{
12114 return iterator->handle == INVALID_HANDLE_VALUE;
12115}
12116
Victor Stinner6036e442015-03-08 01:58:04 +010012117static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012118ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012119{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012120 HANDLE handle = iterator->handle;
12121
12122 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012123 return;
12124
Victor Stinner6036e442015-03-08 01:58:04 +010012125 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012126 Py_BEGIN_ALLOW_THREADS
12127 FindClose(handle);
12128 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012129}
12130
12131static PyObject *
12132ScandirIterator_iternext(ScandirIterator *iterator)
12133{
12134 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12135 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012136 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012137
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012138 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012139 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012140 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012141
12142 while (1) {
12143 if (!iterator->first_time) {
12144 Py_BEGIN_ALLOW_THREADS
12145 success = FindNextFileW(iterator->handle, file_data);
12146 Py_END_ALLOW_THREADS
12147 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012148 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012149 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012150 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012151 break;
12152 }
12153 }
12154 iterator->first_time = 0;
12155
12156 /* Skip over . and .. */
12157 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012158 wcscmp(file_data->cFileName, L"..") != 0) {
12159 entry = DirEntry_from_find_data(&iterator->path, file_data);
12160 if (!entry)
12161 break;
12162 return entry;
12163 }
Victor Stinner6036e442015-03-08 01:58:04 +010012164
12165 /* Loop till we get a non-dot directory or finish iterating */
12166 }
12167
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012168 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012169 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012170 return NULL;
12171}
12172
12173#else /* POSIX */
12174
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012175static int
12176ScandirIterator_is_closed(ScandirIterator *iterator)
12177{
12178 return !iterator->dirp;
12179}
12180
Victor Stinner6036e442015-03-08 01:58:04 +010012181static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012182ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012183{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012184 DIR *dirp = iterator->dirp;
12185
12186 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012187 return;
12188
Victor Stinner6036e442015-03-08 01:58:04 +010012189 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012190 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012191#ifdef HAVE_FDOPENDIR
12192 if (iterator->path.fd != -1)
12193 rewinddir(dirp);
12194#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012195 closedir(dirp);
12196 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012197 return;
12198}
12199
12200static PyObject *
12201ScandirIterator_iternext(ScandirIterator *iterator)
12202{
12203 struct dirent *direntp;
12204 Py_ssize_t name_len;
12205 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012206 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012207
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012208 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012209 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012210 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012211
12212 while (1) {
12213 errno = 0;
12214 Py_BEGIN_ALLOW_THREADS
12215 direntp = readdir(iterator->dirp);
12216 Py_END_ALLOW_THREADS
12217
12218 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012219 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012220 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012221 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012222 break;
12223 }
12224
12225 /* Skip over . and .. */
12226 name_len = NAMLEN(direntp);
12227 is_dot = direntp->d_name[0] == '.' &&
12228 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12229 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012230 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012231 name_len, direntp->d_ino
12232#ifdef HAVE_DIRENT_D_TYPE
12233 , direntp->d_type
12234#endif
12235 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012236 if (!entry)
12237 break;
12238 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012239 }
12240
12241 /* Loop till we get a non-dot directory or finish iterating */
12242 }
12243
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012244 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012245 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012246 return NULL;
12247}
12248
12249#endif
12250
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012251static PyObject *
12252ScandirIterator_close(ScandirIterator *self, PyObject *args)
12253{
12254 ScandirIterator_closedir(self);
12255 Py_RETURN_NONE;
12256}
12257
12258static PyObject *
12259ScandirIterator_enter(PyObject *self, PyObject *args)
12260{
12261 Py_INCREF(self);
12262 return self;
12263}
12264
12265static PyObject *
12266ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12267{
12268 ScandirIterator_closedir(self);
12269 Py_RETURN_NONE;
12270}
12271
Victor Stinner6036e442015-03-08 01:58:04 +010012272static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012273ScandirIterator_finalize(ScandirIterator *iterator)
12274{
12275 PyObject *error_type, *error_value, *error_traceback;
12276
12277 /* Save the current exception, if any. */
12278 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12279
12280 if (!ScandirIterator_is_closed(iterator)) {
12281 ScandirIterator_closedir(iterator);
12282
12283 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12284 "unclosed scandir iterator %R", iterator)) {
12285 /* Spurious errors can appear at shutdown */
12286 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12287 PyErr_WriteUnraisable((PyObject *) iterator);
12288 }
12289 }
12290 }
12291
Victor Stinner7bfa4092016-03-23 00:43:54 +010012292 path_cleanup(&iterator->path);
12293
12294 /* Restore the saved exception. */
12295 PyErr_Restore(error_type, error_value, error_traceback);
12296}
12297
12298static void
Victor Stinner6036e442015-03-08 01:58:04 +010012299ScandirIterator_dealloc(ScandirIterator *iterator)
12300{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012301 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12302 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012303
Victor Stinner6036e442015-03-08 01:58:04 +010012304 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12305}
12306
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012307static PyMethodDef ScandirIterator_methods[] = {
12308 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12309 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12310 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12311 {NULL}
12312};
12313
Benjamin Peterson5646de42015-04-12 17:56:34 -040012314static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012315 PyVarObject_HEAD_INIT(NULL, 0)
12316 MODNAME ".ScandirIterator", /* tp_name */
12317 sizeof(ScandirIterator), /* tp_basicsize */
12318 0, /* tp_itemsize */
12319 /* methods */
12320 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12321 0, /* tp_print */
12322 0, /* tp_getattr */
12323 0, /* tp_setattr */
12324 0, /* tp_compare */
12325 0, /* tp_repr */
12326 0, /* tp_as_number */
12327 0, /* tp_as_sequence */
12328 0, /* tp_as_mapping */
12329 0, /* tp_hash */
12330 0, /* tp_call */
12331 0, /* tp_str */
12332 0, /* tp_getattro */
12333 0, /* tp_setattro */
12334 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012335 Py_TPFLAGS_DEFAULT
12336 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012337 0, /* tp_doc */
12338 0, /* tp_traverse */
12339 0, /* tp_clear */
12340 0, /* tp_richcompare */
12341 0, /* tp_weaklistoffset */
12342 PyObject_SelfIter, /* tp_iter */
12343 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012344 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012345 0, /* tp_members */
12346 0, /* tp_getset */
12347 0, /* tp_base */
12348 0, /* tp_dict */
12349 0, /* tp_descr_get */
12350 0, /* tp_descr_set */
12351 0, /* tp_dictoffset */
12352 0, /* tp_init */
12353 0, /* tp_alloc */
12354 0, /* tp_new */
12355 0, /* tp_free */
12356 0, /* tp_is_gc */
12357 0, /* tp_bases */
12358 0, /* tp_mro */
12359 0, /* tp_cache */
12360 0, /* tp_subclasses */
12361 0, /* tp_weaklist */
12362 0, /* tp_del */
12363 0, /* tp_version_tag */
12364 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012365};
12366
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012367/*[clinic input]
12368os.scandir
12369
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012370 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012371
12372Return an iterator of DirEntry objects for given path.
12373
12374path can be specified as either str, bytes or path-like object. If path
12375is bytes, the names of yielded DirEntry objects will also be bytes; in
12376all other circumstances they will be str.
12377
12378If path is None, uses the path='.'.
12379[clinic start generated code]*/
12380
Victor Stinner6036e442015-03-08 01:58:04 +010012381static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012382os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012383/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012384{
12385 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012386#ifdef MS_WINDOWS
12387 wchar_t *path_strW;
12388#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012389 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012390#ifdef HAVE_FDOPENDIR
12391 int fd = -1;
12392#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012393#endif
12394
12395 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12396 if (!iterator)
12397 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012398
12399#ifdef MS_WINDOWS
12400 iterator->handle = INVALID_HANDLE_VALUE;
12401#else
12402 iterator->dirp = NULL;
12403#endif
12404
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012405 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012406 /* Move the ownership to iterator->path */
12407 path->object = NULL;
12408 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012409
12410#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012411 iterator->first_time = 1;
12412
12413 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12414 if (!path_strW)
12415 goto error;
12416
12417 Py_BEGIN_ALLOW_THREADS
12418 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12419 Py_END_ALLOW_THREADS
12420
12421 PyMem_Free(path_strW);
12422
12423 if (iterator->handle == INVALID_HANDLE_VALUE) {
12424 path_error(&iterator->path);
12425 goto error;
12426 }
12427#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012428 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012429#ifdef HAVE_FDOPENDIR
12430 if (path->fd != -1) {
12431 /* closedir() closes the FD, so we duplicate it */
12432 fd = _Py_dup(path->fd);
12433 if (fd == -1)
12434 goto error;
12435
12436 Py_BEGIN_ALLOW_THREADS
12437 iterator->dirp = fdopendir(fd);
12438 Py_END_ALLOW_THREADS
12439 }
12440 else
12441#endif
12442 {
12443 if (iterator->path.narrow)
12444 path_str = iterator->path.narrow;
12445 else
12446 path_str = ".";
12447
12448 Py_BEGIN_ALLOW_THREADS
12449 iterator->dirp = opendir(path_str);
12450 Py_END_ALLOW_THREADS
12451 }
Victor Stinner6036e442015-03-08 01:58:04 +010012452
12453 if (!iterator->dirp) {
12454 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012455#ifdef HAVE_FDOPENDIR
12456 if (fd != -1) {
12457 Py_BEGIN_ALLOW_THREADS
12458 close(fd);
12459 Py_END_ALLOW_THREADS
12460 }
12461#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012462 goto error;
12463 }
12464#endif
12465
12466 return (PyObject *)iterator;
12467
12468error:
12469 Py_DECREF(iterator);
12470 return NULL;
12471}
12472
Ethan Furman410ef8e2016-06-04 12:06:26 -070012473/*
12474 Return the file system path representation of the object.
12475
12476 If the object is str or bytes, then allow it to pass through with
12477 an incremented refcount. If the object defines __fspath__(), then
12478 return the result of that method. All other types raise a TypeError.
12479*/
12480PyObject *
12481PyOS_FSPath(PyObject *path)
12482{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012483 /* For error message reasons, this function is manually inlined in
12484 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012485 _Py_IDENTIFIER(__fspath__);
12486 PyObject *func = NULL;
12487 PyObject *path_repr = NULL;
12488
12489 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12490 Py_INCREF(path);
12491 return path;
12492 }
12493
12494 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12495 if (NULL == func) {
12496 return PyErr_Format(PyExc_TypeError,
12497 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012498 "not %.200s",
12499 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012500 }
12501
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012502 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012503 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012504 if (NULL == path_repr) {
12505 return NULL;
12506 }
12507
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012508 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12509 PyErr_Format(PyExc_TypeError,
12510 "expected %.200s.__fspath__() to return str or bytes, "
12511 "not %.200s", Py_TYPE(path)->tp_name,
12512 Py_TYPE(path_repr)->tp_name);
12513 Py_DECREF(path_repr);
12514 return NULL;
12515 }
12516
Ethan Furman410ef8e2016-06-04 12:06:26 -070012517 return path_repr;
12518}
12519
12520/*[clinic input]
12521os.fspath
12522
12523 path: object
12524
12525Return the file system path representation of the object.
12526
Brett Cannonb4f43e92016-06-09 14:32:08 -070012527If the object is str or bytes, then allow it to pass through as-is. If the
12528object defines __fspath__(), then return the result of that method. All other
12529types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012530[clinic start generated code]*/
12531
12532static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012533os_fspath_impl(PyObject *module, PyObject *path)
12534/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012535{
12536 return PyOS_FSPath(path);
12537}
Victor Stinner6036e442015-03-08 01:58:04 +010012538
Victor Stinner9b1f4742016-09-06 16:18:52 -070012539#ifdef HAVE_GETRANDOM_SYSCALL
12540/*[clinic input]
12541os.getrandom
12542
12543 size: Py_ssize_t
12544 flags: int=0
12545
12546Obtain a series of random bytes.
12547[clinic start generated code]*/
12548
12549static PyObject *
12550os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12551/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12552{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012553 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012554 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012555
12556 if (size < 0) {
12557 errno = EINVAL;
12558 return posix_error();
12559 }
12560
Victor Stinnerec2319c2016-09-20 23:00:59 +020012561 bytes = PyBytes_FromStringAndSize(NULL, size);
12562 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012563 PyErr_NoMemory();
12564 return NULL;
12565 }
12566
12567 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012568 n = syscall(SYS_getrandom,
12569 PyBytes_AS_STRING(bytes),
12570 PyBytes_GET_SIZE(bytes),
12571 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012572 if (n < 0 && errno == EINTR) {
12573 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012574 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012575 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012576
12577 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012578 continue;
12579 }
12580 break;
12581 }
12582
12583 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012584 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012585 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012586 }
12587
Victor Stinnerec2319c2016-09-20 23:00:59 +020012588 if (n != size) {
12589 _PyBytes_Resize(&bytes, n);
12590 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012591
12592 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012593
12594error:
12595 Py_DECREF(bytes);
12596 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012597}
12598#endif /* HAVE_GETRANDOM_SYSCALL */
12599
Larry Hastings31826802013-10-19 00:09:25 -070012600
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012601static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012602
12603 OS_STAT_METHODDEF
12604 OS_ACCESS_METHODDEF
12605 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012606 OS_CHDIR_METHODDEF
12607 OS_CHFLAGS_METHODDEF
12608 OS_CHMOD_METHODDEF
12609 OS_FCHMOD_METHODDEF
12610 OS_LCHMOD_METHODDEF
12611 OS_CHOWN_METHODDEF
12612 OS_FCHOWN_METHODDEF
12613 OS_LCHOWN_METHODDEF
12614 OS_LCHFLAGS_METHODDEF
12615 OS_CHROOT_METHODDEF
12616 OS_CTERMID_METHODDEF
12617 OS_GETCWD_METHODDEF
12618 OS_GETCWDB_METHODDEF
12619 OS_LINK_METHODDEF
12620 OS_LISTDIR_METHODDEF
12621 OS_LSTAT_METHODDEF
12622 OS_MKDIR_METHODDEF
12623 OS_NICE_METHODDEF
12624 OS_GETPRIORITY_METHODDEF
12625 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012626#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012627 {"readlink", (PyCFunction)posix_readlink,
12628 METH_VARARGS | METH_KEYWORDS,
12629 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012630#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012631#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012632 {"readlink", (PyCFunction)win_readlink,
12633 METH_VARARGS | METH_KEYWORDS,
12634 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012635#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012636 OS_RENAME_METHODDEF
12637 OS_REPLACE_METHODDEF
12638 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012639 OS_SYMLINK_METHODDEF
12640 OS_SYSTEM_METHODDEF
12641 OS_UMASK_METHODDEF
12642 OS_UNAME_METHODDEF
12643 OS_UNLINK_METHODDEF
12644 OS_REMOVE_METHODDEF
12645 OS_UTIME_METHODDEF
12646 OS_TIMES_METHODDEF
12647 OS__EXIT_METHODDEF
12648 OS_EXECV_METHODDEF
12649 OS_EXECVE_METHODDEF
12650 OS_SPAWNV_METHODDEF
12651 OS_SPAWNVE_METHODDEF
12652 OS_FORK1_METHODDEF
12653 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012654 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012655 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12656 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12657 OS_SCHED_GETPARAM_METHODDEF
12658 OS_SCHED_GETSCHEDULER_METHODDEF
12659 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12660 OS_SCHED_SETPARAM_METHODDEF
12661 OS_SCHED_SETSCHEDULER_METHODDEF
12662 OS_SCHED_YIELD_METHODDEF
12663 OS_SCHED_SETAFFINITY_METHODDEF
12664 OS_SCHED_GETAFFINITY_METHODDEF
12665 OS_OPENPTY_METHODDEF
12666 OS_FORKPTY_METHODDEF
12667 OS_GETEGID_METHODDEF
12668 OS_GETEUID_METHODDEF
12669 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012670#ifdef HAVE_GETGROUPLIST
12671 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12672#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012673 OS_GETGROUPS_METHODDEF
12674 OS_GETPID_METHODDEF
12675 OS_GETPGRP_METHODDEF
12676 OS_GETPPID_METHODDEF
12677 OS_GETUID_METHODDEF
12678 OS_GETLOGIN_METHODDEF
12679 OS_KILL_METHODDEF
12680 OS_KILLPG_METHODDEF
12681 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012682#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012683 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012684#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012685 OS_SETUID_METHODDEF
12686 OS_SETEUID_METHODDEF
12687 OS_SETREUID_METHODDEF
12688 OS_SETGID_METHODDEF
12689 OS_SETEGID_METHODDEF
12690 OS_SETREGID_METHODDEF
12691 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012692#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012693 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012694#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012695 OS_GETPGID_METHODDEF
12696 OS_SETPGRP_METHODDEF
12697 OS_WAIT_METHODDEF
12698 OS_WAIT3_METHODDEF
12699 OS_WAIT4_METHODDEF
12700 OS_WAITID_METHODDEF
12701 OS_WAITPID_METHODDEF
12702 OS_GETSID_METHODDEF
12703 OS_SETSID_METHODDEF
12704 OS_SETPGID_METHODDEF
12705 OS_TCGETPGRP_METHODDEF
12706 OS_TCSETPGRP_METHODDEF
12707 OS_OPEN_METHODDEF
12708 OS_CLOSE_METHODDEF
12709 OS_CLOSERANGE_METHODDEF
12710 OS_DEVICE_ENCODING_METHODDEF
12711 OS_DUP_METHODDEF
12712 OS_DUP2_METHODDEF
12713 OS_LOCKF_METHODDEF
12714 OS_LSEEK_METHODDEF
12715 OS_READ_METHODDEF
12716 OS_READV_METHODDEF
12717 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012718 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012719 OS_WRITE_METHODDEF
12720 OS_WRITEV_METHODDEF
12721 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012722 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012723#ifdef HAVE_SENDFILE
12724 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12725 posix_sendfile__doc__},
12726#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012727 OS_FSTAT_METHODDEF
12728 OS_ISATTY_METHODDEF
12729 OS_PIPE_METHODDEF
12730 OS_PIPE2_METHODDEF
12731 OS_MKFIFO_METHODDEF
12732 OS_MKNOD_METHODDEF
12733 OS_MAJOR_METHODDEF
12734 OS_MINOR_METHODDEF
12735 OS_MAKEDEV_METHODDEF
12736 OS_FTRUNCATE_METHODDEF
12737 OS_TRUNCATE_METHODDEF
12738 OS_POSIX_FALLOCATE_METHODDEF
12739 OS_POSIX_FADVISE_METHODDEF
12740 OS_PUTENV_METHODDEF
12741 OS_UNSETENV_METHODDEF
12742 OS_STRERROR_METHODDEF
12743 OS_FCHDIR_METHODDEF
12744 OS_FSYNC_METHODDEF
12745 OS_SYNC_METHODDEF
12746 OS_FDATASYNC_METHODDEF
12747 OS_WCOREDUMP_METHODDEF
12748 OS_WIFCONTINUED_METHODDEF
12749 OS_WIFSTOPPED_METHODDEF
12750 OS_WIFSIGNALED_METHODDEF
12751 OS_WIFEXITED_METHODDEF
12752 OS_WEXITSTATUS_METHODDEF
12753 OS_WTERMSIG_METHODDEF
12754 OS_WSTOPSIG_METHODDEF
12755 OS_FSTATVFS_METHODDEF
12756 OS_STATVFS_METHODDEF
12757 OS_CONFSTR_METHODDEF
12758 OS_SYSCONF_METHODDEF
12759 OS_FPATHCONF_METHODDEF
12760 OS_PATHCONF_METHODDEF
12761 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012762 OS__GETFULLPATHNAME_METHODDEF
12763 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012764 OS__GETDISKUSAGE_METHODDEF
12765 OS__GETFINALPATHNAME_METHODDEF
12766 OS__GETVOLUMEPATHNAME_METHODDEF
12767 OS_GETLOADAVG_METHODDEF
12768 OS_URANDOM_METHODDEF
12769 OS_SETRESUID_METHODDEF
12770 OS_SETRESGID_METHODDEF
12771 OS_GETRESUID_METHODDEF
12772 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012773
Larry Hastings2f936352014-08-05 14:04:04 +100012774 OS_GETXATTR_METHODDEF
12775 OS_SETXATTR_METHODDEF
12776 OS_REMOVEXATTR_METHODDEF
12777 OS_LISTXATTR_METHODDEF
12778
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012779#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12780 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12781#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012782 OS_CPU_COUNT_METHODDEF
12783 OS_GET_INHERITABLE_METHODDEF
12784 OS_SET_INHERITABLE_METHODDEF
12785 OS_GET_HANDLE_INHERITABLE_METHODDEF
12786 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012787#ifndef MS_WINDOWS
12788 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12789 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12790#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012791 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012792 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012793 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012794 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012795};
12796
12797
Brian Curtin52173d42010-12-02 18:29:18 +000012798#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012799static int
Brian Curtin52173d42010-12-02 18:29:18 +000012800enable_symlink()
12801{
12802 HANDLE tok;
12803 TOKEN_PRIVILEGES tok_priv;
12804 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012805
12806 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012807 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012808
12809 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012810 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012811
12812 tok_priv.PrivilegeCount = 1;
12813 tok_priv.Privileges[0].Luid = luid;
12814 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12815
12816 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12817 sizeof(TOKEN_PRIVILEGES),
12818 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012819 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012820
Brian Curtin3b4499c2010-12-28 14:31:47 +000012821 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12822 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012823}
12824#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12825
Barry Warsaw4a342091996-12-19 23:50:02 +000012826static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012827all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012828{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012829#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012830 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012831#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012832#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012833 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012834#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012835#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012836 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012837#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012838#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012839 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012840#endif
Fred Drakec9680921999-12-13 16:37:25 +000012841#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012843#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012844#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012846#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012847#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012849#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012850#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012852#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012853#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012855#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012856#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012858#endif
12859#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012861#endif
12862#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012863 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012864#endif
12865#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012867#endif
12868#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012870#endif
12871#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012873#endif
12874#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012876#endif
12877#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012879#endif
12880#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012882#endif
12883#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012885#endif
12886#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012888#endif
12889#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012891#endif
12892#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012894#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012895#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012897#endif
12898#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012900#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012901#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012903#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012904#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012906#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012907#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012908#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012909 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012910#endif
12911#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012912 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012913#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012914#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012915#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012916 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012917#endif
12918#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012919 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012920#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012921#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012922 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012923#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012924#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012925 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012926#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012927#ifdef O_TMPFILE
12928 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12929#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012930#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012931 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012932#endif
12933#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012934 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012935#endif
12936#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012937 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012938#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012939#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012941#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012942#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012943 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012944#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012945
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012946
Jesus Cea94363612012-06-22 18:32:07 +020012947#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012948 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012949#endif
12950#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012951 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012952#endif
12953
Tim Peters5aa91602002-01-30 05:46:57 +000012954/* MS Windows */
12955#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012956 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012957 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012958#endif
12959#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012960 /* Optimize for short life (keep in memory). */
12961 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012962 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012963#endif
12964#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012965 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012966 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012967#endif
12968#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012970 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012971#endif
12972#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012973 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012974 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012975#endif
12976
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012977/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012978#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 /* Send a SIGIO signal whenever input or output
12980 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012981 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012982#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012983#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012984 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012985 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012986#endif
12987#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012988 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012989 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012990#endif
12991#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012992 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012993 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012994#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012995#ifdef O_NOLINKS
12996 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012997 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012998#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012999#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013000 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013001 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013002#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013003
Victor Stinner8c62be82010-05-06 00:08:46 +000013004 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013005#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013007#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013008#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013009 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013010#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013011#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013012 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013013#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013014#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013016#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013017#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013019#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013020#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013022#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013023#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013024 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013025#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013026#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013027 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013028#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013029#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013030 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013031#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013032#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013033 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013034#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013035#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013036 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013037#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013038#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013039 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013040#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013041#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013042 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013043#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013044#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013046#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013047#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013048 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013049#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013050#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013051 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013052#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013053#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013054 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013055#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013056
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013057 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013058#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013059 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013060#endif /* ST_RDONLY */
13061#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013062 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013063#endif /* ST_NOSUID */
13064
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013065 /* GNU extensions */
13066#ifdef ST_NODEV
13067 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13068#endif /* ST_NODEV */
13069#ifdef ST_NOEXEC
13070 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13071#endif /* ST_NOEXEC */
13072#ifdef ST_SYNCHRONOUS
13073 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13074#endif /* ST_SYNCHRONOUS */
13075#ifdef ST_MANDLOCK
13076 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13077#endif /* ST_MANDLOCK */
13078#ifdef ST_WRITE
13079 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13080#endif /* ST_WRITE */
13081#ifdef ST_APPEND
13082 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13083#endif /* ST_APPEND */
13084#ifdef ST_NOATIME
13085 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13086#endif /* ST_NOATIME */
13087#ifdef ST_NODIRATIME
13088 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13089#endif /* ST_NODIRATIME */
13090#ifdef ST_RELATIME
13091 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13092#endif /* ST_RELATIME */
13093
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013094 /* FreeBSD sendfile() constants */
13095#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013096 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013097#endif
13098#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013099 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013100#endif
13101#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013102 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013103#endif
13104
Ross Lagerwall7807c352011-03-17 20:20:30 +020013105 /* constants for posix_fadvise */
13106#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013107 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013108#endif
13109#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013110 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013111#endif
13112#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013113 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013114#endif
13115#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013116 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013117#endif
13118#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013119 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013120#endif
13121#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013122 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013123#endif
13124
13125 /* constants for waitid */
13126#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013127 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13128 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13129 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013130#endif
13131#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013132 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013133#endif
13134#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013135 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013136#endif
13137#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013138 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013139#endif
13140#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013141 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013142#endif
13143#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013144 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013145#endif
13146#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013147 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013148#endif
13149#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013150 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013151#endif
13152
13153 /* constants for lockf */
13154#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013155 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013156#endif
13157#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013158 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013159#endif
13160#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013161 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013162#endif
13163#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013164 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013165#endif
13166
Pablo Galindo4defba32018-01-27 16:16:37 +000013167#ifdef RWF_DSYNC
13168 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13169#endif
13170#ifdef RWF_HIPRI
13171 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13172#endif
13173#ifdef RWF_SYNC
13174 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13175#endif
13176#ifdef RWF_NOWAIT
13177 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13178#endif
13179
Guido van Rossum246bc171999-02-01 23:54:31 +000013180#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013181 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13182 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13183 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13184 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13185 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013186#endif
13187
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013188#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013189#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013190 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013191#endif
13192#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013193 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013194#endif
13195#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013196 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013197#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013198#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013199 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013200#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013201#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013202 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013203#endif
13204#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013205 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013206#endif
13207#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013208 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013209#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013210#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013211 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013212#endif
13213#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013214 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013215#endif
13216#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013217 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013218#endif
13219#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013220 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013221#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013222#endif
13223
Benjamin Peterson9428d532011-09-14 11:45:52 -040013224#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013225 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13226 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13227 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013228#endif
13229
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013230#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013231 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013232#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013233#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013234 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013235#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013236#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013237 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013238#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013239#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013240 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013241#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013242#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013243 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013244#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013245#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013246 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013247#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013248#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013249 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013250#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013251#if HAVE_DECL_RTLD_MEMBER
13252 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13253#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013254
Victor Stinner9b1f4742016-09-06 16:18:52 -070013255#ifdef HAVE_GETRANDOM_SYSCALL
13256 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13257 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13258#endif
13259
Victor Stinner8c62be82010-05-06 00:08:46 +000013260 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013261}
13262
13263
Martin v. Löwis1a214512008-06-11 05:26:20 +000013264static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013265 PyModuleDef_HEAD_INIT,
13266 MODNAME,
13267 posix__doc__,
13268 -1,
13269 posix_methods,
13270 NULL,
13271 NULL,
13272 NULL,
13273 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013274};
13275
13276
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013277static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013278
13279#ifdef HAVE_FACCESSAT
13280 "HAVE_FACCESSAT",
13281#endif
13282
13283#ifdef HAVE_FCHDIR
13284 "HAVE_FCHDIR",
13285#endif
13286
13287#ifdef HAVE_FCHMOD
13288 "HAVE_FCHMOD",
13289#endif
13290
13291#ifdef HAVE_FCHMODAT
13292 "HAVE_FCHMODAT",
13293#endif
13294
13295#ifdef HAVE_FCHOWN
13296 "HAVE_FCHOWN",
13297#endif
13298
Larry Hastings00964ed2013-08-12 13:49:30 -040013299#ifdef HAVE_FCHOWNAT
13300 "HAVE_FCHOWNAT",
13301#endif
13302
Larry Hastings9cf065c2012-06-22 16:30:09 -070013303#ifdef HAVE_FEXECVE
13304 "HAVE_FEXECVE",
13305#endif
13306
13307#ifdef HAVE_FDOPENDIR
13308 "HAVE_FDOPENDIR",
13309#endif
13310
Georg Brandl306336b2012-06-24 12:55:33 +020013311#ifdef HAVE_FPATHCONF
13312 "HAVE_FPATHCONF",
13313#endif
13314
Larry Hastings9cf065c2012-06-22 16:30:09 -070013315#ifdef HAVE_FSTATAT
13316 "HAVE_FSTATAT",
13317#endif
13318
13319#ifdef HAVE_FSTATVFS
13320 "HAVE_FSTATVFS",
13321#endif
13322
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013323#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013324 "HAVE_FTRUNCATE",
13325#endif
13326
Larry Hastings9cf065c2012-06-22 16:30:09 -070013327#ifdef HAVE_FUTIMENS
13328 "HAVE_FUTIMENS",
13329#endif
13330
13331#ifdef HAVE_FUTIMES
13332 "HAVE_FUTIMES",
13333#endif
13334
13335#ifdef HAVE_FUTIMESAT
13336 "HAVE_FUTIMESAT",
13337#endif
13338
13339#ifdef HAVE_LINKAT
13340 "HAVE_LINKAT",
13341#endif
13342
13343#ifdef HAVE_LCHFLAGS
13344 "HAVE_LCHFLAGS",
13345#endif
13346
13347#ifdef HAVE_LCHMOD
13348 "HAVE_LCHMOD",
13349#endif
13350
13351#ifdef HAVE_LCHOWN
13352 "HAVE_LCHOWN",
13353#endif
13354
13355#ifdef HAVE_LSTAT
13356 "HAVE_LSTAT",
13357#endif
13358
13359#ifdef HAVE_LUTIMES
13360 "HAVE_LUTIMES",
13361#endif
13362
13363#ifdef HAVE_MKDIRAT
13364 "HAVE_MKDIRAT",
13365#endif
13366
13367#ifdef HAVE_MKFIFOAT
13368 "HAVE_MKFIFOAT",
13369#endif
13370
13371#ifdef HAVE_MKNODAT
13372 "HAVE_MKNODAT",
13373#endif
13374
13375#ifdef HAVE_OPENAT
13376 "HAVE_OPENAT",
13377#endif
13378
13379#ifdef HAVE_READLINKAT
13380 "HAVE_READLINKAT",
13381#endif
13382
13383#ifdef HAVE_RENAMEAT
13384 "HAVE_RENAMEAT",
13385#endif
13386
13387#ifdef HAVE_SYMLINKAT
13388 "HAVE_SYMLINKAT",
13389#endif
13390
13391#ifdef HAVE_UNLINKAT
13392 "HAVE_UNLINKAT",
13393#endif
13394
13395#ifdef HAVE_UTIMENSAT
13396 "HAVE_UTIMENSAT",
13397#endif
13398
13399#ifdef MS_WINDOWS
13400 "MS_WINDOWS",
13401#endif
13402
13403 NULL
13404};
13405
13406
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013407PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013408INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013409{
Victor Stinner8c62be82010-05-06 00:08:46 +000013410 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013411 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013412 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013413
Brian Curtin52173d42010-12-02 18:29:18 +000013414#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013415 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013416#endif
13417
Victor Stinner8c62be82010-05-06 00:08:46 +000013418 m = PyModule_Create(&posixmodule);
13419 if (m == NULL)
13420 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013421
Victor Stinner8c62be82010-05-06 00:08:46 +000013422 /* Initialize environ dictionary */
13423 v = convertenviron();
13424 Py_XINCREF(v);
13425 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13426 return NULL;
13427 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013428
Victor Stinner8c62be82010-05-06 00:08:46 +000013429 if (all_ins(m))
13430 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013431
Victor Stinner8c62be82010-05-06 00:08:46 +000013432 if (setup_confname_tables(m))
13433 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013434
Victor Stinner8c62be82010-05-06 00:08:46 +000013435 Py_INCREF(PyExc_OSError);
13436 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013437
Guido van Rossumb3d39562000-01-31 18:41:26 +000013438#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013439 if (posix_putenv_garbage == NULL)
13440 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013441#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013442
Victor Stinner8c62be82010-05-06 00:08:46 +000013443 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013444#if defined(HAVE_WAITID) && !defined(__APPLE__)
13445 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013446 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13447 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013448#endif
13449
Christian Heimes25827622013-10-12 01:27:08 +020013450 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013451 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13452 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13453 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013454 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13455 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013456 structseq_new = StatResultType.tp_new;
13457 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013458
Christian Heimes25827622013-10-12 01:27:08 +020013459 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013460 if (PyStructSequence_InitType2(&StatVFSResultType,
13461 &statvfs_result_desc) < 0)
13462 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013463#ifdef NEED_TICKS_PER_SECOND
13464# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013465 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013466# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013467 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013468# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013469 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013470# endif
13471#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013472
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013473#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013474 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013475 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13476 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013477 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013478#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013479
13480 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013481 if (PyStructSequence_InitType2(&TerminalSizeType,
13482 &TerminalSize_desc) < 0)
13483 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013484
13485 /* initialize scandir types */
13486 if (PyType_Ready(&ScandirIteratorType) < 0)
13487 return NULL;
13488 if (PyType_Ready(&DirEntryType) < 0)
13489 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013490 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013491#if defined(HAVE_WAITID) && !defined(__APPLE__)
13492 Py_INCREF((PyObject*) &WaitidResultType);
13493 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13494#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013495 Py_INCREF((PyObject*) &StatResultType);
13496 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13497 Py_INCREF((PyObject*) &StatVFSResultType);
13498 PyModule_AddObject(m, "statvfs_result",
13499 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013500
13501#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013502 Py_INCREF(&SchedParamType);
13503 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013504#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013505
Larry Hastings605a62d2012-06-24 04:33:36 -070013506 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013507 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13508 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013509 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13510
13511 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013512 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13513 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013514 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13515
Thomas Wouters477c8d52006-05-27 19:21:47 +000013516#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013517 /*
13518 * Step 2 of weak-linking support on Mac OS X.
13519 *
13520 * The code below removes functions that are not available on the
13521 * currently active platform.
13522 *
13523 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013524 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013525 * OSX 10.4.
13526 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013527#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013528 if (fstatvfs == NULL) {
13529 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13530 return NULL;
13531 }
13532 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013533#endif /* HAVE_FSTATVFS */
13534
13535#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013536 if (statvfs == NULL) {
13537 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13538 return NULL;
13539 }
13540 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013541#endif /* HAVE_STATVFS */
13542
13543# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013544 if (lchown == NULL) {
13545 if (PyObject_DelAttrString(m, "lchown") == -1) {
13546 return NULL;
13547 }
13548 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013549#endif /* HAVE_LCHOWN */
13550
13551
13552#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013553
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013554 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013555 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13556
Larry Hastings6fe20b32012-04-19 15:07:49 -070013557 billion = PyLong_FromLong(1000000000);
13558 if (!billion)
13559 return NULL;
13560
Larry Hastings9cf065c2012-06-22 16:30:09 -070013561 /* suppress "function not used" warnings */
13562 {
13563 int ignored;
13564 fd_specified("", -1);
13565 follow_symlinks_specified("", 1);
13566 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13567 dir_fd_converter(Py_None, &ignored);
13568 dir_fd_unavailable(Py_None, &ignored);
13569 }
13570
13571 /*
13572 * provide list of locally available functions
13573 * so os.py can populate support_* lists
13574 */
13575 list = PyList_New(0);
13576 if (!list)
13577 return NULL;
13578 for (trace = have_functions; *trace; trace++) {
13579 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13580 if (!unicode)
13581 return NULL;
13582 if (PyList_Append(list, unicode))
13583 return NULL;
13584 Py_DECREF(unicode);
13585 }
13586 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013587
13588 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013589 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013590
13591 initialized = 1;
13592
Victor Stinner8c62be82010-05-06 00:08:46 +000013593 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013594}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013595
13596#ifdef __cplusplus
13597}
13598#endif