blob: 0c48a66a64dd78a8397620ea0e1dec91c4e605cd [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 *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001425posix_path_object_error(PyObject *path)
1426{
1427 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1428}
1429
1430static PyObject *
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001431path_object_error(PyObject *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001432{
1433#ifdef MS_WINDOWS
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001434 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1435 PyExc_OSError, 0, path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001436#else
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001437 return posix_path_object_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001438#endif
1439}
1440
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001441static PyObject *
1442path_object_error2(PyObject *path, PyObject *path2)
1443{
1444#ifdef MS_WINDOWS
1445 return PyErr_SetExcFromWindowsErrWithFilenameObjects(
1446 PyExc_OSError, 0, path, path2);
1447#else
1448 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2);
1449#endif
1450}
1451
1452static PyObject *
1453path_error(path_t *path)
1454{
1455 return path_object_error(path->object);
1456}
Larry Hastings31826802013-10-19 00:09:25 -07001457
Larry Hastingsb0827312014-02-09 22:05:19 -08001458static PyObject *
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07001459posix_path_error(path_t *path)
1460{
1461 return posix_path_object_error(path->object);
1462}
1463
1464static PyObject *
Larry Hastingsb0827312014-02-09 22:05:19 -08001465path_error2(path_t *path, path_t *path2)
1466{
Serhiy Storchaka2674bc72016-10-08 20:16:57 +03001467 return path_object_error2(path->object, path2->object);
Larry Hastingsb0827312014-02-09 22:05:19 -08001468}
1469
1470
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001471/* POSIX generic methods */
1472
Larry Hastings2f936352014-08-05 14:04:04 +10001473static int
1474fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001475{
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001477 int *pointer = (int *)p;
1478 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001479 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001480 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001481 *pointer = fd;
1482 return 1;
1483}
1484
1485static PyObject *
1486posix_fildes_fd(int fd, int (*func)(int))
1487{
1488 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001489 int async_err = 0;
1490
1491 do {
1492 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001493 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001494 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001495 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001496 Py_END_ALLOW_THREADS
1497 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1498 if (res != 0)
1499 return (!async_err) ? posix_error() : NULL;
1500 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001501}
Guido van Rossum21142a01999-01-08 21:05:37 +00001502
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001504#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505/* This is a reimplementation of the C library's chdir function,
1506 but one that produces Win32 errors instead of DOS error codes.
1507 chdir is essentially a wrapper around SetCurrentDirectory; however,
1508 it also needs to set "magic" environment variables indicating
1509 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001510static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511win32_wchdir(LPCWSTR path)
1512{
Victor Stinnered537822015-12-13 21:40:26 +01001513 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 int result;
1515 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 if(!SetCurrentDirectoryW(path))
1518 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001519 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 if (!result)
1521 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001522 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001523 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001524 if (!new_path) {
1525 SetLastError(ERROR_OUTOFMEMORY);
1526 return FALSE;
1527 }
1528 result = GetCurrentDirectoryW(result, new_path);
1529 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001530 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001531 return FALSE;
1532 }
1533 }
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001534 int is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1535 wcsncmp(new_path, L"//", 2) == 0);
1536 if (!is_unc_like_path) {
1537 env[1] = new_path[0];
1538 result = SetEnvironmentVariableW(env, new_path);
1539 }
Victor Stinnered537822015-12-13 21:40:26 +01001540 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001541 PyMem_RawFree(new_path);
Miss Islington (bot)6ae75d92018-03-01 02:28:41 -08001542 return result ? TRUE : FALSE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543}
1544#endif
1545
Martin v. Löwis14694662006-02-03 12:54:16 +00001546#ifdef MS_WINDOWS
1547/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1548 - time stamps are restricted to second resolution
1549 - file modification times suffer from forth-and-back conversions between
1550 UTC and local time
1551 Therefore, we implement our own stat, based on the Win32 API directly.
1552*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001553#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001554#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001555
Victor Stinner6036e442015-03-08 01:58:04 +01001556static void
Steve Dowercc16be82016-09-08 10:35:16 -07001557find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1558 BY_HANDLE_FILE_INFORMATION *info,
1559 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001560{
1561 memset(info, 0, sizeof(*info));
1562 info->dwFileAttributes = pFileData->dwFileAttributes;
1563 info->ftCreationTime = pFileData->ftCreationTime;
1564 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1565 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1566 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1567 info->nFileSizeLow = pFileData->nFileSizeLow;
1568/* info->nNumberOfLinks = 1; */
1569 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1570 *reparse_tag = pFileData->dwReserved0;
1571 else
1572 *reparse_tag = 0;
1573}
1574
Guido van Rossumd8faa362007-04-27 19:54:29 +00001575static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001576attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001577{
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 HANDLE hFindFile;
1579 WIN32_FIND_DATAW FileData;
1580 hFindFile = FindFirstFileW(pszFile, &FileData);
1581 if (hFindFile == INVALID_HANDLE_VALUE)
1582 return FALSE;
1583 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001584 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001585 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001586}
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588static BOOL
1589get_target_path(HANDLE hdl, wchar_t **target_path)
1590{
1591 int buf_size, result_length;
1592 wchar_t *buf;
1593
1594 /* We have a good handle to the target, use it to determine
1595 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001596 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1597 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001598 if(!buf_size)
1599 return FALSE;
1600
Victor Stinnerc36674a2016-03-16 14:30:16 +01001601 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001602 if (!buf) {
1603 SetLastError(ERROR_OUTOFMEMORY);
1604 return FALSE;
1605 }
1606
Steve Dower2ea51c92015-03-20 21:49:12 -07001607 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001608 buf, buf_size, VOLUME_NAME_DOS);
1609
1610 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001611 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001612 return FALSE;
1613 }
1614
1615 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001616 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001617 return FALSE;
1618 }
1619
1620 buf[result_length] = 0;
1621
1622 *target_path = buf;
1623 return TRUE;
1624}
1625
1626static int
Steve Dowercc16be82016-09-08 10:35:16 -07001627win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001628 BOOL traverse)
1629{
Victor Stinner26de69d2011-06-17 15:15:38 +02001630 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001631 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001633 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001634 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001635 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636
Steve Dowercc16be82016-09-08 10:35:16 -07001637 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001638 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001639 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001640 0, /* share mode */
1641 NULL, /* security attributes */
1642 OPEN_EXISTING,
1643 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001644 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1645 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001646 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001647 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1648 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001649 NULL);
1650
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001651 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001652 /* Either the target doesn't exist, or we don't have access to
1653 get a handle to it. If the former, we need to return an error.
1654 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001655 DWORD lastError = GetLastError();
1656 if (lastError != ERROR_ACCESS_DENIED &&
1657 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 return -1;
1659 /* Could not get attributes on open file. Fall back to
1660 reading the directory. */
1661 if (!attributes_from_dir(path, &info, &reparse_tag))
1662 /* Very strange. This should not fail now */
1663 return -1;
1664 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1665 if (traverse) {
1666 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001667 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001668 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001671 } else {
1672 if (!GetFileInformationByHandle(hFile, &info)) {
1673 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001674 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 }
1676 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001677 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1678 return -1;
1679
1680 /* Close the outer open file handle now that we're about to
1681 reopen it with different flags. */
1682 if (!CloseHandle(hFile))
1683 return -1;
1684
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001686 /* In order to call GetFinalPathNameByHandle we need to open
1687 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001688 hFile2 = CreateFileW(
1689 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1690 NULL, OPEN_EXISTING,
1691 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1692 NULL);
1693 if (hFile2 == INVALID_HANDLE_VALUE)
1694 return -1;
1695
1696 if (!get_target_path(hFile2, &target_path))
1697 return -1;
1698
Steve Dowercc16be82016-09-08 10:35:16 -07001699 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001700 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001701 return code;
1702 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001703 } else
1704 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001706 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001707
1708 /* Set S_IEXEC if it is an .exe, .bat, ... */
1709 dot = wcsrchr(path, '.');
1710 if (dot) {
1711 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1712 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1713 result->st_mode |= 0111;
1714 }
1715 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716}
1717
1718static int
Steve Dowercc16be82016-09-08 10:35:16 -07001719win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 /* Protocol violation: we explicitly clear errno, instead of
1722 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001723 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001724 errno = 0;
1725 return code;
1726}
Brian Curtind25aef52011-06-13 15:16:04 -05001727/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001728
1729 In Posix, stat automatically traverses symlinks and returns the stat
1730 structure for the target. In Windows, the equivalent GetFileAttributes by
1731 default does not traverse symlinks and instead returns attributes for
1732 the symlink.
1733
1734 Therefore, win32_lstat will get the attributes traditionally, and
1735 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001736 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001737
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001738static int
Steve Dowercc16be82016-09-08 10:35:16 -07001739win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001740{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001741 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001742}
1743
Victor Stinner8c62be82010-05-06 00:08:46 +00001744static int
Steve Dowercc16be82016-09-08 10:35:16 -07001745win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001746{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001747 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001748}
1749
Martin v. Löwis14694662006-02-03 12:54:16 +00001750#endif /* MS_WINDOWS */
1751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001753"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001755 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1757\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001758Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1759or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001760\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762
1763static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_mode", "protection bits"},
1765 {"st_ino", "inode"},
1766 {"st_dev", "device"},
1767 {"st_nlink", "number of hard links"},
1768 {"st_uid", "user ID of owner"},
1769 {"st_gid", "group ID of owner"},
1770 {"st_size", "total size, in bytes"},
1771 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1772 {NULL, "integer time of last access"},
1773 {NULL, "integer time of last modification"},
1774 {NULL, "integer time of last change"},
1775 {"st_atime", "time of last access"},
1776 {"st_mtime", "time of last modification"},
1777 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001778 {"st_atime_ns", "time of last access in nanoseconds"},
1779 {"st_mtime_ns", "time of last modification in nanoseconds"},
1780 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001781#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001787#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001790#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001792#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001793#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001795#endif
1796#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001798#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001799#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1800 {"st_file_attributes", "Windows file attribute bits"},
1801#endif
jcea6c51d512018-01-28 14:00:08 +01001802#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1803 {"st_fstype", "Type of filesystem"},
1804#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806};
1807
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001808#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001809#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001810#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001811#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812#endif
1813
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001814#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001815#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1816#else
1817#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1818#endif
1819
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001820#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001821#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1822#else
1823#define ST_RDEV_IDX ST_BLOCKS_IDX
1824#endif
1825
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001826#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1827#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1828#else
1829#define ST_FLAGS_IDX ST_RDEV_IDX
1830#endif
1831
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001832#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001833#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001834#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001835#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#endif
1837
1838#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1839#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1840#else
1841#define ST_BIRTHTIME_IDX ST_GEN_IDX
1842#endif
1843
Zachary Ware63f277b2014-06-19 09:46:37 -05001844#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1845#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1846#else
1847#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1848#endif
1849
jcea6c51d512018-01-28 14:00:08 +01001850#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
1851#define ST_FSTYPE_IDX (ST_FILE_ATTRIBUTES_IDX+1)
1852#else
1853#define ST_FSTYPE_IDX ST_FILE_ATTRIBUTES_IDX
1854#endif
1855
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 "stat_result", /* name */
1858 stat_result__doc__, /* doc */
1859 stat_result_fields,
1860 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861};
1862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001863PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1865This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001867or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001870
1871static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001872 {"f_bsize", },
1873 {"f_frsize", },
1874 {"f_blocks", },
1875 {"f_bfree", },
1876 {"f_bavail", },
1877 {"f_files", },
1878 {"f_ffree", },
1879 {"f_favail", },
1880 {"f_flag", },
1881 {"f_namemax",},
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01001882 {"f_fsid", },
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001884};
1885
1886static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 "statvfs_result", /* name */
1888 statvfs_result__doc__, /* doc */
1889 statvfs_result_fields,
1890 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001891};
1892
Ross Lagerwall7807c352011-03-17 20:20:30 +02001893#if defined(HAVE_WAITID) && !defined(__APPLE__)
1894PyDoc_STRVAR(waitid_result__doc__,
1895"waitid_result: Result from waitid.\n\n\
1896This object may be accessed either as a tuple of\n\
1897 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1898or via the attributes si_pid, si_uid, and so on.\n\
1899\n\
1900See os.waitid for more information.");
1901
1902static PyStructSequence_Field waitid_result_fields[] = {
1903 {"si_pid", },
1904 {"si_uid", },
1905 {"si_signo", },
1906 {"si_status", },
1907 {"si_code", },
1908 {0}
1909};
1910
1911static PyStructSequence_Desc waitid_result_desc = {
1912 "waitid_result", /* name */
1913 waitid_result__doc__, /* doc */
1914 waitid_result_fields,
1915 5
1916};
1917static PyTypeObject WaitidResultType;
1918#endif
1919
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001920static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921static PyTypeObject StatResultType;
1922static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001923#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001924static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001925#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001926static newfunc structseq_new;
1927
1928static PyObject *
1929statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1930{
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 PyStructSequence *result;
1932 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 result = (PyStructSequence*)structseq_new(type, args, kwds);
1935 if (!result)
1936 return NULL;
1937 /* If we have been initialized from a tuple,
1938 st_?time might be set to None. Initialize it
1939 from the int slots. */
1940 for (i = 7; i <= 9; i++) {
1941 if (result->ob_item[i+3] == Py_None) {
1942 Py_DECREF(Py_None);
1943 Py_INCREF(result->ob_item[i]);
1944 result->ob_item[i+3] = result->ob_item[i];
1945 }
1946 }
1947 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001948}
1949
1950
Larry Hastings6fe20b32012-04-19 15:07:49 -07001951static PyObject *billion = NULL;
1952
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001953static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001954fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001955{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001956 PyObject *s = _PyLong_FromTime_t(sec);
1957 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1958 PyObject *s_in_ns = NULL;
1959 PyObject *ns_total = NULL;
1960 PyObject *float_s = NULL;
1961
1962 if (!(s && ns_fractional))
1963 goto exit;
1964
1965 s_in_ns = PyNumber_Multiply(s, billion);
1966 if (!s_in_ns)
1967 goto exit;
1968
1969 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1970 if (!ns_total)
1971 goto exit;
1972
Victor Stinner01b5aab2017-10-24 02:02:00 -07001973 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1974 if (!float_s) {
1975 goto exit;
Larry Hastings6fe20b32012-04-19 15:07:49 -07001976 }
1977
1978 PyStructSequence_SET_ITEM(v, index, s);
1979 PyStructSequence_SET_ITEM(v, index+3, float_s);
1980 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1981 s = NULL;
1982 float_s = NULL;
1983 ns_total = NULL;
1984exit:
1985 Py_XDECREF(s);
1986 Py_XDECREF(ns_fractional);
1987 Py_XDECREF(s_in_ns);
1988 Py_XDECREF(ns_total);
1989 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001990}
1991
Tim Peters5aa91602002-01-30 05:46:57 +00001992/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001993 (used by posix_stat() and posix_fstat()) */
1994static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001995_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001996{
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 unsigned long ansec, mnsec, cnsec;
1998 PyObject *v = PyStructSequence_New(&StatResultType);
1999 if (v == NULL)
2000 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002001
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Victor Stinner0f6d7332017-03-09 17:34:28 +01002003 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino));
xdegaye50e86032017-05-22 11:15:08 +02002004 PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino));
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002005#ifdef MS_WINDOWS
2006 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002007#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002008 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002011#if defined(MS_WINDOWS)
2012 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2013 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2014#else
2015 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2016 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2017#endif
xdegaye50e86032017-05-22 11:15:08 +02002018 Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size));
2019 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size));
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002020
Martin v. Löwis14694662006-02-03 12:54:16 +00002021#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 ansec = st->st_atim.tv_nsec;
2023 mnsec = st->st_mtim.tv_nsec;
2024 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002025#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 ansec = st->st_atimespec.tv_nsec;
2027 mnsec = st->st_mtimespec.tv_nsec;
2028 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002029#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 ansec = st->st_atime_nsec;
2031 mnsec = st->st_mtime_nsec;
2032 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002033#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002035#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002036 fill_time(v, 7, st->st_atime, ansec);
2037 fill_time(v, 8, st->st_mtime, mnsec);
2038 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002039
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002040#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2042 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002043#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002044#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2046 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002047#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002048#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2050 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002051#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002052#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2054 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002055#endif
2056#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002058 PyObject *val;
2059 unsigned long bsec,bnsec;
2060 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002061#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002062 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002063#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002064 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002065#endif
Victor Stinner01b5aab2017-10-24 02:02:00 -07002066 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
Victor Stinner4195b5c2012-02-08 23:03:19 +01002067 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2068 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002070#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002071#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2073 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002074#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002075#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2076 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2077 PyLong_FromUnsignedLong(st->st_file_attributes));
2078#endif
jcea6c51d512018-01-28 14:00:08 +01002079#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
2080 PyStructSequence_SET_ITEM(v, ST_FSTYPE_IDX,
2081 PyUnicode_FromString(st->st_fstype));
2082#endif
Fred Drake699f3522000-06-29 21:12:41 +00002083
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 if (PyErr_Occurred()) {
2085 Py_DECREF(v);
2086 return NULL;
2087 }
Fred Drake699f3522000-06-29 21:12:41 +00002088
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002090}
2091
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092/* POSIX methods */
2093
Guido van Rossum94f6f721999-01-06 18:42:14 +00002094
2095static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002096posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002097 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002098{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002099 STRUCT_STAT st;
2100 int result;
2101
2102#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2103 if (follow_symlinks_specified(function_name, follow_symlinks))
2104 return NULL;
2105#endif
2106
2107 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2108 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2109 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2110 return NULL;
2111
2112 Py_BEGIN_ALLOW_THREADS
2113 if (path->fd != -1)
2114 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002115#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002116 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002117 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002118 else
Steve Dowercc16be82016-09-08 10:35:16 -07002119 result = win32_lstat(path->wide, &st);
2120#else
2121 else
2122#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002123 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2124 result = LSTAT(path->narrow, &st);
2125 else
Steve Dowercc16be82016-09-08 10:35:16 -07002126#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002127#ifdef HAVE_FSTATAT
2128 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2129 result = fstatat(dir_fd, path->narrow, &st,
2130 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2131 else
Steve Dowercc16be82016-09-08 10:35:16 -07002132#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002133 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002134#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002135 Py_END_ALLOW_THREADS
2136
Victor Stinner292c8352012-10-30 02:17:38 +01002137 if (result != 0) {
2138 return path_error(path);
2139 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002140
2141 return _pystat_fromstructstat(&st);
2142}
2143
Larry Hastings2f936352014-08-05 14:04:04 +10002144/*[python input]
2145
2146for s in """
2147
2148FACCESSAT
2149FCHMODAT
2150FCHOWNAT
2151FSTATAT
2152LINKAT
2153MKDIRAT
2154MKFIFOAT
2155MKNODAT
2156OPENAT
2157READLINKAT
2158SYMLINKAT
2159UNLINKAT
2160
2161""".strip().split():
2162 s = s.strip()
2163 print("""
2164#ifdef HAVE_{s}
2165 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002166#else
Larry Hastings2f936352014-08-05 14:04:04 +10002167 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002168#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002169""".rstrip().format(s=s))
2170
2171for s in """
2172
2173FCHDIR
2174FCHMOD
2175FCHOWN
2176FDOPENDIR
2177FEXECVE
2178FPATHCONF
2179FSTATVFS
2180FTRUNCATE
2181
2182""".strip().split():
2183 s = s.strip()
2184 print("""
2185#ifdef HAVE_{s}
2186 #define PATH_HAVE_{s} 1
2187#else
2188 #define PATH_HAVE_{s} 0
2189#endif
2190
2191""".rstrip().format(s=s))
2192[python start generated code]*/
2193
2194#ifdef HAVE_FACCESSAT
2195 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2196#else
2197 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2198#endif
2199
2200#ifdef HAVE_FCHMODAT
2201 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2202#else
2203 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2204#endif
2205
2206#ifdef HAVE_FCHOWNAT
2207 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2208#else
2209 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2210#endif
2211
2212#ifdef HAVE_FSTATAT
2213 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_LINKAT
2219 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_MKDIRAT
2225 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_MKFIFOAT
2231 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_MKNODAT
2237 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_OPENAT
2243 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_READLINKAT
2249 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_SYMLINKAT
2255 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_UNLINKAT
2261 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_FCHDIR
2267 #define PATH_HAVE_FCHDIR 1
2268#else
2269 #define PATH_HAVE_FCHDIR 0
2270#endif
2271
2272#ifdef HAVE_FCHMOD
2273 #define PATH_HAVE_FCHMOD 1
2274#else
2275 #define PATH_HAVE_FCHMOD 0
2276#endif
2277
2278#ifdef HAVE_FCHOWN
2279 #define PATH_HAVE_FCHOWN 1
2280#else
2281 #define PATH_HAVE_FCHOWN 0
2282#endif
2283
2284#ifdef HAVE_FDOPENDIR
2285 #define PATH_HAVE_FDOPENDIR 1
2286#else
2287 #define PATH_HAVE_FDOPENDIR 0
2288#endif
2289
2290#ifdef HAVE_FEXECVE
2291 #define PATH_HAVE_FEXECVE 1
2292#else
2293 #define PATH_HAVE_FEXECVE 0
2294#endif
2295
2296#ifdef HAVE_FPATHCONF
2297 #define PATH_HAVE_FPATHCONF 1
2298#else
2299 #define PATH_HAVE_FPATHCONF 0
2300#endif
2301
2302#ifdef HAVE_FSTATVFS
2303 #define PATH_HAVE_FSTATVFS 1
2304#else
2305 #define PATH_HAVE_FSTATVFS 0
2306#endif
2307
2308#ifdef HAVE_FTRUNCATE
2309 #define PATH_HAVE_FTRUNCATE 1
2310#else
2311 #define PATH_HAVE_FTRUNCATE 0
2312#endif
2313/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002314
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002315#ifdef MS_WINDOWS
2316 #undef PATH_HAVE_FTRUNCATE
2317 #define PATH_HAVE_FTRUNCATE 1
2318#endif
Larry Hastings31826802013-10-19 00:09:25 -07002319
Larry Hastings61272b72014-01-07 12:41:53 -08002320/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002321
2322class path_t_converter(CConverter):
2323
2324 type = "path_t"
2325 impl_by_reference = True
2326 parse_by_reference = True
2327
2328 converter = 'path_converter'
2329
2330 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002331 # right now path_t doesn't support default values.
2332 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002333 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002334 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002335
Larry Hastings2f936352014-08-05 14:04:04 +10002336 if self.c_default not in (None, 'Py_None'):
2337 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002338
2339 self.nullable = nullable
2340 self.allow_fd = allow_fd
2341
Larry Hastings7726ac92014-01-31 22:03:12 -08002342 def pre_render(self):
2343 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002344 if isinstance(value, str):
2345 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002346 return str(int(bool(value)))
2347
2348 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002349 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002350 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002351 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002352 strify(self.nullable),
2353 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002354 )
2355
2356 def cleanup(self):
2357 return "path_cleanup(&" + self.name + ");\n"
2358
2359
2360class dir_fd_converter(CConverter):
2361 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002362
Larry Hastings2f936352014-08-05 14:04:04 +10002363 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002364 if self.default in (unspecified, None):
2365 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002366 if isinstance(requires, str):
2367 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2368 else:
2369 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002370
Larry Hastings2f936352014-08-05 14:04:04 +10002371class fildes_converter(CConverter):
2372 type = 'int'
2373 converter = 'fildes_converter'
2374
2375class uid_t_converter(CConverter):
2376 type = "uid_t"
2377 converter = '_Py_Uid_Converter'
2378
2379class gid_t_converter(CConverter):
2380 type = "gid_t"
2381 converter = '_Py_Gid_Converter'
2382
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002383class dev_t_converter(CConverter):
2384 type = 'dev_t'
2385 converter = '_Py_Dev_Converter'
2386
2387class dev_t_return_converter(unsigned_long_return_converter):
2388 type = 'dev_t'
2389 conversion_fn = '_PyLong_FromDev'
2390 unsigned_cast = '(dev_t)'
2391
Larry Hastings2f936352014-08-05 14:04:04 +10002392class FSConverter_converter(CConverter):
2393 type = 'PyObject *'
2394 converter = 'PyUnicode_FSConverter'
2395 def converter_init(self):
2396 if self.default is not unspecified:
2397 fail("FSConverter_converter does not support default values")
2398 self.c_default = 'NULL'
2399
2400 def cleanup(self):
2401 return "Py_XDECREF(" + self.name + ");\n"
2402
2403class pid_t_converter(CConverter):
2404 type = 'pid_t'
2405 format_unit = '" _Py_PARSE_PID "'
2406
2407class idtype_t_converter(int_converter):
2408 type = 'idtype_t'
2409
2410class id_t_converter(CConverter):
2411 type = 'id_t'
2412 format_unit = '" _Py_PARSE_PID "'
2413
Benjamin Petersonca470632016-09-06 13:47:26 -07002414class intptr_t_converter(CConverter):
2415 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002416 format_unit = '" _Py_PARSE_INTPTR "'
2417
2418class Py_off_t_converter(CConverter):
2419 type = 'Py_off_t'
2420 converter = 'Py_off_t_converter'
2421
2422class Py_off_t_return_converter(long_return_converter):
2423 type = 'Py_off_t'
2424 conversion_fn = 'PyLong_FromPy_off_t'
2425
2426class path_confname_converter(CConverter):
2427 type="int"
2428 converter="conv_path_confname"
2429
2430class confstr_confname_converter(path_confname_converter):
2431 converter='conv_confstr_confname'
2432
2433class sysconf_confname_converter(path_confname_converter):
2434 converter="conv_sysconf_confname"
2435
2436class sched_param_converter(CConverter):
2437 type = 'struct sched_param'
2438 converter = 'convert_sched_param'
2439 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002440
Larry Hastings61272b72014-01-07 12:41:53 -08002441[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002442/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002443
Larry Hastings61272b72014-01-07 12:41:53 -08002444/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002445
Larry Hastings2a727912014-01-16 11:32:01 -08002446os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002447
2448 path : path_t(allow_fd=True)
Xiang Zhang4459e002017-01-22 13:04:17 +08002449 Path to be examined; can be string, bytes, path-like object or
2450 open-file-descriptor int.
Larry Hastings31826802013-10-19 00:09:25 -07002451
2452 *
2453
Larry Hastings2f936352014-08-05 14:04:04 +10002454 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002455 If not None, it should be a file descriptor open to a directory,
2456 and path should be a relative string; path will then be relative to
2457 that directory.
2458
2459 follow_symlinks: bool = True
2460 If False, and the last element of the path is a symbolic link,
2461 stat will examine the symbolic link itself instead of the file
2462 the link points to.
2463
2464Perform a stat system call on the given path.
2465
2466dir_fd and follow_symlinks may not be implemented
2467 on your platform. If they are unavailable, using them will raise a
2468 NotImplementedError.
2469
2470It's an error to use dir_fd or follow_symlinks when specifying path as
2471 an open file descriptor.
2472
Larry Hastings61272b72014-01-07 12:41:53 -08002473[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002474
Larry Hastings31826802013-10-19 00:09:25 -07002475static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002476os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
Xiang Zhang4459e002017-01-22 13:04:17 +08002477/*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/
Larry Hastings31826802013-10-19 00:09:25 -07002478{
2479 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2480}
2481
Larry Hastings2f936352014-08-05 14:04:04 +10002482
2483/*[clinic input]
2484os.lstat
2485
2486 path : path_t
2487
2488 *
2489
2490 dir_fd : dir_fd(requires='fstatat') = None
2491
2492Perform a stat system call on the given path, without following symbolic links.
2493
2494Like stat(), but do not follow symbolic links.
2495Equivalent to stat(path, follow_symlinks=False).
2496[clinic start generated code]*/
2497
Larry Hastings2f936352014-08-05 14:04:04 +10002498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002499os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2500/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002501{
2502 int follow_symlinks = 0;
2503 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2504}
Larry Hastings31826802013-10-19 00:09:25 -07002505
Larry Hastings2f936352014-08-05 14:04:04 +10002506
Larry Hastings61272b72014-01-07 12:41:53 -08002507/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002508os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002509
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002510 path: path_t
2511 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002512
2513 mode: int
2514 Operating-system mode bitfield. Can be F_OK to test existence,
2515 or the inclusive-OR of R_OK, W_OK, and X_OK.
2516
2517 *
2518
Larry Hastings2f936352014-08-05 14:04:04 +10002519 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002520 If not None, it should be a file descriptor open to a directory,
2521 and path should be relative; path will then be relative to that
2522 directory.
2523
2524 effective_ids: bool = False
2525 If True, access will use the effective uid/gid instead of
2526 the real uid/gid.
2527
2528 follow_symlinks: bool = True
2529 If False, and the last element of the path is a symbolic link,
2530 access will examine the symbolic link itself instead of the file
2531 the link points to.
2532
2533Use the real uid/gid to test for access to a path.
2534
2535{parameters}
2536dir_fd, effective_ids, and follow_symlinks may not be implemented
2537 on your platform. If they are unavailable, using them will raise a
2538 NotImplementedError.
2539
2540Note that most operations will use the effective uid/gid, therefore this
2541 routine can be used in a suid/sgid environment to test if the invoking user
2542 has the specified access to the path.
2543
Larry Hastings61272b72014-01-07 12:41:53 -08002544[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002545
Larry Hastings2f936352014-08-05 14:04:04 +10002546static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002547os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002548 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002549/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002550{
Larry Hastings2f936352014-08-05 14:04:04 +10002551 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002552
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002553#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002554 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002555#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002556 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002557#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558
Larry Hastings9cf065c2012-06-22 16:30:09 -07002559#ifndef HAVE_FACCESSAT
2560 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002561 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562
2563 if (effective_ids) {
2564 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002565 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002566 }
2567#endif
2568
2569#ifdef MS_WINDOWS
2570 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002571 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 Py_END_ALLOW_THREADS
2573
2574 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002575 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576 * * we didn't get a -1, and
2577 * * write access wasn't requested,
2578 * * or the file isn't read-only,
2579 * * or it's a directory.
2580 * (Directories cannot be read-only on Windows.)
2581 */
Larry Hastings2f936352014-08-05 14:04:04 +10002582 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002583 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002585 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002586#else
2587
2588 Py_BEGIN_ALLOW_THREADS
2589#ifdef HAVE_FACCESSAT
2590 if ((dir_fd != DEFAULT_DIR_FD) ||
2591 effective_ids ||
2592 !follow_symlinks) {
2593 int flags = 0;
2594 if (!follow_symlinks)
2595 flags |= AT_SYMLINK_NOFOLLOW;
2596 if (effective_ids)
2597 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002598 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599 }
2600 else
2601#endif
Larry Hastings31826802013-10-19 00:09:25 -07002602 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002604 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605#endif
2606
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002608}
2609
Guido van Rossumd371ff11999-01-25 16:12:23 +00002610#ifndef F_OK
2611#define F_OK 0
2612#endif
2613#ifndef R_OK
2614#define R_OK 4
2615#endif
2616#ifndef W_OK
2617#define W_OK 2
2618#endif
2619#ifndef X_OK
2620#define X_OK 1
2621#endif
2622
Larry Hastings31826802013-10-19 00:09:25 -07002623
Guido van Rossumd371ff11999-01-25 16:12:23 +00002624#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002625/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002626os.ttyname -> DecodeFSDefault
2627
2628 fd: int
2629 Integer file descriptor handle.
2630
2631 /
2632
2633Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002634[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002635
Larry Hastings31826802013-10-19 00:09:25 -07002636static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002637os_ttyname_impl(PyObject *module, int fd)
2638/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002639{
2640 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002641
Larry Hastings31826802013-10-19 00:09:25 -07002642 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002643 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002644 posix_error();
2645 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002646}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002647#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002648
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002649#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002650/*[clinic input]
2651os.ctermid
2652
2653Return the name of the controlling terminal for this process.
2654[clinic start generated code]*/
2655
Larry Hastings2f936352014-08-05 14:04:04 +10002656static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002657os_ctermid_impl(PyObject *module)
2658/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659{
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 char *ret;
2661 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002662
Greg Wardb48bc172000-03-01 21:51:56 +00002663#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002667#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 if (ret == NULL)
2669 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002670 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671}
Larry Hastings2f936352014-08-05 14:04:04 +10002672#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673
Larry Hastings2f936352014-08-05 14:04:04 +10002674
2675/*[clinic input]
2676os.chdir
2677
2678 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2679
2680Change the current working directory to the specified path.
2681
2682path may always be specified as a string.
2683On some platforms, path may also be specified as an open file descriptor.
2684 If this functionality is unavailable, using it raises an exception.
2685[clinic start generated code]*/
2686
Larry Hastings2f936352014-08-05 14:04:04 +10002687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002688os_chdir_impl(PyObject *module, path_t *path)
2689/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002690{
2691 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002692
2693 Py_BEGIN_ALLOW_THREADS
2694#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002695 /* on unix, success = 0, on windows, success = !0 */
2696 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697#else
2698#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002699 if (path->fd != -1)
2700 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701 else
2702#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002703 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704#endif
2705 Py_END_ALLOW_THREADS
2706
2707 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002708 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709 }
2710
Larry Hastings2f936352014-08-05 14:04:04 +10002711 Py_RETURN_NONE;
2712}
2713
2714
2715#ifdef HAVE_FCHDIR
2716/*[clinic input]
2717os.fchdir
2718
2719 fd: fildes
2720
2721Change to the directory of the given file descriptor.
2722
2723fd must be opened on a directory, not a file.
2724Equivalent to os.chdir(fd).
2725
2726[clinic start generated code]*/
2727
Fred Drake4d1e64b2002-04-15 19:40:07 +00002728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002729os_fchdir_impl(PyObject *module, int fd)
2730/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002731{
Larry Hastings2f936352014-08-05 14:04:04 +10002732 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002733}
2734#endif /* HAVE_FCHDIR */
2735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002736
Larry Hastings2f936352014-08-05 14:04:04 +10002737/*[clinic input]
2738os.chmod
2739
2740 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2741 Path to be modified. May always be specified as a str or bytes.
2742 On some platforms, path may also be specified as an open file descriptor.
2743 If this functionality is unavailable, using it raises an exception.
2744
2745 mode: int
2746 Operating-system mode bitfield.
2747
2748 *
2749
2750 dir_fd : dir_fd(requires='fchmodat') = None
2751 If not None, it should be a file descriptor open to a directory,
2752 and path should be relative; path will then be relative to that
2753 directory.
2754
2755 follow_symlinks: bool = True
2756 If False, and the last element of the path is a symbolic link,
2757 chmod will modify the symbolic link itself instead of the file
2758 the link points to.
2759
2760Change the access permissions of a file.
2761
2762It is an error to use dir_fd or follow_symlinks when specifying path as
2763 an open file descriptor.
2764dir_fd and follow_symlinks may not be implemented on your platform.
2765 If they are unavailable, using them will raise a NotImplementedError.
2766
2767[clinic start generated code]*/
2768
Larry Hastings2f936352014-08-05 14:04:04 +10002769static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002770os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002771 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002772/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002773{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002775
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002776#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002779
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780#ifdef HAVE_FCHMODAT
2781 int fchmodat_nofollow_unsupported = 0;
2782#endif
2783
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2785 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002786 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787#endif
2788
2789#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002790 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002791 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002792 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793 result = 0;
2794 else {
2795 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 attr &= ~FILE_ATTRIBUTE_READONLY;
2797 else
2798 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002799 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800 }
2801 Py_END_ALLOW_THREADS
2802
2803 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002804 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805 }
2806#else /* MS_WINDOWS */
2807 Py_BEGIN_ALLOW_THREADS
2808#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002809 if (path->fd != -1)
2810 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 else
2812#endif
2813#ifdef HAVE_LCHMOD
2814 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002815 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 else
2817#endif
2818#ifdef HAVE_FCHMODAT
2819 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2820 /*
2821 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2822 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002823 * and then says it isn't implemented yet.
2824 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 *
2826 * Once it is supported, os.chmod will automatically
2827 * support dir_fd and follow_symlinks=False. (Hopefully.)
2828 * Until then, we need to be careful what exception we raise.
2829 */
Larry Hastings2f936352014-08-05 14:04:04 +10002830 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2832 /*
2833 * But wait! We can't throw the exception without allowing threads,
2834 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2835 */
2836 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002837 result &&
2838 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2839 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 }
2841 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002842#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002843 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 Py_END_ALLOW_THREADS
2845
2846 if (result) {
2847#ifdef HAVE_FCHMODAT
2848 if (fchmodat_nofollow_unsupported) {
2849 if (dir_fd != DEFAULT_DIR_FD)
2850 dir_fd_and_follow_symlinks_invalid("chmod",
2851 dir_fd, follow_symlinks);
2852 else
2853 follow_symlinks_specified("chmod", follow_symlinks);
Anthony Sottile233ef242017-12-14 08:57:55 -08002854 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 }
2856 else
2857#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002858 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 }
2860#endif
2861
Larry Hastings2f936352014-08-05 14:04:04 +10002862 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002863}
2864
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865
Christian Heimes4e30a842007-11-30 22:12:06 +00002866#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002867/*[clinic input]
2868os.fchmod
2869
2870 fd: int
2871 mode: int
2872
2873Change the access permissions of the file given by file descriptor fd.
2874
2875Equivalent to os.chmod(fd, mode).
2876[clinic start generated code]*/
2877
Larry Hastings2f936352014-08-05 14:04:04 +10002878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002879os_fchmod_impl(PyObject *module, int fd, int mode)
2880/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002881{
2882 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002883 int async_err = 0;
2884
2885 do {
2886 Py_BEGIN_ALLOW_THREADS
2887 res = fchmod(fd, mode);
2888 Py_END_ALLOW_THREADS
2889 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2890 if (res != 0)
2891 return (!async_err) ? posix_error() : NULL;
2892
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002894}
2895#endif /* HAVE_FCHMOD */
2896
Larry Hastings2f936352014-08-05 14:04:04 +10002897
Christian Heimes4e30a842007-11-30 22:12:06 +00002898#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002899/*[clinic input]
2900os.lchmod
2901
2902 path: path_t
2903 mode: int
2904
2905Change the access permissions of a file, without following symbolic links.
2906
2907If path is a symlink, this affects the link itself rather than the target.
2908Equivalent to chmod(path, mode, follow_symlinks=False)."
2909[clinic start generated code]*/
2910
Larry Hastings2f936352014-08-05 14:04:04 +10002911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002912os_lchmod_impl(PyObject *module, path_t *path, int mode)
2913/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002914{
Victor Stinner8c62be82010-05-06 00:08:46 +00002915 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002917 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002919 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002920 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002921 return NULL;
2922 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002923 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002924}
2925#endif /* HAVE_LCHMOD */
2926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002927
Thomas Wouterscf297e42007-02-23 15:07:44 +00002928#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002929/*[clinic input]
2930os.chflags
2931
2932 path: path_t
2933 flags: unsigned_long(bitwise=True)
2934 follow_symlinks: bool=True
2935
2936Set file flags.
2937
2938If follow_symlinks is False, and the last element of the path is a symbolic
2939 link, chflags will change flags on the symbolic link itself instead of the
2940 file the link points to.
2941follow_symlinks may not be implemented on your platform. If it is
2942unavailable, using it will raise a NotImplementedError.
2943
2944[clinic start generated code]*/
2945
Larry Hastings2f936352014-08-05 14:04:04 +10002946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002947os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002948 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002949/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002950{
2951 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002952
2953#ifndef HAVE_LCHFLAGS
2954 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002955 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002956#endif
2957
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959#ifdef HAVE_LCHFLAGS
2960 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002961 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 else
2963#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002964 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002965 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966
Larry Hastings2f936352014-08-05 14:04:04 +10002967 if (result)
2968 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002969
Larry Hastings2f936352014-08-05 14:04:04 +10002970 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002971}
2972#endif /* HAVE_CHFLAGS */
2973
Larry Hastings2f936352014-08-05 14:04:04 +10002974
Thomas Wouterscf297e42007-02-23 15:07:44 +00002975#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002976/*[clinic input]
2977os.lchflags
2978
2979 path: path_t
2980 flags: unsigned_long(bitwise=True)
2981
2982Set file flags.
2983
2984This function will not follow symbolic links.
2985Equivalent to chflags(path, flags, follow_symlinks=False).
2986[clinic start generated code]*/
2987
Larry Hastings2f936352014-08-05 14:04:04 +10002988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002989os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2990/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002991{
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002994 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002996 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002997 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002998 }
Victor Stinner292c8352012-10-30 02:17:38 +01002999 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003000}
3001#endif /* HAVE_LCHFLAGS */
3002
Larry Hastings2f936352014-08-05 14:04:04 +10003003
Martin v. Löwis244edc82001-10-04 22:44:26 +00003004#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003005/*[clinic input]
3006os.chroot
3007 path: path_t
3008
3009Change root directory to path.
3010
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_chroot_impl(PyObject *module, path_t *path)
3015/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
3017 int res;
3018 Py_BEGIN_ALLOW_THREADS
3019 res = chroot(path->narrow);
3020 Py_END_ALLOW_THREADS
3021 if (res < 0)
3022 return path_error(path);
3023 Py_RETURN_NONE;
3024}
3025#endif /* HAVE_CHROOT */
3026
Martin v. Löwis244edc82001-10-04 22:44:26 +00003027
Guido van Rossum21142a01999-01-08 21:05:37 +00003028#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003029/*[clinic input]
3030os.fsync
3031
3032 fd: fildes
3033
3034Force write of fd to disk.
3035[clinic start generated code]*/
3036
Larry Hastings2f936352014-08-05 14:04:04 +10003037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003038os_fsync_impl(PyObject *module, int fd)
3039/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003040{
3041 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003042}
3043#endif /* HAVE_FSYNC */
3044
Larry Hastings2f936352014-08-05 14:04:04 +10003045
Ross Lagerwall7807c352011-03-17 20:20:30 +02003046#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003047/*[clinic input]
3048os.sync
3049
3050Force write of everything to disk.
3051[clinic start generated code]*/
3052
Larry Hastings2f936352014-08-05 14:04:04 +10003053static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003054os_sync_impl(PyObject *module)
3055/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003056{
3057 Py_BEGIN_ALLOW_THREADS
3058 sync();
3059 Py_END_ALLOW_THREADS
3060 Py_RETURN_NONE;
3061}
Larry Hastings2f936352014-08-05 14:04:04 +10003062#endif /* HAVE_SYNC */
3063
Ross Lagerwall7807c352011-03-17 20:20:30 +02003064
Guido van Rossum21142a01999-01-08 21:05:37 +00003065#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003066#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003067extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3068#endif
3069
Larry Hastings2f936352014-08-05 14:04:04 +10003070/*[clinic input]
3071os.fdatasync
3072
3073 fd: fildes
3074
3075Force write of fd to disk without forcing update of metadata.
3076[clinic start generated code]*/
3077
Larry Hastings2f936352014-08-05 14:04:04 +10003078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003079os_fdatasync_impl(PyObject *module, int fd)
3080/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003081{
3082 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003083}
3084#endif /* HAVE_FDATASYNC */
3085
3086
Fredrik Lundh10723342000-07-10 16:38:09 +00003087#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003088/*[clinic input]
3089os.chown
3090
3091 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3092 Path to be examined; can be string, bytes, or open-file-descriptor int.
3093
3094 uid: uid_t
3095
3096 gid: gid_t
3097
3098 *
3099
3100 dir_fd : dir_fd(requires='fchownat') = None
3101 If not None, it should be a file descriptor open to a directory,
3102 and path should be relative; path will then be relative to that
3103 directory.
3104
3105 follow_symlinks: bool = True
3106 If False, and the last element of the path is a symbolic link,
3107 stat will examine the symbolic link itself instead of the file
3108 the link points to.
3109
3110Change the owner and group id of path to the numeric uid and gid.\
3111
3112path may always be specified as a string.
3113On some platforms, path may also be specified as an open file descriptor.
3114 If this functionality is unavailable, using it raises an exception.
3115If dir_fd is not None, it should be a file descriptor open to a directory,
3116 and path should be relative; path will then be relative to that directory.
3117If follow_symlinks is False, and the last element of the path is a symbolic
3118 link, chown will modify the symbolic link itself instead of the file the
3119 link points to.
3120It is an error to use dir_fd or follow_symlinks when specifying path as
3121 an open file descriptor.
3122dir_fd and follow_symlinks may not be implemented on your platform.
3123 If they are unavailable, using them will raise a NotImplementedError.
3124
3125[clinic start generated code]*/
3126
Larry Hastings2f936352014-08-05 14:04:04 +10003127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003128os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003129 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003130/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003131{
3132 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003133
3134#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3135 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003136 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003138 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3139 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141
3142#ifdef __APPLE__
3143 /*
3144 * This is for Mac OS X 10.3, which doesn't have lchown.
3145 * (But we still have an lchown symbol because of weak-linking.)
3146 * It doesn't have fchownat either. So there's no possibility
3147 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003148 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003149 if ((!follow_symlinks) && (lchown == NULL)) {
3150 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003151 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003152 }
3153#endif
3154
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003157 if (path->fd != -1)
3158 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159 else
3160#endif
3161#ifdef HAVE_LCHOWN
3162 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003163 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003164 else
3165#endif
3166#ifdef HAVE_FCHOWNAT
3167 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003168 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3170 else
3171#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003172 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174
Larry Hastings2f936352014-08-05 14:04:04 +10003175 if (result)
3176 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177
Larry Hastings2f936352014-08-05 14:04:04 +10003178 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003179}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003180#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003181
Larry Hastings2f936352014-08-05 14:04:04 +10003182
Christian Heimes4e30a842007-11-30 22:12:06 +00003183#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003184/*[clinic input]
3185os.fchown
3186
3187 fd: int
3188 uid: uid_t
3189 gid: gid_t
3190
3191Change the owner and group id of the file specified by file descriptor.
3192
3193Equivalent to os.chown(fd, uid, gid).
3194
3195[clinic start generated code]*/
3196
Larry Hastings2f936352014-08-05 14:04:04 +10003197static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003198os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3199/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003200{
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003202 int async_err = 0;
3203
3204 do {
3205 Py_BEGIN_ALLOW_THREADS
3206 res = fchown(fd, uid, gid);
3207 Py_END_ALLOW_THREADS
3208 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3209 if (res != 0)
3210 return (!async_err) ? posix_error() : NULL;
3211
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003213}
3214#endif /* HAVE_FCHOWN */
3215
Larry Hastings2f936352014-08-05 14:04:04 +10003216
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003217#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003218/*[clinic input]
3219os.lchown
3220
3221 path : path_t
3222 uid: uid_t
3223 gid: gid_t
3224
3225Change the owner and group id of path to the numeric uid and gid.
3226
3227This function will not follow symbolic links.
3228Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3229[clinic start generated code]*/
3230
Larry Hastings2f936352014-08-05 14:04:04 +10003231static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003232os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3233/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003234{
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003237 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003238 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003239 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003240 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003241 }
Larry Hastings2f936352014-08-05 14:04:04 +10003242 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003243}
3244#endif /* HAVE_LCHOWN */
3245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003246
Barry Warsaw53699e91996-12-10 23:23:01 +00003247static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003248posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003249{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003250 char *buf, *tmpbuf;
3251 char *cwd;
3252 const size_t chunk = 1024;
3253 size_t buflen = 0;
3254 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003255
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003256#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003258 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 wchar_t *wbuf2 = wbuf;
3260 PyObject *resobj;
3261 DWORD len;
3262 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003263 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 /* If the buffer is large enough, len does not include the
3265 terminating \0. If the buffer is too small, len includes
3266 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003267 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003268 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 if (wbuf2)
3270 len = GetCurrentDirectoryW(len, wbuf2);
3271 }
3272 Py_END_ALLOW_THREADS
3273 if (!wbuf2) {
3274 PyErr_NoMemory();
3275 return NULL;
3276 }
3277 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003278 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003279 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003280 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 }
3282 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003283 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003284 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 return resobj;
3286 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003287
3288 if (win32_warn_bytes_api())
3289 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003290#endif
3291
Victor Stinner4403d7d2015-04-25 00:16:10 +02003292 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003294 do {
3295 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003296#ifdef MS_WINDOWS
3297 if (buflen > INT_MAX) {
3298 PyErr_NoMemory();
3299 break;
3300 }
3301#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003302 tmpbuf = PyMem_RawRealloc(buf, buflen);
3303 if (tmpbuf == NULL)
3304 break;
3305
3306 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003307#ifdef MS_WINDOWS
3308 cwd = getcwd(buf, (int)buflen);
3309#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003310 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003311#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003312 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003314
3315 if (cwd == NULL) {
3316 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003317 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003318 }
3319
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003321 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3322 else
3323 obj = PyUnicode_DecodeFSDefault(buf);
3324 PyMem_RawFree(buf);
3325
3326 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003327}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003328
Larry Hastings2f936352014-08-05 14:04:04 +10003329
3330/*[clinic input]
3331os.getcwd
3332
3333Return a unicode string representing the current working directory.
3334[clinic start generated code]*/
3335
Larry Hastings2f936352014-08-05 14:04:04 +10003336static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003337os_getcwd_impl(PyObject *module)
3338/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003339{
3340 return posix_getcwd(0);
3341}
3342
Larry Hastings2f936352014-08-05 14:04:04 +10003343
3344/*[clinic input]
3345os.getcwdb
3346
3347Return a bytes string representing the current working directory.
3348[clinic start generated code]*/
3349
Larry Hastings2f936352014-08-05 14:04:04 +10003350static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003351os_getcwdb_impl(PyObject *module)
3352/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003353{
3354 return posix_getcwd(1);
3355}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003356
Larry Hastings2f936352014-08-05 14:04:04 +10003357
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3359#define HAVE_LINK 1
3360#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
Guido van Rossumb6775db1994-08-01 11:34:53 +00003362#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003363/*[clinic input]
3364
3365os.link
3366
3367 src : path_t
3368 dst : path_t
3369 *
3370 src_dir_fd : dir_fd = None
3371 dst_dir_fd : dir_fd = None
3372 follow_symlinks: bool = True
3373
3374Create a hard link to a file.
3375
3376If either src_dir_fd or dst_dir_fd is not None, it should be a file
3377 descriptor open to a directory, and the respective path string (src or dst)
3378 should be relative; the path will then be relative to that directory.
3379If follow_symlinks is False, and the last element of src is a symbolic
3380 link, link will create a link to the symbolic link itself instead of the
3381 file the link points to.
3382src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3383 platform. If they are unavailable, using them will raise a
3384 NotImplementedError.
3385[clinic start generated code]*/
3386
Larry Hastings2f936352014-08-05 14:04:04 +10003387static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003388os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003389 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003390/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003391{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003393 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394#else
3395 int result;
3396#endif
3397
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398#ifndef HAVE_LINKAT
3399 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3400 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003401 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402 }
3403#endif
3404
Steve Dowercc16be82016-09-08 10:35:16 -07003405#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003406 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407 PyErr_SetString(PyExc_NotImplementedError,
3408 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003409 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410 }
Steve Dowercc16be82016-09-08 10:35:16 -07003411#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003412
Brian Curtin1b9df392010-11-24 20:24:31 +00003413#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08003415 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003417
Larry Hastings2f936352014-08-05 14:04:04 +10003418 if (!result)
3419 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420#else
3421 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003422#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3424 (dst_dir_fd != DEFAULT_DIR_FD) ||
3425 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003426 result = linkat(src_dir_fd, src->narrow,
3427 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3429 else
Steve Dowercc16be82016-09-08 10:35:16 -07003430#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003431 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if (result)
3435 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003436#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437
Larry Hastings2f936352014-08-05 14:04:04 +10003438 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003439}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440#endif
3441
Brian Curtin1b9df392010-11-24 20:24:31 +00003442
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003443#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003444static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003446{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447 PyObject *v;
3448 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3449 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003450 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003452 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454
Steve Dowercc16be82016-09-08 10:35:16 -07003455 WIN32_FIND_DATAW wFileData;
3456 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003457
Steve Dowercc16be82016-09-08 10:35:16 -07003458 if (!path->wide) { /* Default arg: "." */
3459 po_wchars = L".";
3460 len = 1;
3461 } else {
3462 po_wchars = path->wide;
3463 len = wcslen(path->wide);
3464 }
3465 /* The +5 is so we can append "\\*.*\0" */
3466 wnamebuf = PyMem_New(wchar_t, len + 5);
3467 if (!wnamebuf) {
3468 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 }
Steve Dowercc16be82016-09-08 10:35:16 -07003471 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003473 wchar_t wch = wnamebuf[len-1];
3474 if (wch != SEP && wch != ALTSEP && wch != L':')
3475 wnamebuf[len++] = SEP;
3476 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 }
Steve Dowercc16be82016-09-08 10:35:16 -07003478 if ((list = PyList_New(0)) == NULL) {
3479 goto exit;
3480 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003481 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003482 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003483 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 if (hFindFile == INVALID_HANDLE_VALUE) {
3485 int error = GetLastError();
3486 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 goto exit;
3488 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003489 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 }
3492 do {
3493 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003494 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3495 wcscmp(wFileData.cFileName, L"..") != 0) {
3496 v = PyUnicode_FromWideChar(wFileData.cFileName,
3497 wcslen(wFileData.cFileName));
3498 if (path->narrow && v) {
3499 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3500 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_DECREF(list);
3503 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 break;
3505 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 Py_DECREF(list);
3509 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 break;
3511 }
3512 Py_DECREF(v);
3513 }
3514 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003515 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 Py_END_ALLOW_THREADS
3517 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3518 it got to the end of the directory. */
3519 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003521 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
3524 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003525
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526exit:
3527 if (hFindFile != INVALID_HANDLE_VALUE) {
3528 if (FindClose(hFindFile) == FALSE) {
3529 if (list != NULL) {
3530 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 }
3533 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003535 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003536
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003538} /* end of _listdir_windows_no_opendir */
3539
3540#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3541
3542static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003543_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003544{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003545 PyObject *v;
3546 DIR *dirp = NULL;
3547 struct dirent *ep;
3548 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003549#ifdef HAVE_FDOPENDIR
3550 int fd = -1;
3551#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003552
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003555 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003557 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003558 if (fd == -1)
3559 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560
Larry Hastingsfdaea062012-06-25 04:42:23 -07003561 return_str = 1;
3562
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_BEGIN_ALLOW_THREADS
3564 dirp = fdopendir(fd);
3565 Py_END_ALLOW_THREADS
3566 }
3567 else
3568#endif
3569 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003570 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003571 if (path->narrow) {
3572 name = path->narrow;
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +03003573 /* only return bytes if they specified a bytes-like object */
3574 return_str = !PyObject_CheckBuffer(path->object);
Larry Hastingsfdaea062012-06-25 04:42:23 -07003575 }
3576 else {
3577 name = ".";
3578 return_str = 1;
3579 }
3580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 Py_BEGIN_ALLOW_THREADS
3582 dirp = opendir(name);
3583 Py_END_ALLOW_THREADS
3584 }
3585
3586 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003587 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003588#ifdef HAVE_FDOPENDIR
3589 if (fd != -1) {
3590 Py_BEGIN_ALLOW_THREADS
3591 close(fd);
3592 Py_END_ALLOW_THREADS
3593 }
3594#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595 goto exit;
3596 }
3597 if ((list = PyList_New(0)) == NULL) {
3598 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 }
3600 for (;;) {
3601 errno = 0;
3602 Py_BEGIN_ALLOW_THREADS
3603 ep = readdir(dirp);
3604 Py_END_ALLOW_THREADS
3605 if (ep == NULL) {
3606 if (errno == 0) {
3607 break;
3608 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 }
3613 }
3614 if (ep->d_name[0] == '.' &&
3615 (NAMLEN(ep) == 1 ||
3616 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3617 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003618 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003619 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3620 else
3621 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 break;
3625 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 break;
3630 }
3631 Py_DECREF(v);
3632 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003633
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634exit:
3635 if (dirp != NULL) {
3636 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003637#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 if (fd > -1)
3639 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003640#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003641 closedir(dirp);
3642 Py_END_ALLOW_THREADS
3643 }
3644
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003646} /* end of _posix_listdir */
3647#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003648
Larry Hastings2f936352014-08-05 14:04:04 +10003649
3650/*[clinic input]
3651os.listdir
3652
3653 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3654
3655Return a list containing the names of the files in the directory.
3656
3657path can be specified as either str or bytes. If path is bytes,
3658 the filenames returned will also be bytes; in all other circumstances
3659 the filenames returned will be str.
3660If path is None, uses the path='.'.
3661On some platforms, path may also be specified as an open file descriptor;\
3662 the file descriptor must refer to a directory.
3663 If this functionality is unavailable, using it raises NotImplementedError.
3664
3665The list is in arbitrary order. It does not include the special
3666entries '.' and '..' even if they are present in the directory.
3667
3668
3669[clinic start generated code]*/
3670
Larry Hastings2f936352014-08-05 14:04:04 +10003671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003672os_listdir_impl(PyObject *module, path_t *path)
3673/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003674{
3675#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3676 return _listdir_windows_no_opendir(path, NULL);
3677#else
3678 return _posix_listdir(path, NULL);
3679#endif
3680}
3681
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003682#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003683/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003684/*[clinic input]
3685os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003686
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003687 path: path_t
3688 /
3689
3690[clinic start generated code]*/
3691
3692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003693os__getfullpathname_impl(PyObject *module, path_t *path)
3694/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003695{
Steve Dowercc16be82016-09-08 10:35:16 -07003696 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3697 wchar_t *wtemp;
3698 DWORD result;
3699 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003700
Steve Dowercc16be82016-09-08 10:35:16 -07003701 result = GetFullPathNameW(path->wide,
3702 Py_ARRAY_LENGTH(woutbuf),
3703 woutbuf, &wtemp);
3704 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3705 woutbufp = PyMem_New(wchar_t, result);
3706 if (!woutbufp)
3707 return PyErr_NoMemory();
3708 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 }
Steve Dowercc16be82016-09-08 10:35:16 -07003710 if (result) {
3711 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3712 if (path->narrow)
3713 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3714 } else
3715 v = win32_error_object("GetFullPathNameW", path->object);
3716 if (woutbufp != woutbuf)
3717 PyMem_Free(woutbufp);
3718 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003719}
Brian Curtind40e6f72010-07-08 21:39:08 +00003720
Brian Curtind25aef52011-06-13 15:16:04 -05003721
Larry Hastings2f936352014-08-05 14:04:04 +10003722/*[clinic input]
3723os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003724
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003725 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003726 /
3727
3728A helper function for samepath on windows.
3729[clinic start generated code]*/
3730
Larry Hastings2f936352014-08-05 14:04:04 +10003731static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003732os__getfinalpathname_impl(PyObject *module, path_t *path)
3733/*[clinic end generated code: output=621a3c79bc29ebfa input=2b6b6c7cbad5fb84]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003734{
3735 HANDLE hFile;
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003736 wchar_t buf[MAXPATHLEN], *target_path = buf;
3737 int buf_size = Py_ARRAY_LENGTH(buf);
Brian Curtind40e6f72010-07-08 21:39:08 +00003738 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003739 PyObject *result;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003740
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003741 Py_BEGIN_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003742 hFile = CreateFileW(
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003743 path->wide,
Brian Curtind40e6f72010-07-08 21:39:08 +00003744 0, /* desired access */
3745 0, /* share mode */
3746 NULL, /* security attributes */
3747 OPEN_EXISTING,
3748 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3749 FILE_FLAG_BACKUP_SEMANTICS,
3750 NULL);
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003751 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003752
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003753 if (hFile == INVALID_HANDLE_VALUE) {
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003754 return win32_error_object("CreateFileW", path->object);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003755 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003756
3757 /* We have a good handle to the target, use it to determine the
3758 target path name. */
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003759 while (1) {
3760 Py_BEGIN_ALLOW_THREADS
3761 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3762 buf_size, VOLUME_NAME_DOS);
3763 Py_END_ALLOW_THREADS
Brian Curtind40e6f72010-07-08 21:39:08 +00003764
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003765 if (!result_length) {
3766 result = win32_error_object("GetFinalPathNameByHandleW",
3767 path->object);
3768 goto cleanup;
3769 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003770
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003771 if (result_length < buf_size) {
3772 break;
3773 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003774
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003775 wchar_t *tmp;
3776 tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3777 result_length * sizeof(*tmp));
3778 if (!tmp) {
3779 result = PyErr_NoMemory();
3780 goto cleanup;
3781 }
3782
3783 buf_size = result_length;
3784 target_path = tmp;
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003785 }
Brian Curtind40e6f72010-07-08 21:39:08 +00003786
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003787 result = PyUnicode_FromWideChar(target_path, result_length);
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003788 if (path->narrow)
3789 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003790
Miss Islington (bot)8c163bb2018-03-08 08:26:43 -08003791cleanup:
3792 if (target_path != buf) {
3793 PyMem_Free(target_path);
3794 }
3795 CloseHandle(hFile);
3796 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003797}
Brian Curtin62857742010-09-06 17:07:27 +00003798
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003799/*[clinic input]
3800os._isdir
3801
3802 path: path_t
3803 /
3804
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003805Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003806[clinic start generated code]*/
3807
Brian Curtin9c669cc2011-06-08 18:17:18 -05003808static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003809os__isdir_impl(PyObject *module, path_t *path)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003810/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003811{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003812 DWORD attributes;
3813
Steve Dowerb22a6772016-07-17 20:49:38 -07003814 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003815 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003816 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003817
Brian Curtin9c669cc2011-06-08 18:17:18 -05003818 if (attributes == INVALID_FILE_ATTRIBUTES)
3819 Py_RETURN_FALSE;
3820
Brian Curtin9c669cc2011-06-08 18:17:18 -05003821 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3822 Py_RETURN_TRUE;
3823 else
3824 Py_RETURN_FALSE;
3825}
Tim Golden6b528062013-08-01 12:44:00 +01003826
Tim Golden6b528062013-08-01 12:44:00 +01003827
Larry Hastings2f936352014-08-05 14:04:04 +10003828/*[clinic input]
3829os._getvolumepathname
3830
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003831 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10003832
3833A helper function for ismount on Win32.
3834[clinic start generated code]*/
3835
Larry Hastings2f936352014-08-05 14:04:04 +10003836static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003837os__getvolumepathname_impl(PyObject *module, path_t *path)
3838/*[clinic end generated code: output=804c63fd13a1330b input=722b40565fa21552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003839{
3840 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003841 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003842 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003843 BOOL ret;
3844
Tim Golden6b528062013-08-01 12:44:00 +01003845 /* Volume path should be shorter than entire path */
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003846 buflen = Py_MAX(path->length, MAX_PATH);
Victor Stinner6edddfa2013-11-24 19:22:57 +01003847
Victor Stinner850a18e2017-10-24 16:53:32 -07003848 if (buflen > PY_DWORD_MAX) {
Victor Stinner6edddfa2013-11-24 19:22:57 +01003849 PyErr_SetString(PyExc_OverflowError, "path too long");
3850 return NULL;
3851 }
3852
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003853 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003854 if (mountpath == NULL)
3855 return PyErr_NoMemory();
3856
3857 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003858 ret = GetVolumePathNameW(path->wide, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003859 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003860 Py_END_ALLOW_THREADS
3861
3862 if (!ret) {
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003863 result = win32_error_object("_getvolumepathname", path->object);
Tim Golden6b528062013-08-01 12:44:00 +01003864 goto exit;
3865 }
3866 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08003867 if (path->narrow)
3868 Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
Tim Golden6b528062013-08-01 12:44:00 +01003869
3870exit:
3871 PyMem_Free(mountpath);
3872 return result;
3873}
Tim Golden6b528062013-08-01 12:44:00 +01003874
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003875#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003876
Larry Hastings2f936352014-08-05 14:04:04 +10003877
3878/*[clinic input]
3879os.mkdir
3880
3881 path : path_t
3882
3883 mode: int = 0o777
3884
3885 *
3886
3887 dir_fd : dir_fd(requires='mkdirat') = None
3888
3889# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3890
3891Create a directory.
3892
3893If dir_fd is not None, it should be a file descriptor open to a directory,
3894 and path should be relative; path will then be relative to that directory.
3895dir_fd may not be implemented on your platform.
3896 If it is unavailable, using it will raise a NotImplementedError.
3897
3898The mode argument is ignored on Windows.
3899[clinic start generated code]*/
3900
Larry Hastings2f936352014-08-05 14:04:04 +10003901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003902os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3903/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003904{
3905 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003906
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003907#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003909 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003911
Larry Hastings2f936352014-08-05 14:04:04 +10003912 if (!result)
3913 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003914#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003916#if HAVE_MKDIRAT
3917 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003918 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003919 else
3920#endif
Erik Bray03eb11f2017-10-27 14:27:06 +02003921#if defined(__WATCOMC__) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003922 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003923#else
Larry Hastings2f936352014-08-05 14:04:04 +10003924 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003925#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003927 if (result < 0)
3928 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003929#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003930 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003931}
3932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003933
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003934/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3935#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003936#include <sys/resource.h>
3937#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003938
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003939
3940#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003941/*[clinic input]
3942os.nice
3943
3944 increment: int
3945 /
3946
3947Add increment to the priority of process and return the new priority.
3948[clinic start generated code]*/
3949
Larry Hastings2f936352014-08-05 14:04:04 +10003950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003951os_nice_impl(PyObject *module, int increment)
3952/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003953{
3954 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003955
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 /* There are two flavours of 'nice': one that returns the new
3957 priority (as required by almost all standards out there) and the
Benjamin Peterson288d1da2017-09-28 22:44:27 -07003958 Linux/FreeBSD one, which returns '0' on success and advices
Victor Stinner8c62be82010-05-06 00:08:46 +00003959 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003960
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 If we are of the nice family that returns the new priority, we
3962 need to clear errno before the call, and check if errno is filled
3963 before calling posix_error() on a returnvalue of -1, because the
3964 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003965
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 errno = 0;
3967 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003968#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003969 if (value == 0)
3970 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003971#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003972 if (value == -1 && errno != 0)
3973 /* either nice() or getpriority() returned an error */
3974 return posix_error();
3975 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003976}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003977#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003978
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003979
3980#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003981/*[clinic input]
3982os.getpriority
3983
3984 which: int
3985 who: int
3986
3987Return program scheduling priority.
3988[clinic start generated code]*/
3989
Larry Hastings2f936352014-08-05 14:04:04 +10003990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003991os_getpriority_impl(PyObject *module, int which, int who)
3992/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003993{
3994 int retval;
3995
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003996 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003997 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003998 if (errno != 0)
3999 return posix_error();
4000 return PyLong_FromLong((long)retval);
4001}
4002#endif /* HAVE_GETPRIORITY */
4003
4004
4005#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004006/*[clinic input]
4007os.setpriority
4008
4009 which: int
4010 who: int
4011 priority: int
4012
4013Set program scheduling priority.
4014[clinic start generated code]*/
4015
Larry Hastings2f936352014-08-05 14:04:04 +10004016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004017os_setpriority_impl(PyObject *module, int which, int who, int priority)
4018/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004019{
4020 int retval;
4021
4022 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004023 if (retval == -1)
4024 return posix_error();
4025 Py_RETURN_NONE;
4026}
4027#endif /* HAVE_SETPRIORITY */
4028
4029
Barry Warsaw53699e91996-12-10 23:23:01 +00004030static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004031internal_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 +00004032{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004033 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004034 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004035
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004036#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004037 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004038 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004039#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004040 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004041#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042
Larry Hastings9cf065c2012-06-22 16:30:09 -07004043 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4044 (dst_dir_fd != DEFAULT_DIR_FD);
4045#ifndef HAVE_RENAMEAT
4046 if (dir_fd_specified) {
4047 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004048 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049 }
4050#endif
4051
Larry Hastings9cf065c2012-06-22 16:30:09 -07004052#ifdef MS_WINDOWS
4053 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004054 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055 Py_END_ALLOW_THREADS
4056
Larry Hastings2f936352014-08-05 14:04:04 +10004057 if (!result)
4058 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004059
4060#else
Steve Dowercc16be82016-09-08 10:35:16 -07004061 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4062 PyErr_Format(PyExc_ValueError,
4063 "%s: src and dst must be the same type", function_name);
4064 return NULL;
4065 }
4066
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 Py_BEGIN_ALLOW_THREADS
4068#ifdef HAVE_RENAMEAT
4069 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004070 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071 else
4072#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004073 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074 Py_END_ALLOW_THREADS
4075
Larry Hastings2f936352014-08-05 14:04:04 +10004076 if (result)
4077 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004079 Py_RETURN_NONE;
4080}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081
Larry Hastings2f936352014-08-05 14:04:04 +10004082
4083/*[clinic input]
4084os.rename
4085
4086 src : path_t
4087 dst : path_t
4088 *
4089 src_dir_fd : dir_fd = None
4090 dst_dir_fd : dir_fd = None
4091
4092Rename a file or directory.
4093
4094If either src_dir_fd or dst_dir_fd is not None, it should be a file
4095 descriptor open to a directory, and the respective path string (src or dst)
4096 should be relative; the path will then be relative to that directory.
4097src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4098 If they are unavailable, using them will raise a NotImplementedError.
4099[clinic start generated code]*/
4100
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004102os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004103 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004104/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004105{
Larry Hastings2f936352014-08-05 14:04:04 +10004106 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004107}
4108
Larry Hastings2f936352014-08-05 14:04:04 +10004109
4110/*[clinic input]
4111os.replace = os.rename
4112
4113Rename a file or directory, overwriting the destination.
4114
4115If either src_dir_fd or dst_dir_fd is not None, it should be a file
4116 descriptor open to a directory, and the respective path string (src or dst)
4117 should be relative; the path will then be relative to that directory.
4118src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4119 If they are unavailable, using them will raise a NotImplementedError."
4120[clinic start generated code]*/
4121
Larry Hastings2f936352014-08-05 14:04:04 +10004122static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004123os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4124 int dst_dir_fd)
4125/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004126{
4127 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4128}
4129
4130
4131/*[clinic input]
4132os.rmdir
4133
4134 path: path_t
4135 *
4136 dir_fd: dir_fd(requires='unlinkat') = None
4137
4138Remove a directory.
4139
4140If dir_fd is not None, it should be a file descriptor open to a directory,
4141 and path should be relative; path will then be relative to that directory.
4142dir_fd may not be implemented on your platform.
4143 If it is unavailable, using it will raise a NotImplementedError.
4144[clinic start generated code]*/
4145
Larry Hastings2f936352014-08-05 14:04:04 +10004146static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004147os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4148/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004149{
4150 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004151
4152 Py_BEGIN_ALLOW_THREADS
4153#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004154 /* Windows, success=1, UNIX, success=0 */
4155 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004156#else
4157#ifdef HAVE_UNLINKAT
4158 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004159 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004160 else
4161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004162 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004163#endif
4164 Py_END_ALLOW_THREADS
4165
Larry Hastings2f936352014-08-05 14:04:04 +10004166 if (result)
4167 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004168
Larry Hastings2f936352014-08-05 14:04:04 +10004169 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004170}
4171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004172
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004173#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004174#ifdef MS_WINDOWS
4175/*[clinic input]
4176os.system -> long
4177
4178 command: Py_UNICODE
4179
4180Execute the command in a subshell.
4181[clinic start generated code]*/
4182
Larry Hastings2f936352014-08-05 14:04:04 +10004183static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004184os_system_impl(PyObject *module, Py_UNICODE *command)
4185/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004186{
4187 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08004189 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10004190 result = _wsystem(command);
Steve Dowerc3630612016-11-19 18:41:16 -08004191 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004193 return result;
4194}
4195#else /* MS_WINDOWS */
4196/*[clinic input]
4197os.system -> long
4198
4199 command: FSConverter
4200
4201Execute the command in a subshell.
4202[clinic start generated code]*/
4203
Larry Hastings2f936352014-08-05 14:04:04 +10004204static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004205os_system_impl(PyObject *module, PyObject *command)
4206/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004207{
4208 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004209 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004210 Py_BEGIN_ALLOW_THREADS
4211 result = system(bytes);
4212 Py_END_ALLOW_THREADS
4213 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004214}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004215#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004216#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004218
Larry Hastings2f936352014-08-05 14:04:04 +10004219/*[clinic input]
4220os.umask
4221
4222 mask: int
4223 /
4224
4225Set the current numeric umask and return the previous umask.
4226[clinic start generated code]*/
4227
Larry Hastings2f936352014-08-05 14:04:04 +10004228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004229os_umask_impl(PyObject *module, int mask)
4230/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004231{
4232 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 if (i < 0)
4234 return posix_error();
4235 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004236}
4237
Brian Curtind40e6f72010-07-08 21:39:08 +00004238#ifdef MS_WINDOWS
4239
4240/* override the default DeleteFileW behavior so that directory
4241symlinks can be removed with this function, the same as with
4242Unix symlinks */
4243BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4244{
4245 WIN32_FILE_ATTRIBUTE_DATA info;
4246 WIN32_FIND_DATAW find_data;
4247 HANDLE find_data_handle;
4248 int is_directory = 0;
4249 int is_link = 0;
4250
4251 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4252 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004253
Brian Curtind40e6f72010-07-08 21:39:08 +00004254 /* Get WIN32_FIND_DATA structure for the path to determine if
4255 it is a symlink */
4256 if(is_directory &&
4257 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4258 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4259
4260 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004261 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4262 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4263 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4264 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004265 FindClose(find_data_handle);
4266 }
4267 }
4268 }
4269
4270 if (is_directory && is_link)
4271 return RemoveDirectoryW(lpFileName);
4272
4273 return DeleteFileW(lpFileName);
4274}
4275#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004277
Larry Hastings2f936352014-08-05 14:04:04 +10004278/*[clinic input]
4279os.unlink
4280
4281 path: path_t
4282 *
4283 dir_fd: dir_fd(requires='unlinkat')=None
4284
4285Remove a file (same as remove()).
4286
4287If dir_fd is not None, it should be a file descriptor open to a directory,
4288 and path should be relative; path will then be relative to that directory.
4289dir_fd may not be implemented on your platform.
4290 If it is unavailable, using it will raise a NotImplementedError.
4291
4292[clinic start generated code]*/
4293
Larry Hastings2f936352014-08-05 14:04:04 +10004294static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004295os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4296/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004297{
4298 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004299
4300 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004301 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004302#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004303 /* Windows, success=1, UNIX, success=0 */
4304 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004305#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306#ifdef HAVE_UNLINKAT
4307 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004308 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004309 else
4310#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004311 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004313 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004314 Py_END_ALLOW_THREADS
4315
Larry Hastings2f936352014-08-05 14:04:04 +10004316 if (result)
4317 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318
Larry Hastings2f936352014-08-05 14:04:04 +10004319 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004320}
4321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004322
Larry Hastings2f936352014-08-05 14:04:04 +10004323/*[clinic input]
4324os.remove = os.unlink
4325
4326Remove a file (same as unlink()).
4327
4328If dir_fd is not None, it should be a file descriptor open to a directory,
4329 and path should be relative; path will then be relative to that directory.
4330dir_fd may not be implemented on your platform.
4331 If it is unavailable, using it will raise a NotImplementedError.
4332[clinic start generated code]*/
4333
Larry Hastings2f936352014-08-05 14:04:04 +10004334static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004335os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4336/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004337{
4338 return os_unlink_impl(module, path, dir_fd);
4339}
4340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004341
Larry Hastings605a62d2012-06-24 04:33:36 -07004342static PyStructSequence_Field uname_result_fields[] = {
4343 {"sysname", "operating system name"},
4344 {"nodename", "name of machine on network (implementation-defined)"},
4345 {"release", "operating system release"},
4346 {"version", "operating system version"},
4347 {"machine", "hardware identifier"},
4348 {NULL}
4349};
4350
4351PyDoc_STRVAR(uname_result__doc__,
4352"uname_result: Result from os.uname().\n\n\
4353This object may be accessed either as a tuple of\n\
4354 (sysname, nodename, release, version, machine),\n\
4355or via the attributes sysname, nodename, release, version, and machine.\n\
4356\n\
4357See os.uname for more information.");
4358
4359static PyStructSequence_Desc uname_result_desc = {
4360 "uname_result", /* name */
4361 uname_result__doc__, /* doc */
4362 uname_result_fields,
4363 5
4364};
4365
4366static PyTypeObject UnameResultType;
4367
4368
4369#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004370/*[clinic input]
4371os.uname
4372
4373Return an object identifying the current operating system.
4374
4375The object behaves like a named tuple with the following fields:
4376 (sysname, nodename, release, version, machine)
4377
4378[clinic start generated code]*/
4379
Larry Hastings2f936352014-08-05 14:04:04 +10004380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004381os_uname_impl(PyObject *module)
4382/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004383{
Victor Stinner8c62be82010-05-06 00:08:46 +00004384 struct utsname u;
4385 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004386 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004387
Victor Stinner8c62be82010-05-06 00:08:46 +00004388 Py_BEGIN_ALLOW_THREADS
4389 res = uname(&u);
4390 Py_END_ALLOW_THREADS
4391 if (res < 0)
4392 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004393
4394 value = PyStructSequence_New(&UnameResultType);
4395 if (value == NULL)
4396 return NULL;
4397
4398#define SET(i, field) \
4399 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004400 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004401 if (!o) { \
4402 Py_DECREF(value); \
4403 return NULL; \
4404 } \
4405 PyStructSequence_SET_ITEM(value, i, o); \
4406 } \
4407
4408 SET(0, u.sysname);
4409 SET(1, u.nodename);
4410 SET(2, u.release);
4411 SET(3, u.version);
4412 SET(4, u.machine);
4413
4414#undef SET
4415
4416 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004417}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004418#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004419
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004420
Larry Hastings9cf065c2012-06-22 16:30:09 -07004421
4422typedef struct {
4423 int now;
4424 time_t atime_s;
4425 long atime_ns;
4426 time_t mtime_s;
4427 long mtime_ns;
4428} utime_t;
4429
4430/*
Victor Stinner484df002014-10-09 13:52:31 +02004431 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432 * they also intentionally leak the declaration of a pointer named "time"
4433 */
4434#define UTIME_TO_TIMESPEC \
4435 struct timespec ts[2]; \
4436 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004437 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438 time = NULL; \
4439 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004440 ts[0].tv_sec = ut->atime_s; \
4441 ts[0].tv_nsec = ut->atime_ns; \
4442 ts[1].tv_sec = ut->mtime_s; \
4443 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 time = ts; \
4445 } \
4446
4447#define UTIME_TO_TIMEVAL \
4448 struct timeval tv[2]; \
4449 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004450 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451 time = NULL; \
4452 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004453 tv[0].tv_sec = ut->atime_s; \
4454 tv[0].tv_usec = ut->atime_ns / 1000; \
4455 tv[1].tv_sec = ut->mtime_s; \
4456 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457 time = tv; \
4458 } \
4459
4460#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004461 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004462 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004463 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004464 time = NULL; \
4465 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004466 u.actime = ut->atime_s; \
4467 u.modtime = ut->mtime_s; \
4468 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469 }
4470
4471#define UTIME_TO_TIME_T \
4472 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004473 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004474 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475 time = NULL; \
4476 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004477 timet[0] = ut->atime_s; \
4478 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004479 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480 } \
4481
4482
Victor Stinner528a9ab2015-09-03 21:30:26 +02004483#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484
4485static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004486utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487{
4488#ifdef HAVE_UTIMENSAT
4489 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4490 UTIME_TO_TIMESPEC;
4491 return utimensat(dir_fd, path, time, flags);
4492#elif defined(HAVE_FUTIMESAT)
4493 UTIME_TO_TIMEVAL;
4494 /*
4495 * follow_symlinks will never be false here;
4496 * we only allow !follow_symlinks and dir_fd together
4497 * if we have utimensat()
4498 */
4499 assert(follow_symlinks);
4500 return futimesat(dir_fd, path, time);
4501#endif
4502}
4503
Larry Hastings2f936352014-08-05 14:04:04 +10004504 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4505#else
4506 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004507#endif
4508
Victor Stinner528a9ab2015-09-03 21:30:26 +02004509#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510
4511static int
Victor Stinner484df002014-10-09 13:52:31 +02004512utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513{
4514#ifdef HAVE_FUTIMENS
4515 UTIME_TO_TIMESPEC;
4516 return futimens(fd, time);
4517#else
4518 UTIME_TO_TIMEVAL;
4519 return futimes(fd, time);
4520#endif
4521}
4522
Larry Hastings2f936352014-08-05 14:04:04 +10004523 #define PATH_UTIME_HAVE_FD 1
4524#else
4525 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526#endif
4527
Victor Stinner5ebae872015-09-22 01:29:33 +02004528#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4529# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4530#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531
Victor Stinner4552ced2015-09-21 22:37:15 +02004532#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533
4534static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004535utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536{
4537#ifdef HAVE_UTIMENSAT
4538 UTIME_TO_TIMESPEC;
4539 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4540#else
4541 UTIME_TO_TIMEVAL;
4542 return lutimes(path, time);
4543#endif
4544}
4545
4546#endif
4547
4548#ifndef MS_WINDOWS
4549
4550static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004551utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552{
4553#ifdef HAVE_UTIMENSAT
4554 UTIME_TO_TIMESPEC;
4555 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4556#elif defined(HAVE_UTIMES)
4557 UTIME_TO_TIMEVAL;
4558 return utimes(path, time);
4559#elif defined(HAVE_UTIME_H)
4560 UTIME_TO_UTIMBUF;
4561 return utime(path, time);
4562#else
4563 UTIME_TO_TIME_T;
4564 return utime(path, time);
4565#endif
4566}
4567
4568#endif
4569
Larry Hastings76ad59b2012-05-03 00:30:07 -07004570static int
4571split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4572{
4573 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004574 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004575 divmod = PyNumber_Divmod(py_long, billion);
4576 if (!divmod)
4577 goto exit;
Miss Islington (bot)329ea4e2018-09-12 12:46:30 -07004578 if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) {
4579 PyErr_Format(PyExc_TypeError,
4580 "%.200s.__divmod__() must return a 2-tuple, not %.200s",
4581 Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name);
4582 goto exit;
4583 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004584 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4585 if ((*s == -1) && PyErr_Occurred())
4586 goto exit;
4587 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004588 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004589 goto exit;
4590
4591 result = 1;
4592exit:
4593 Py_XDECREF(divmod);
4594 return result;
4595}
4596
Larry Hastings2f936352014-08-05 14:04:04 +10004597
4598/*[clinic input]
4599os.utime
4600
4601 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4602 times: object = NULL
4603 *
4604 ns: object = NULL
4605 dir_fd: dir_fd(requires='futimensat') = None
4606 follow_symlinks: bool=True
4607
Martin Panter0ff89092015-09-09 01:56:53 +00004608# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004609
4610Set the access and modified time of path.
4611
4612path may always be specified as a string.
4613On some platforms, path may also be specified as an open file descriptor.
4614 If this functionality is unavailable, using it raises an exception.
4615
4616If times is not None, it must be a tuple (atime, mtime);
4617 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004618If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004619 atime_ns and mtime_ns should be expressed as integer nanoseconds
4620 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004621If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004622Specifying tuples for both times and ns is an error.
4623
4624If dir_fd is not None, it should be a file descriptor open to a directory,
4625 and path should be relative; path will then be relative to that directory.
4626If follow_symlinks is False, and the last element of the path is a symbolic
4627 link, utime will modify the symbolic link itself instead of the file the
4628 link points to.
4629It is an error to use dir_fd or follow_symlinks when specifying path
4630 as an open file descriptor.
4631dir_fd and follow_symlinks may not be available on your platform.
4632 If they are unavailable, using them will raise a NotImplementedError.
4633
4634[clinic start generated code]*/
4635
Larry Hastings2f936352014-08-05 14:04:04 +10004636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004637os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4638 int dir_fd, int follow_symlinks)
4639/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004640{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641#ifdef MS_WINDOWS
4642 HANDLE hFile;
4643 FILETIME atime, mtime;
4644#else
4645 int result;
4646#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004647
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004649 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004650
Christian Heimesb3c87242013-08-01 00:08:16 +02004651 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004652
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653 if (times && (times != Py_None) && ns) {
4654 PyErr_SetString(PyExc_ValueError,
4655 "utime: you may specify either 'times'"
4656 " or 'ns' but not both");
4657 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004658 }
4659
4660 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004661 time_t a_sec, m_sec;
4662 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004663 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004664 PyErr_SetString(PyExc_TypeError,
4665 "utime: 'times' must be either"
4666 " a tuple of two ints or None");
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 (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004671 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004672 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004673 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004675 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004676 utime.atime_s = a_sec;
4677 utime.atime_ns = a_nsec;
4678 utime.mtime_s = m_sec;
4679 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004680 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004681 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004682 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 PyErr_SetString(PyExc_TypeError,
4684 "utime: 'ns' must be a tuple of two ints");
4685 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004686 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004688 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004690 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004691 &utime.mtime_s, &utime.mtime_ns)) {
4692 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004693 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 }
4695 else {
4696 /* times and ns are both None/unspecified. use "now". */
4697 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004698 }
4699
Victor Stinner4552ced2015-09-21 22:37:15 +02004700#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701 if (follow_symlinks_specified("utime", follow_symlinks))
4702 goto exit;
4703#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004704
Larry Hastings2f936352014-08-05 14:04:04 +10004705 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4706 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4707 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004709
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710#if !defined(HAVE_UTIMENSAT)
4711 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004712 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 "utime: cannot use dir_fd and follow_symlinks "
4714 "together on this platform");
4715 goto exit;
4716 }
4717#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004718
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004719#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004721 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4722 NULL, OPEN_EXISTING,
4723 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004724 Py_END_ALLOW_THREADS
4725 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004726 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004728 }
4729
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004731 GetSystemTimeAsFileTime(&mtime);
4732 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004735 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4736 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004737 }
4738 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4739 /* Avoid putting the file name into the error here,
4740 as that may confuse the user into believing that
4741 something is wrong with the file, when it also
4742 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004743 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004746#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004747 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004748
Victor Stinner4552ced2015-09-21 22:37:15 +02004749#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004751 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004752 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004753#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754
Victor Stinner528a9ab2015-09-03 21:30:26 +02004755#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004757 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 else
4759#endif
4760
Victor Stinner528a9ab2015-09-03 21:30:26 +02004761#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004762 if (path->fd != -1)
4763 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 else
4765#endif
4766
Larry Hastings2f936352014-08-05 14:04:04 +10004767 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768
4769 Py_END_ALLOW_THREADS
4770
4771 if (result < 0) {
4772 /* see previous comment about not putting filename in error here */
4773 return_value = posix_error();
4774 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004775 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004776
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004777#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778
4779 Py_INCREF(Py_None);
4780 return_value = Py_None;
4781
4782exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783#ifdef MS_WINDOWS
4784 if (hFile != INVALID_HANDLE_VALUE)
4785 CloseHandle(hFile);
4786#endif
4787 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004788}
4789
Guido van Rossum3b066191991-06-04 19:40:25 +00004790/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004791
Larry Hastings2f936352014-08-05 14:04:04 +10004792
4793/*[clinic input]
4794os._exit
4795
4796 status: int
4797
4798Exit to the system with specified status, without normal exit processing.
4799[clinic start generated code]*/
4800
Larry Hastings2f936352014-08-05 14:04:04 +10004801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004802os__exit_impl(PyObject *module, int status)
4803/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004804{
4805 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004806 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004807}
4808
Steve Dowercc16be82016-09-08 10:35:16 -07004809#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4810#define EXECV_CHAR wchar_t
4811#else
4812#define EXECV_CHAR char
4813#endif
4814
Martin v. Löwis114619e2002-10-07 06:44:21 +00004815#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4816static void
Steve Dowercc16be82016-09-08 10:35:16 -07004817free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004818{
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 Py_ssize_t i;
4820 for (i = 0; i < count; i++)
4821 PyMem_Free(array[i]);
4822 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004823}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004824
Berker Peksag81816462016-09-15 20:19:47 +03004825static int
4826fsconvert_strdup(PyObject *o, EXECV_CHAR **out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004827{
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 Py_ssize_t size;
Berker Peksag81816462016-09-15 20:19:47 +03004829 PyObject *ub;
4830 int result = 0;
Steve Dowercc16be82016-09-08 10:35:16 -07004831#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
Berker Peksag81816462016-09-15 20:19:47 +03004832 if (!PyUnicode_FSDecoder(o, &ub))
Steve Dowercc16be82016-09-08 10:35:16 -07004833 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004834 *out = PyUnicode_AsWideCharString(ub, &size);
4835 if (*out)
4836 result = 1;
Steve Dowercc16be82016-09-08 10:35:16 -07004837#else
Berker Peksag81816462016-09-15 20:19:47 +03004838 if (!PyUnicode_FSConverter(o, &ub))
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 return 0;
Berker Peksag81816462016-09-15 20:19:47 +03004840 size = PyBytes_GET_SIZE(ub);
4841 *out = PyMem_Malloc(size + 1);
4842 if (*out) {
4843 memcpy(*out, PyBytes_AS_STRING(ub), size + 1);
4844 result = 1;
4845 } else
Victor Stinner50abf222013-11-07 23:56:10 +01004846 PyErr_NoMemory();
Steve Dowercc16be82016-09-08 10:35:16 -07004847#endif
Berker Peksag81816462016-09-15 20:19:47 +03004848 Py_DECREF(ub);
4849 return result;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004850}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004851#endif
4852
Ross Lagerwall7807c352011-03-17 20:20:30 +02004853#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004854static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004855parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4856{
Victor Stinner8c62be82010-05-06 00:08:46 +00004857 Py_ssize_t i, pos, envc;
4858 PyObject *keys=NULL, *vals=NULL;
Berker Peksag81816462016-09-15 20:19:47 +03004859 PyObject *key, *val, *key2, *val2, *keyval;
Steve Dowercc16be82016-09-08 10:35:16 -07004860 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004861
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 i = PyMapping_Size(env);
4863 if (i < 0)
4864 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004865 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 if (envlist == NULL) {
4867 PyErr_NoMemory();
4868 return NULL;
4869 }
4870 envc = 0;
4871 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004872 if (!keys)
4873 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004875 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 goto error;
4877 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4878 PyErr_Format(PyExc_TypeError,
4879 "env.keys() or env.values() is not a list");
4880 goto error;
4881 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004882
Victor Stinner8c62be82010-05-06 00:08:46 +00004883 for (pos = 0; pos < i; pos++) {
4884 key = PyList_GetItem(keys, pos);
4885 val = PyList_GetItem(vals, pos);
4886 if (!key || !val)
4887 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004888
Berker Peksag81816462016-09-15 20:19:47 +03004889#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4890 if (!PyUnicode_FSDecoder(key, &key2))
4891 goto error;
4892 if (!PyUnicode_FSDecoder(val, &val2)) {
4893 Py_DECREF(key2);
4894 goto error;
4895 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004896 /* Search from index 1 because on Windows starting '=' is allowed for
4897 defining hidden environment variables. */
4898 if (PyUnicode_GET_LENGTH(key2) == 0 ||
4899 PyUnicode_FindChar(key2, '=', 1, PyUnicode_GET_LENGTH(key2), 1) != -1)
4900 {
4901 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004902 Py_DECREF(key2);
4903 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004904 goto error;
4905 }
Berker Peksag81816462016-09-15 20:19:47 +03004906 keyval = PyUnicode_FromFormat("%U=%U", key2, val2);
4907#else
4908 if (!PyUnicode_FSConverter(key, &key2))
4909 goto error;
4910 if (!PyUnicode_FSConverter(val, &val2)) {
4911 Py_DECREF(key2);
4912 goto error;
4913 }
Serhiy Storchaka77703942017-06-25 07:33:01 +03004914 if (PyBytes_GET_SIZE(key2) == 0 ||
4915 strchr(PyBytes_AS_STRING(key2) + 1, '=') != NULL)
4916 {
4917 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
Eric N. Vander Weelea7874c72017-06-26 21:35:20 -04004918 Py_DECREF(key2);
4919 Py_DECREF(val2);
Serhiy Storchaka77703942017-06-25 07:33:01 +03004920 goto error;
4921 }
Berker Peksag81816462016-09-15 20:19:47 +03004922 keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2),
4923 PyBytes_AS_STRING(val2));
4924#endif
4925 Py_DECREF(key2);
4926 Py_DECREF(val2);
Steve Dowercc16be82016-09-08 10:35:16 -07004927 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004929
4930 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4931 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 goto error;
4933 }
Berker Peksag81816462016-09-15 20:19:47 +03004934
Steve Dowercc16be82016-09-08 10:35:16 -07004935 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 }
4937 Py_DECREF(vals);
4938 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004939
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 envlist[envc] = 0;
4941 *envc_ptr = envc;
4942 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004943
4944error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 Py_XDECREF(keys);
4946 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004947 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004949}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004950
Steve Dowercc16be82016-09-08 10:35:16 -07004951static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004952parse_arglist(PyObject* argv, Py_ssize_t *argc)
4953{
4954 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004955 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956 if (argvlist == NULL) {
4957 PyErr_NoMemory();
4958 return NULL;
4959 }
4960 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004961 PyObject* item = PySequence_ITEM(argv, i);
4962 if (item == NULL)
4963 goto fail;
4964 if (!fsconvert_strdup(item, &argvlist[i])) {
4965 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004966 goto fail;
4967 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004968 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004969 }
4970 argvlist[*argc] = NULL;
4971 return argvlist;
4972fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004973 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004974 free_string_array(argvlist, *argc);
4975 return NULL;
4976}
Steve Dowercc16be82016-09-08 10:35:16 -07004977
Ross Lagerwall7807c352011-03-17 20:20:30 +02004978#endif
4979
Larry Hastings2f936352014-08-05 14:04:04 +10004980
Ross Lagerwall7807c352011-03-17 20:20:30 +02004981#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004982/*[clinic input]
4983os.execv
4984
Steve Dowercc16be82016-09-08 10:35:16 -07004985 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004986 Path of executable file.
4987 argv: object
4988 Tuple or list of strings.
4989 /
4990
4991Execute an executable path with arguments, replacing current process.
4992[clinic start generated code]*/
4993
Larry Hastings2f936352014-08-05 14:04:04 +10004994static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004995os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4996/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004997{
Steve Dowercc16be82016-09-08 10:35:16 -07004998 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999 Py_ssize_t argc;
5000
5001 /* execv has two arguments: (path, argv), where
5002 argv is a list or tuple of strings. */
5003
Ross Lagerwall7807c352011-03-17 20:20:30 +02005004 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5005 PyErr_SetString(PyExc_TypeError,
5006 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005007 return NULL;
5008 }
5009 argc = PySequence_Size(argv);
5010 if (argc < 1) {
5011 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005012 return NULL;
5013 }
5014
5015 argvlist = parse_arglist(argv, &argc);
5016 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005017 return NULL;
5018 }
Steve Dowerbce26262016-11-19 19:17:26 -08005019 if (!argvlist[0][0]) {
5020 PyErr_SetString(PyExc_ValueError,
5021 "execv() arg 2 first element cannot be empty");
5022 free_string_array(argvlist, argc);
5023 return NULL;
5024 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005025
Steve Dowerbce26262016-11-19 19:17:26 -08005026 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005027#ifdef HAVE_WEXECV
5028 _wexecv(path->wide, argvlist);
5029#else
5030 execv(path->narrow, argvlist);
5031#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005032 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005033
5034 /* If we get here it's definitely an error */
5035
5036 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005037 return posix_error();
5038}
5039
Larry Hastings2f936352014-08-05 14:04:04 +10005040
5041/*[clinic input]
5042os.execve
5043
5044 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5045 Path of executable file.
5046 argv: object
5047 Tuple or list of strings.
5048 env: object
5049 Dictionary of strings mapping to strings.
5050
5051Execute an executable path with arguments, replacing current process.
5052[clinic start generated code]*/
5053
Larry Hastings2f936352014-08-05 14:04:04 +10005054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005055os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5056/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005057{
Steve Dowercc16be82016-09-08 10:35:16 -07005058 EXECV_CHAR **argvlist = NULL;
5059 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005060 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005061
Victor Stinner8c62be82010-05-06 00:08:46 +00005062 /* execve has three arguments: (path, argv, env), where
5063 argv is a list or tuple of strings and env is a dictionary
5064 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005065
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005068 "execve: argv must be a tuple or list");
5069 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071 argc = PySequence_Size(argv);
Steve Dowerbce26262016-11-19 19:17:26 -08005072 if (argc < 1) {
5073 PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
5074 return NULL;
5075 }
5076
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 if (!PyMapping_Check(env)) {
5078 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005079 "execve: environment must be a mapping object");
5080 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005082
Ross Lagerwall7807c352011-03-17 20:20:30 +02005083 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005084 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005085 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 }
Steve Dowerbce26262016-11-19 19:17:26 -08005087 if (!argvlist[0][0]) {
5088 PyErr_SetString(PyExc_ValueError,
5089 "execve: argv first element cannot be empty");
5090 goto fail;
5091 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005092
Victor Stinner8c62be82010-05-06 00:08:46 +00005093 envlist = parse_envlist(env, &envc);
5094 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005095 goto fail;
5096
Steve Dowerbce26262016-11-19 19:17:26 -08005097 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07005098#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005099 if (path->fd > -1)
5100 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005101 else
5102#endif
Steve Dowercc16be82016-09-08 10:35:16 -07005103#ifdef HAVE_WEXECV
5104 _wexecve(path->wide, argvlist, envlist);
5105#else
Larry Hastings2f936352014-08-05 14:04:04 +10005106 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07005107#endif
Steve Dowerbce26262016-11-19 19:17:26 -08005108 _Py_END_SUPPRESS_IPH
Ross Lagerwall7807c352011-03-17 20:20:30 +02005109
5110 /* If we get here it's definitely an error */
5111
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07005112 posix_path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005113
Steve Dowercc16be82016-09-08 10:35:16 -07005114 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005116 if (argvlist)
5117 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005118 return NULL;
5119}
Steve Dowercc16be82016-09-08 10:35:16 -07005120
Larry Hastings9cf065c2012-06-22 16:30:09 -07005121#endif /* HAVE_EXECV */
5122
Steve Dowercc16be82016-09-08 10:35:16 -07005123#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005124/*[clinic input]
5125os.spawnv
5126
5127 mode: int
5128 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005129 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005130 Path of executable file.
5131 argv: object
5132 Tuple or list of strings.
5133 /
5134
5135Execute the program specified by path in a new process.
5136[clinic start generated code]*/
5137
Larry Hastings2f936352014-08-05 14:04:04 +10005138static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005139os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5140/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005141{
Steve Dowercc16be82016-09-08 10:35:16 -07005142 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005143 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005145 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 /* spawnv has three arguments: (mode, path, argv), where
5149 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005150
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 if (PyList_Check(argv)) {
5152 argc = PyList_Size(argv);
5153 getitem = PyList_GetItem;
5154 }
5155 else if (PyTuple_Check(argv)) {
5156 argc = PyTuple_Size(argv);
5157 getitem = PyTuple_GetItem;
5158 }
5159 else {
5160 PyErr_SetString(PyExc_TypeError,
5161 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 return NULL;
5163 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005164 if (argc == 0) {
5165 PyErr_SetString(PyExc_ValueError,
5166 "spawnv() arg 2 cannot be empty");
5167 return NULL;
5168 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005169
Steve Dowercc16be82016-09-08 10:35:16 -07005170 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 return PyErr_NoMemory();
5173 }
5174 for (i = 0; i < argc; i++) {
5175 if (!fsconvert_strdup((*getitem)(argv, i),
5176 &argvlist[i])) {
5177 free_string_array(argvlist, i);
5178 PyErr_SetString(
5179 PyExc_TypeError,
5180 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 return NULL;
5182 }
Steve Dower93ff8722016-11-19 19:03:54 -08005183 if (i == 0 && !argvlist[0][0]) {
Victor Stinner8acb4cf2017-06-15 15:30:40 +02005184 free_string_array(argvlist, i + 1);
Steve Dower93ff8722016-11-19 19:03:54 -08005185 PyErr_SetString(
5186 PyExc_ValueError,
5187 "spawnv() arg 2 first element cannot be empty");
5188 return NULL;
5189 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 }
5191 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005192
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 if (mode == _OLD_P_OVERLAY)
5194 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005197 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005198#ifdef HAVE_WSPAWNV
5199 spawnval = _wspawnv(mode, path->wide, argvlist);
5200#else
5201 spawnval = _spawnv(mode, path->narrow, argvlist);
5202#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005203 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005207
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 if (spawnval == -1)
5209 return posix_error();
5210 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005211 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005212}
5213
Larry Hastings2f936352014-08-05 14:04:04 +10005214/*[clinic input]
5215os.spawnve
5216
5217 mode: int
5218 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005219 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005220 Path of executable file.
5221 argv: object
5222 Tuple or list of strings.
5223 env: object
5224 Dictionary of strings mapping to strings.
5225 /
5226
5227Execute the program specified by path in a new process.
5228[clinic start generated code]*/
5229
Larry Hastings2f936352014-08-05 14:04:04 +10005230static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005231os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005232 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005233/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005234{
Steve Dowercc16be82016-09-08 10:35:16 -07005235 EXECV_CHAR **argvlist;
5236 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005237 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005238 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005239 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005241 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005242
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 /* spawnve has four arguments: (mode, path, argv, env), where
5244 argv is a list or tuple of strings and env is a dictionary
5245 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005246
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 if (PyList_Check(argv)) {
5248 argc = PyList_Size(argv);
5249 getitem = PyList_GetItem;
5250 }
5251 else if (PyTuple_Check(argv)) {
5252 argc = PyTuple_Size(argv);
5253 getitem = PyTuple_GetItem;
5254 }
5255 else {
5256 PyErr_SetString(PyExc_TypeError,
5257 "spawnve() arg 2 must be a tuple or list");
5258 goto fail_0;
5259 }
Steve Dower859fd7b2016-11-19 18:53:19 -08005260 if (argc == 0) {
5261 PyErr_SetString(PyExc_ValueError,
5262 "spawnve() arg 2 cannot be empty");
5263 goto fail_0;
5264 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 if (!PyMapping_Check(env)) {
5266 PyErr_SetString(PyExc_TypeError,
5267 "spawnve() arg 3 must be a mapping object");
5268 goto fail_0;
5269 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005270
Steve Dowercc16be82016-09-08 10:35:16 -07005271 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 if (argvlist == NULL) {
5273 PyErr_NoMemory();
5274 goto fail_0;
5275 }
5276 for (i = 0; i < argc; i++) {
5277 if (!fsconvert_strdup((*getitem)(argv, i),
5278 &argvlist[i]))
5279 {
5280 lastarg = i;
5281 goto fail_1;
5282 }
Steve Dowerbce26262016-11-19 19:17:26 -08005283 if (i == 0 && !argvlist[0][0]) {
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005284 lastarg = i + 1;
Steve Dowerbce26262016-11-19 19:17:26 -08005285 PyErr_SetString(
5286 PyExc_ValueError,
5287 "spawnv() arg 2 first element cannot be empty");
5288 goto fail_1;
5289 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005290 }
5291 lastarg = argc;
5292 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 envlist = parse_envlist(env, &envc);
5295 if (envlist == NULL)
5296 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005297
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 if (mode == _OLD_P_OVERLAY)
5299 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005302 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005303#ifdef HAVE_WSPAWNV
5304 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5305#else
5306 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5307#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005308 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005310
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 if (spawnval == -1)
5312 (void) posix_error();
5313 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005314 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005315
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 while (--envc >= 0)
5317 PyMem_DEL(envlist[envc]);
5318 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005319 fail_1:
Victor Stinnerc8d6ab22017-06-23 15:04:46 +02005320 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005321 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005323}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005324
Guido van Rossuma1065681999-01-25 23:20:23 +00005325#endif /* HAVE_SPAWNV */
5326
5327
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005328#ifdef HAVE_FORK
Gregory P. Smith163468a2017-05-29 10:03:41 -07005329
5330/* Helper function to validate arguments.
5331 Returns 0 on success. non-zero on failure with a TypeError raised.
5332 If obj is non-NULL it must be callable. */
5333static int
5334check_null_or_callable(PyObject *obj, const char* obj_name)
5335{
5336 if (obj && !PyCallable_Check(obj)) {
5337 PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s",
5338 obj_name, Py_TYPE(obj)->tp_name);
5339 return -1;
5340 }
5341 return 0;
5342}
5343
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005344/*[clinic input]
5345os.register_at_fork
5346
Gregory P. Smith163468a2017-05-29 10:03:41 -07005347 *
5348 before: object=NULL
5349 A callable to be called in the parent before the fork() syscall.
5350 after_in_child: object=NULL
5351 A callable to be called in the child after fork().
5352 after_in_parent: object=NULL
5353 A callable to be called in the parent after fork().
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005354
Gregory P. Smith163468a2017-05-29 10:03:41 -07005355Register callables to be called when forking a new process.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005356
Gregory P. Smith163468a2017-05-29 10:03:41 -07005357'before' callbacks are called in reverse order.
5358'after_in_child' and 'after_in_parent' callbacks are called in order.
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005359
5360[clinic start generated code]*/
5361
5362static PyObject *
Gregory P. Smith163468a2017-05-29 10:03:41 -07005363os_register_at_fork_impl(PyObject *module, PyObject *before,
5364 PyObject *after_in_child, PyObject *after_in_parent)
5365/*[clinic end generated code: output=5398ac75e8e97625 input=cd1187aa85d2312e]*/
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005366{
5367 PyInterpreterState *interp;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005368
Gregory P. Smith163468a2017-05-29 10:03:41 -07005369 if (!before && !after_in_child && !after_in_parent) {
5370 PyErr_SetString(PyExc_TypeError, "At least one argument is required.");
5371 return NULL;
5372 }
5373 if (check_null_or_callable(before, "before") ||
5374 check_null_or_callable(after_in_child, "after_in_child") ||
5375 check_null_or_callable(after_in_parent, "after_in_parent")) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005376 return NULL;
5377 }
5378 interp = PyThreadState_Get()->interp;
5379
Gregory P. Smith163468a2017-05-29 10:03:41 -07005380 if (register_at_forker(&interp->before_forkers, before)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005381 return NULL;
5382 }
Gregory P. Smith163468a2017-05-29 10:03:41 -07005383 if (register_at_forker(&interp->after_forkers_child, after_in_child)) {
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005384 return NULL;
Gregory P. Smith163468a2017-05-29 10:03:41 -07005385 }
5386 if (register_at_forker(&interp->after_forkers_parent, after_in_parent)) {
5387 return NULL;
5388 }
5389 Py_RETURN_NONE;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005390}
5391#endif /* HAVE_FORK */
5392
5393
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005394#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005395/*[clinic input]
5396os.fork1
5397
5398Fork a child process with a single multiplexed (i.e., not bound) thread.
5399
5400Return 0 to child process and PID of child to parent process.
5401[clinic start generated code]*/
5402
Larry Hastings2f936352014-08-05 14:04:04 +10005403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005404os_fork1_impl(PyObject *module)
5405/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005406{
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005408
5409 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 pid = fork1();
5411 if (pid == 0) {
5412 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005413 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 } else {
5415 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005416 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005417 }
5418 if (pid == -1)
5419 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005421}
Larry Hastings2f936352014-08-05 14:04:04 +10005422#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005423
5424
Guido van Rossumad0ee831995-03-01 10:34:45 +00005425#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005426/*[clinic input]
5427os.fork
5428
5429Fork a child process.
5430
5431Return 0 to child process and PID of child to parent process.
5432[clinic start generated code]*/
5433
Larry Hastings2f936352014-08-05 14:04:04 +10005434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005435os_fork_impl(PyObject *module)
5436/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005437{
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 pid_t pid;
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005439
5440 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 pid = fork();
5442 if (pid == 0) {
5443 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005444 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00005445 } else {
5446 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02005447 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00005448 }
5449 if (pid == -1)
5450 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005451 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005452}
Larry Hastings2f936352014-08-05 14:04:04 +10005453#endif /* HAVE_FORK */
5454
Guido van Rossum85e3b011991-06-03 12:42:10 +00005455
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005456#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005457#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005458/*[clinic input]
5459os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005460
Larry Hastings2f936352014-08-05 14:04:04 +10005461 policy: int
5462
5463Get the maximum scheduling priority for policy.
5464[clinic start generated code]*/
5465
Larry Hastings2f936352014-08-05 14:04:04 +10005466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005467os_sched_get_priority_max_impl(PyObject *module, int policy)
5468/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005469{
5470 int max;
5471
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005472 max = sched_get_priority_max(policy);
5473 if (max < 0)
5474 return posix_error();
5475 return PyLong_FromLong(max);
5476}
5477
Larry Hastings2f936352014-08-05 14:04:04 +10005478
5479/*[clinic input]
5480os.sched_get_priority_min
5481
5482 policy: int
5483
5484Get the minimum scheduling priority for policy.
5485[clinic start generated code]*/
5486
Larry Hastings2f936352014-08-05 14:04:04 +10005487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005488os_sched_get_priority_min_impl(PyObject *module, int policy)
5489/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005490{
5491 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492 if (min < 0)
5493 return posix_error();
5494 return PyLong_FromLong(min);
5495}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005496#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5497
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005498
Larry Hastings2f936352014-08-05 14:04:04 +10005499#ifdef HAVE_SCHED_SETSCHEDULER
5500/*[clinic input]
5501os.sched_getscheduler
5502 pid: pid_t
5503 /
5504
5505Get the scheduling policy for the process identifiedy by pid.
5506
5507Passing 0 for pid returns the scheduling policy for the calling process.
5508[clinic start generated code]*/
5509
Larry Hastings2f936352014-08-05 14:04:04 +10005510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005511os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5512/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005513{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005514 int policy;
5515
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005516 policy = sched_getscheduler(pid);
5517 if (policy < 0)
5518 return posix_error();
5519 return PyLong_FromLong(policy);
5520}
Larry Hastings2f936352014-08-05 14:04:04 +10005521#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005522
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005523
5524#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005525/*[clinic input]
5526class os.sched_param "PyObject *" "&SchedParamType"
5527
5528@classmethod
5529os.sched_param.__new__
5530
5531 sched_priority: object
5532 A scheduling parameter.
5533
5534Current has only one field: sched_priority");
5535[clinic start generated code]*/
5536
Larry Hastings2f936352014-08-05 14:04:04 +10005537static PyObject *
5538os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005539/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005540{
5541 PyObject *res;
5542
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005543 res = PyStructSequence_New(type);
5544 if (!res)
5545 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005546 Py_INCREF(sched_priority);
5547 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548 return res;
5549}
5550
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005551
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005552PyDoc_VAR(os_sched_param__doc__);
5553
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005554static PyStructSequence_Field sched_param_fields[] = {
5555 {"sched_priority", "the scheduling priority"},
5556 {0}
5557};
5558
5559static PyStructSequence_Desc sched_param_desc = {
5560 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005561 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005562 sched_param_fields,
5563 1
5564};
5565
5566static int
5567convert_sched_param(PyObject *param, struct sched_param *res)
5568{
5569 long priority;
5570
5571 if (Py_TYPE(param) != &SchedParamType) {
5572 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5573 return 0;
5574 }
5575 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5576 if (priority == -1 && PyErr_Occurred())
5577 return 0;
5578 if (priority > INT_MAX || priority < INT_MIN) {
5579 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5580 return 0;
5581 }
5582 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5583 return 1;
5584}
Larry Hastings2f936352014-08-05 14:04:04 +10005585#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005587
5588#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005589/*[clinic input]
5590os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005591
Larry Hastings2f936352014-08-05 14:04:04 +10005592 pid: pid_t
5593 policy: int
5594 param: sched_param
5595 /
5596
5597Set the scheduling policy for the process identified by pid.
5598
5599If pid is 0, the calling process is changed.
5600param is an instance of sched_param.
5601[clinic start generated code]*/
5602
Larry Hastings2f936352014-08-05 14:04:04 +10005603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005604os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005605 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005606/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005607{
Jesus Cea9c822272011-09-10 01:40:52 +02005608 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005609 ** sched_setscheduler() returns 0 in Linux, but the previous
5610 ** scheduling policy under Solaris/Illumos, and others.
5611 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005612 */
Larry Hastings2f936352014-08-05 14:04:04 +10005613 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005614 return posix_error();
5615 Py_RETURN_NONE;
5616}
Larry Hastings2f936352014-08-05 14:04:04 +10005617#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005618
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005619
5620#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005621/*[clinic input]
5622os.sched_getparam
5623 pid: pid_t
5624 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005625
Larry Hastings2f936352014-08-05 14:04:04 +10005626Returns scheduling parameters for the process identified by pid.
5627
5628If pid is 0, returns parameters for the calling process.
5629Return value is an instance of sched_param.
5630[clinic start generated code]*/
5631
Larry Hastings2f936352014-08-05 14:04:04 +10005632static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005633os_sched_getparam_impl(PyObject *module, pid_t pid)
5634/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005635{
5636 struct sched_param param;
5637 PyObject *result;
5638 PyObject *priority;
5639
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005640 if (sched_getparam(pid, &param))
5641 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005642 result = PyStructSequence_New(&SchedParamType);
5643 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005644 return NULL;
5645 priority = PyLong_FromLong(param.sched_priority);
5646 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005647 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005648 return NULL;
5649 }
Larry Hastings2f936352014-08-05 14:04:04 +10005650 PyStructSequence_SET_ITEM(result, 0, priority);
5651 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005652}
5653
Larry Hastings2f936352014-08-05 14:04:04 +10005654
5655/*[clinic input]
5656os.sched_setparam
5657 pid: pid_t
5658 param: sched_param
5659 /
5660
5661Set scheduling parameters for the process identified by pid.
5662
5663If pid is 0, sets parameters for the calling process.
5664param should be an instance of sched_param.
5665[clinic start generated code]*/
5666
Larry Hastings2f936352014-08-05 14:04:04 +10005667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005668os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005669 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005670/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005671{
5672 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005673 return posix_error();
5674 Py_RETURN_NONE;
5675}
Larry Hastings2f936352014-08-05 14:04:04 +10005676#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005677
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005678
5679#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005680/*[clinic input]
5681os.sched_rr_get_interval -> double
5682 pid: pid_t
5683 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005684
Larry Hastings2f936352014-08-05 14:04:04 +10005685Return the round-robin quantum for the process identified by pid, in seconds.
5686
5687Value returned is a float.
5688[clinic start generated code]*/
5689
Larry Hastings2f936352014-08-05 14:04:04 +10005690static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005691os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5692/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005693{
5694 struct timespec interval;
5695 if (sched_rr_get_interval(pid, &interval)) {
5696 posix_error();
5697 return -1.0;
5698 }
5699 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5700}
5701#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005702
Larry Hastings2f936352014-08-05 14:04:04 +10005703
5704/*[clinic input]
5705os.sched_yield
5706
5707Voluntarily relinquish the CPU.
5708[clinic start generated code]*/
5709
Larry Hastings2f936352014-08-05 14:04:04 +10005710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005711os_sched_yield_impl(PyObject *module)
5712/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005713{
5714 if (sched_yield())
5715 return posix_error();
5716 Py_RETURN_NONE;
5717}
5718
Benjamin Peterson2740af82011-08-02 17:41:34 -05005719#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005720/* The minimum number of CPUs allocated in a cpu_set_t */
5721static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005722
Larry Hastings2f936352014-08-05 14:04:04 +10005723/*[clinic input]
5724os.sched_setaffinity
5725 pid: pid_t
5726 mask : object
5727 /
5728
5729Set the CPU affinity of the process identified by pid to mask.
5730
5731mask should be an iterable of integers identifying CPUs.
5732[clinic start generated code]*/
5733
Larry Hastings2f936352014-08-05 14:04:04 +10005734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005735os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5736/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005737{
Antoine Pitrou84869872012-08-04 16:16:35 +02005738 int ncpus;
5739 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005740 cpu_set_t *cpu_set = NULL;
5741 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005742
Larry Hastings2f936352014-08-05 14:04:04 +10005743 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005744 if (iterator == NULL)
5745 return NULL;
5746
5747 ncpus = NCPUS_START;
5748 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005749 cpu_set = CPU_ALLOC(ncpus);
5750 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005751 PyErr_NoMemory();
5752 goto error;
5753 }
Larry Hastings2f936352014-08-05 14:04:04 +10005754 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005755
5756 while ((item = PyIter_Next(iterator))) {
5757 long cpu;
5758 if (!PyLong_Check(item)) {
5759 PyErr_Format(PyExc_TypeError,
5760 "expected an iterator of ints, "
5761 "but iterator yielded %R",
5762 Py_TYPE(item));
5763 Py_DECREF(item);
5764 goto error;
5765 }
5766 cpu = PyLong_AsLong(item);
5767 Py_DECREF(item);
5768 if (cpu < 0) {
5769 if (!PyErr_Occurred())
5770 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5771 goto error;
5772 }
5773 if (cpu > INT_MAX - 1) {
5774 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5775 goto error;
5776 }
5777 if (cpu >= ncpus) {
5778 /* Grow CPU mask to fit the CPU number */
5779 int newncpus = ncpus;
5780 cpu_set_t *newmask;
5781 size_t newsetsize;
5782 while (newncpus <= cpu) {
5783 if (newncpus > INT_MAX / 2)
5784 newncpus = cpu + 1;
5785 else
5786 newncpus = newncpus * 2;
5787 }
5788 newmask = CPU_ALLOC(newncpus);
5789 if (newmask == NULL) {
5790 PyErr_NoMemory();
5791 goto error;
5792 }
5793 newsetsize = CPU_ALLOC_SIZE(newncpus);
5794 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005795 memcpy(newmask, cpu_set, setsize);
5796 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005797 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005798 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005799 ncpus = newncpus;
5800 }
Larry Hastings2f936352014-08-05 14:04:04 +10005801 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005802 }
5803 Py_CLEAR(iterator);
5804
Larry Hastings2f936352014-08-05 14:04:04 +10005805 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005806 posix_error();
5807 goto error;
5808 }
Larry Hastings2f936352014-08-05 14:04:04 +10005809 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005810 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005811
5812error:
Larry Hastings2f936352014-08-05 14:04:04 +10005813 if (cpu_set)
5814 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005815 Py_XDECREF(iterator);
5816 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005817}
5818
Larry Hastings2f936352014-08-05 14:04:04 +10005819
5820/*[clinic input]
5821os.sched_getaffinity
5822 pid: pid_t
5823 /
5824
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005825Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005826
5827The affinity is returned as a set of CPU identifiers.
5828[clinic start generated code]*/
5829
Larry Hastings2f936352014-08-05 14:04:04 +10005830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005831os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005832/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005833{
Antoine Pitrou84869872012-08-04 16:16:35 +02005834 int cpu, ncpus, count;
5835 size_t setsize;
5836 cpu_set_t *mask = NULL;
5837 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005838
Antoine Pitrou84869872012-08-04 16:16:35 +02005839 ncpus = NCPUS_START;
5840 while (1) {
5841 setsize = CPU_ALLOC_SIZE(ncpus);
5842 mask = CPU_ALLOC(ncpus);
5843 if (mask == NULL)
5844 return PyErr_NoMemory();
5845 if (sched_getaffinity(pid, setsize, mask) == 0)
5846 break;
5847 CPU_FREE(mask);
5848 if (errno != EINVAL)
5849 return posix_error();
5850 if (ncpus > INT_MAX / 2) {
5851 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5852 "a large enough CPU set");
5853 return NULL;
5854 }
5855 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005856 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005857
5858 res = PySet_New(NULL);
5859 if (res == NULL)
5860 goto error;
5861 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5862 if (CPU_ISSET_S(cpu, setsize, mask)) {
5863 PyObject *cpu_num = PyLong_FromLong(cpu);
5864 --count;
5865 if (cpu_num == NULL)
5866 goto error;
5867 if (PySet_Add(res, cpu_num)) {
5868 Py_DECREF(cpu_num);
5869 goto error;
5870 }
5871 Py_DECREF(cpu_num);
5872 }
5873 }
5874 CPU_FREE(mask);
5875 return res;
5876
5877error:
5878 if (mask)
5879 CPU_FREE(mask);
5880 Py_XDECREF(res);
5881 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005882}
5883
Benjamin Peterson2740af82011-08-02 17:41:34 -05005884#endif /* HAVE_SCHED_SETAFFINITY */
5885
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005886#endif /* HAVE_SCHED_H */
5887
Larry Hastings2f936352014-08-05 14:04:04 +10005888
Neal Norwitzb59798b2003-03-21 01:43:31 +00005889/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005890/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5891#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005892#define DEV_PTY_FILE "/dev/ptc"
5893#define HAVE_DEV_PTMX
5894#else
5895#define DEV_PTY_FILE "/dev/ptmx"
5896#endif
5897
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005898#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005899#ifdef HAVE_PTY_H
5900#include <pty.h>
5901#else
5902#ifdef HAVE_LIBUTIL_H
5903#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005904#else
5905#ifdef HAVE_UTIL_H
5906#include <util.h>
5907#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005908#endif /* HAVE_LIBUTIL_H */
5909#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005910#ifdef HAVE_STROPTS_H
5911#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005912#endif
Miss Islington (bot)f0616ce2018-02-14 13:06:46 -08005913#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005914
Larry Hastings2f936352014-08-05 14:04:04 +10005915
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005916#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005917/*[clinic input]
5918os.openpty
5919
5920Open a pseudo-terminal.
5921
5922Return a tuple of (master_fd, slave_fd) containing open file descriptors
5923for both the master and slave ends.
5924[clinic start generated code]*/
5925
Larry Hastings2f936352014-08-05 14:04:04 +10005926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005927os_openpty_impl(PyObject *module)
5928/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005929{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005930 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005931#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005934#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005936#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005938#endif
5939#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005940
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005943 goto posix_error;
5944
5945 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5946 goto error;
5947 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5948 goto error;
5949
Neal Norwitzb59798b2003-03-21 01:43:31 +00005950#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5952 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953 goto posix_error;
5954 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5955 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005956
Victor Stinnerdaf45552013-08-28 00:53:59 +02005957 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005959 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005960
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005961#else
Victor Stinner000de532013-11-25 23:19:58 +01005962 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964 goto posix_error;
5965
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005967
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 /* change permission of slave */
5969 if (grantpt(master_fd) < 0) {
5970 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005971 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005973
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 /* unlock slave */
5975 if (unlockpt(master_fd) < 0) {
5976 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005977 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005979
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005981
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 slave_name = ptsname(master_fd); /* get name of slave */
5983 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005984 goto posix_error;
5985
5986 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005987 if (slave_fd == -1)
5988 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005989
5990 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5991 goto posix_error;
5992
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005993#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5995 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005996#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005998#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005999#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006000#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006001
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006003
Victor Stinnerdaf45552013-08-28 00:53:59 +02006004posix_error:
6005 posix_error();
6006error:
6007 if (master_fd != -1)
6008 close(master_fd);
6009 if (slave_fd != -1)
6010 close(slave_fd);
6011 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006012}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006013#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014
Larry Hastings2f936352014-08-05 14:04:04 +10006015
Fred Drake8cef4cf2000-06-28 16:40:38 +00006016#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006017/*[clinic input]
6018os.forkpty
6019
6020Fork a new process with a new pseudo-terminal as controlling tty.
6021
6022Returns a tuple of (pid, master_fd).
6023Like fork(), return pid of 0 to the child process,
6024and pid of child to the parent process.
6025To both, return fd of newly opened pseudo-terminal.
6026[clinic start generated code]*/
6027
Larry Hastings2f936352014-08-05 14:04:04 +10006028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006029os_forkpty_impl(PyObject *module)
6030/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006031{
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006032 int master_fd = -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006034
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006035 PyOS_BeforeFork();
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 pid = forkpty(&master_fd, NULL, NULL, NULL);
6037 if (pid == 0) {
6038 /* child: this clobbers and resets the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006039 PyOS_AfterFork_Child();
Victor Stinner8c62be82010-05-06 00:08:46 +00006040 } else {
6041 /* parent: release the import lock. */
Antoine Pitrou346cbd32017-05-27 17:50:54 +02006042 PyOS_AfterFork_Parent();
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 }
6044 if (pid == -1)
6045 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006047}
Larry Hastings2f936352014-08-05 14:04:04 +10006048#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006049
Ross Lagerwall7807c352011-03-17 20:20:30 +02006050
Guido van Rossumad0ee831995-03-01 10:34:45 +00006051#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006052/*[clinic input]
6053os.getegid
6054
6055Return the current process's effective group id.
6056[clinic start generated code]*/
6057
Larry Hastings2f936352014-08-05 14:04:04 +10006058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006059os_getegid_impl(PyObject *module)
6060/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006061{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006062 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006063}
Larry Hastings2f936352014-08-05 14:04:04 +10006064#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006066
Guido van Rossumad0ee831995-03-01 10:34:45 +00006067#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006068/*[clinic input]
6069os.geteuid
6070
6071Return the current process's effective user id.
6072[clinic start generated code]*/
6073
Larry Hastings2f936352014-08-05 14:04:04 +10006074static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006075os_geteuid_impl(PyObject *module)
6076/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006077{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006078 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006079}
Larry Hastings2f936352014-08-05 14:04:04 +10006080#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Guido van Rossumad0ee831995-03-01 10:34:45 +00006083#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006084/*[clinic input]
6085os.getgid
6086
6087Return the current process's group id.
6088[clinic start generated code]*/
6089
Larry Hastings2f936352014-08-05 14:04:04 +10006090static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006091os_getgid_impl(PyObject *module)
6092/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006093{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006094 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006095}
Larry Hastings2f936352014-08-05 14:04:04 +10006096#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006098
Berker Peksag39404992016-09-15 20:45:16 +03006099#ifdef HAVE_GETPID
Larry Hastings2f936352014-08-05 14:04:04 +10006100/*[clinic input]
6101os.getpid
6102
6103Return the current process id.
6104[clinic start generated code]*/
6105
Larry Hastings2f936352014-08-05 14:04:04 +10006106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006107os_getpid_impl(PyObject *module)
6108/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006109{
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006111}
Berker Peksag39404992016-09-15 20:45:16 +03006112#endif /* HAVE_GETPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006113
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006114#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006115
6116/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006117PyDoc_STRVAR(posix_getgrouplist__doc__,
6118"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6119Returns a list of groups to which a user belongs.\n\n\
6120 user: username to lookup\n\
6121 group: base group id of the user");
6122
6123static PyObject *
6124posix_getgrouplist(PyObject *self, PyObject *args)
6125{
6126#ifdef NGROUPS_MAX
6127#define MAX_GROUPS NGROUPS_MAX
6128#else
6129 /* defined to be 16 on Solaris7, so this should be a small number */
6130#define MAX_GROUPS 64
6131#endif
6132
6133 const char *user;
6134 int i, ngroups;
6135 PyObject *list;
6136#ifdef __APPLE__
6137 int *groups, basegid;
6138#else
6139 gid_t *groups, basegid;
6140#endif
6141 ngroups = MAX_GROUPS;
6142
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006143#ifdef __APPLE__
6144 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006145 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006146#else
6147 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6148 _Py_Gid_Converter, &basegid))
6149 return NULL;
6150#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006151
6152#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006153 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006154#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006155 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006156#endif
6157 if (groups == NULL)
6158 return PyErr_NoMemory();
6159
6160 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6161 PyMem_Del(groups);
6162 return posix_error();
6163 }
6164
6165 list = PyList_New(ngroups);
6166 if (list == NULL) {
6167 PyMem_Del(groups);
6168 return NULL;
6169 }
6170
6171 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006172#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006173 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006174#else
6175 PyObject *o = _PyLong_FromGid(groups[i]);
6176#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006177 if (o == NULL) {
6178 Py_DECREF(list);
6179 PyMem_Del(groups);
6180 return NULL;
6181 }
6182 PyList_SET_ITEM(list, i, o);
6183 }
6184
6185 PyMem_Del(groups);
6186
6187 return list;
6188}
Larry Hastings2f936352014-08-05 14:04:04 +10006189#endif /* HAVE_GETGROUPLIST */
6190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006191
Fred Drakec9680921999-12-13 16:37:25 +00006192#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006193/*[clinic input]
6194os.getgroups
6195
6196Return list of supplemental group IDs for the process.
6197[clinic start generated code]*/
6198
Larry Hastings2f936352014-08-05 14:04:04 +10006199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006200os_getgroups_impl(PyObject *module)
6201/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006202{
6203 PyObject *result = NULL;
6204
Fred Drakec9680921999-12-13 16:37:25 +00006205#ifdef NGROUPS_MAX
6206#define MAX_GROUPS NGROUPS_MAX
6207#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006208 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006209#define MAX_GROUPS 64
6210#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006212
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006213 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006214 * This is a helper variable to store the intermediate result when
6215 * that happens.
6216 *
6217 * To keep the code readable the OSX behaviour is unconditional,
6218 * according to the POSIX spec this should be safe on all unix-y
6219 * systems.
6220 */
6221 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006223
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006224#ifdef __APPLE__
6225 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6226 * there are more groups than can fit in grouplist. Therefore, on OS X
6227 * always first call getgroups with length 0 to get the actual number
6228 * of groups.
6229 */
6230 n = getgroups(0, NULL);
6231 if (n < 0) {
6232 return posix_error();
6233 } else if (n <= MAX_GROUPS) {
6234 /* groups will fit in existing array */
6235 alt_grouplist = grouplist;
6236 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006237 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006238 if (alt_grouplist == NULL) {
6239 errno = EINVAL;
6240 return posix_error();
6241 }
6242 }
6243
6244 n = getgroups(n, alt_grouplist);
6245 if (n == -1) {
6246 if (alt_grouplist != grouplist) {
6247 PyMem_Free(alt_grouplist);
6248 }
6249 return posix_error();
6250 }
6251#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006253 if (n < 0) {
6254 if (errno == EINVAL) {
6255 n = getgroups(0, NULL);
6256 if (n == -1) {
6257 return posix_error();
6258 }
6259 if (n == 0) {
6260 /* Avoid malloc(0) */
6261 alt_grouplist = grouplist;
6262 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006263 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006264 if (alt_grouplist == NULL) {
6265 errno = EINVAL;
6266 return posix_error();
6267 }
6268 n = getgroups(n, alt_grouplist);
6269 if (n == -1) {
6270 PyMem_Free(alt_grouplist);
6271 return posix_error();
6272 }
6273 }
6274 } else {
6275 return posix_error();
6276 }
6277 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006278#endif
6279
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006280 result = PyList_New(n);
6281 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006282 int i;
6283 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006284 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006285 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006286 Py_DECREF(result);
6287 result = NULL;
6288 break;
Fred Drakec9680921999-12-13 16:37:25 +00006289 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006291 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292 }
6293
6294 if (alt_grouplist != grouplist) {
6295 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006297
Fred Drakec9680921999-12-13 16:37:25 +00006298 return result;
6299}
Larry Hastings2f936352014-08-05 14:04:04 +10006300#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006301
Antoine Pitroub7572f02009-12-02 20:46:48 +00006302#ifdef HAVE_INITGROUPS
6303PyDoc_STRVAR(posix_initgroups__doc__,
6304"initgroups(username, gid) -> None\n\n\
6305Call the system initgroups() to initialize the group access list with all of\n\
6306the groups of which the specified username is a member, plus the specified\n\
6307group id.");
6308
Larry Hastings2f936352014-08-05 14:04:04 +10006309/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006310static PyObject *
6311posix_initgroups(PyObject *self, PyObject *args)
6312{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006313 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006314 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006315 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006316#ifdef __APPLE__
6317 int gid;
6318#else
6319 gid_t gid;
6320#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006321
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006322#ifdef __APPLE__
6323 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6324 PyUnicode_FSConverter, &oname,
6325 &gid))
6326#else
6327 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6328 PyUnicode_FSConverter, &oname,
6329 _Py_Gid_Converter, &gid))
6330#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006331 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006332 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006333
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006334 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006335 Py_DECREF(oname);
6336 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006338
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006339 Py_RETURN_NONE;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006340}
Larry Hastings2f936352014-08-05 14:04:04 +10006341#endif /* HAVE_INITGROUPS */
6342
Antoine Pitroub7572f02009-12-02 20:46:48 +00006343
Martin v. Löwis606edc12002-06-13 21:09:11 +00006344#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006345/*[clinic input]
6346os.getpgid
6347
6348 pid: pid_t
6349
6350Call the system call getpgid(), and return the result.
6351[clinic start generated code]*/
6352
Larry Hastings2f936352014-08-05 14:04:04 +10006353static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006354os_getpgid_impl(PyObject *module, pid_t pid)
6355/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006356{
6357 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 if (pgid < 0)
6359 return posix_error();
6360 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006361}
6362#endif /* HAVE_GETPGID */
6363
6364
Guido van Rossumb6775db1994-08-01 11:34:53 +00006365#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006366/*[clinic input]
6367os.getpgrp
6368
6369Return the current process group id.
6370[clinic start generated code]*/
6371
Larry Hastings2f936352014-08-05 14:04:04 +10006372static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006373os_getpgrp_impl(PyObject *module)
6374/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006375{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006376#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006378#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006380#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006381}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006382#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006384
Guido van Rossumb6775db1994-08-01 11:34:53 +00006385#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006386/*[clinic input]
6387os.setpgrp
6388
6389Make the current process the leader of its process group.
6390[clinic start generated code]*/
6391
Larry Hastings2f936352014-08-05 14:04:04 +10006392static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006393os_setpgrp_impl(PyObject *module)
6394/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006395{
Guido van Rossum64933891994-10-20 21:56:42 +00006396#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006398#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006400#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006402 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006403}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#endif /* HAVE_SETPGRP */
6405
Guido van Rossumad0ee831995-03-01 10:34:45 +00006406#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006407
6408#ifdef MS_WINDOWS
6409#include <tlhelp32.h>
6410
6411static PyObject*
6412win32_getppid()
6413{
6414 HANDLE snapshot;
6415 pid_t mypid;
6416 PyObject* result = NULL;
6417 BOOL have_record;
6418 PROCESSENTRY32 pe;
6419
6420 mypid = getpid(); /* This function never fails */
6421
6422 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6423 if (snapshot == INVALID_HANDLE_VALUE)
6424 return PyErr_SetFromWindowsErr(GetLastError());
6425
6426 pe.dwSize = sizeof(pe);
6427 have_record = Process32First(snapshot, &pe);
6428 while (have_record) {
6429 if (mypid == (pid_t)pe.th32ProcessID) {
6430 /* We could cache the ulong value in a static variable. */
6431 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6432 break;
6433 }
6434
6435 have_record = Process32Next(snapshot, &pe);
6436 }
6437
6438 /* If our loop exits and our pid was not found (result will be NULL)
6439 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6440 * error anyway, so let's raise it. */
6441 if (!result)
6442 result = PyErr_SetFromWindowsErr(GetLastError());
6443
6444 CloseHandle(snapshot);
6445
6446 return result;
6447}
6448#endif /*MS_WINDOWS*/
6449
Larry Hastings2f936352014-08-05 14:04:04 +10006450
6451/*[clinic input]
6452os.getppid
6453
6454Return the parent's process id.
6455
6456If the parent process has already exited, Windows machines will still
6457return its id; others systems will return the id of the 'init' process (1).
6458[clinic start generated code]*/
6459
Larry Hastings2f936352014-08-05 14:04:04 +10006460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006461os_getppid_impl(PyObject *module)
6462/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006463{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006464#ifdef MS_WINDOWS
6465 return win32_getppid();
6466#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006468#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006469}
6470#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Fred Drake12c6e2d1999-12-14 21:25:03 +00006473#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006474/*[clinic input]
6475os.getlogin
6476
6477Return the actual login name.
6478[clinic start generated code]*/
6479
Larry Hastings2f936352014-08-05 14:04:04 +10006480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006481os_getlogin_impl(PyObject *module)
6482/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006483{
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006485#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006486 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006487 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006488
6489 if (GetUserNameW(user_name, &num_chars)) {
6490 /* num_chars is the number of unicode chars plus null terminator */
6491 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006492 }
6493 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006494 result = PyErr_SetFromWindowsErr(GetLastError());
6495#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 char *name;
6497 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006498
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 errno = 0;
6500 name = getlogin();
6501 if (name == NULL) {
6502 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006503 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006505 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 }
6507 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006508 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006510#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006511 return result;
6512}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006513#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006514
Larry Hastings2f936352014-08-05 14:04:04 +10006515
Guido van Rossumad0ee831995-03-01 10:34:45 +00006516#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006517/*[clinic input]
6518os.getuid
6519
6520Return the current process's user id.
6521[clinic start generated code]*/
6522
Larry Hastings2f936352014-08-05 14:04:04 +10006523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006524os_getuid_impl(PyObject *module)
6525/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006526{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006527 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006528}
Larry Hastings2f936352014-08-05 14:04:04 +10006529#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006530
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006531
Brian Curtineb24d742010-04-12 17:16:38 +00006532#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006533#define HAVE_KILL
6534#endif /* MS_WINDOWS */
6535
6536#ifdef HAVE_KILL
6537/*[clinic input]
6538os.kill
6539
6540 pid: pid_t
6541 signal: Py_ssize_t
6542 /
6543
6544Kill a process with a signal.
6545[clinic start generated code]*/
6546
Larry Hastings2f936352014-08-05 14:04:04 +10006547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006548os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6549/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006550#ifndef MS_WINDOWS
6551{
6552 if (kill(pid, (int)signal) == -1)
6553 return posix_error();
6554 Py_RETURN_NONE;
6555}
6556#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006557{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006558 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006559 DWORD sig = (DWORD)signal;
6560 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006562
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 /* Console processes which share a common console can be sent CTRL+C or
6564 CTRL+BREAK events, provided they handle said events. */
6565 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006566 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 err = GetLastError();
6568 PyErr_SetFromWindowsErr(err);
6569 }
6570 else
6571 Py_RETURN_NONE;
6572 }
Brian Curtineb24d742010-04-12 17:16:38 +00006573
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6575 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006576 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 if (handle == NULL) {
6578 err = GetLastError();
6579 return PyErr_SetFromWindowsErr(err);
6580 }
Brian Curtineb24d742010-04-12 17:16:38 +00006581
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 if (TerminateProcess(handle, sig) == 0) {
6583 err = GetLastError();
6584 result = PyErr_SetFromWindowsErr(err);
6585 } else {
6586 Py_INCREF(Py_None);
6587 result = Py_None;
6588 }
Brian Curtineb24d742010-04-12 17:16:38 +00006589
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 CloseHandle(handle);
6591 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006592}
Larry Hastings2f936352014-08-05 14:04:04 +10006593#endif /* !MS_WINDOWS */
6594#endif /* HAVE_KILL */
6595
6596
6597#ifdef HAVE_KILLPG
6598/*[clinic input]
6599os.killpg
6600
6601 pgid: pid_t
6602 signal: int
6603 /
6604
6605Kill a process group with a signal.
6606[clinic start generated code]*/
6607
Larry Hastings2f936352014-08-05 14:04:04 +10006608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006609os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6610/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006611{
6612 /* XXX some man pages make the `pgid` parameter an int, others
6613 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6614 take the same type. Moreover, pid_t is always at least as wide as
6615 int (else compilation of this module fails), which is safe. */
6616 if (killpg(pgid, signal) == -1)
6617 return posix_error();
6618 Py_RETURN_NONE;
6619}
6620#endif /* HAVE_KILLPG */
6621
Brian Curtineb24d742010-04-12 17:16:38 +00006622
Guido van Rossumc0125471996-06-28 18:55:32 +00006623#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006624#ifdef HAVE_SYS_LOCK_H
6625#include <sys/lock.h>
6626#endif
6627
Larry Hastings2f936352014-08-05 14:04:04 +10006628/*[clinic input]
6629os.plock
6630 op: int
6631 /
6632
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006633Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006634[clinic start generated code]*/
6635
Larry Hastings2f936352014-08-05 14:04:04 +10006636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006637os_plock_impl(PyObject *module, int op)
6638/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006639{
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 if (plock(op) == -1)
6641 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006642 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006643}
Larry Hastings2f936352014-08-05 14:04:04 +10006644#endif /* HAVE_PLOCK */
6645
Guido van Rossumc0125471996-06-28 18:55:32 +00006646
Guido van Rossumb6775db1994-08-01 11:34:53 +00006647#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006648/*[clinic input]
6649os.setuid
6650
6651 uid: uid_t
6652 /
6653
6654Set the current process's user id.
6655[clinic start generated code]*/
6656
Larry Hastings2f936352014-08-05 14:04:04 +10006657static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006658os_setuid_impl(PyObject *module, uid_t uid)
6659/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006660{
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 if (setuid(uid) < 0)
6662 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006663 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006664}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006665#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006667
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006668#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006669/*[clinic input]
6670os.seteuid
6671
6672 euid: uid_t
6673 /
6674
6675Set the current process's effective user id.
6676[clinic start generated code]*/
6677
Larry Hastings2f936352014-08-05 14:04:04 +10006678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006679os_seteuid_impl(PyObject *module, uid_t euid)
6680/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006681{
6682 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006683 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006684 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006685}
6686#endif /* HAVE_SETEUID */
6687
Larry Hastings2f936352014-08-05 14:04:04 +10006688
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006689#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006690/*[clinic input]
6691os.setegid
6692
6693 egid: gid_t
6694 /
6695
6696Set the current process's effective group id.
6697[clinic start generated code]*/
6698
Larry Hastings2f936352014-08-05 14:04:04 +10006699static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006700os_setegid_impl(PyObject *module, gid_t egid)
6701/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006702{
6703 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006705 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006706}
6707#endif /* HAVE_SETEGID */
6708
Larry Hastings2f936352014-08-05 14:04:04 +10006709
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006710#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006711/*[clinic input]
6712os.setreuid
6713
6714 ruid: uid_t
6715 euid: uid_t
6716 /
6717
6718Set the current process's real and effective user ids.
6719[clinic start generated code]*/
6720
Larry Hastings2f936352014-08-05 14:04:04 +10006721static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006722os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6723/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 if (setreuid(ruid, euid) < 0) {
6726 return posix_error();
6727 } else {
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006728 Py_RETURN_NONE;
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006730}
6731#endif /* HAVE_SETREUID */
6732
Larry Hastings2f936352014-08-05 14:04:04 +10006733
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006734#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006735/*[clinic input]
6736os.setregid
6737
6738 rgid: gid_t
6739 egid: gid_t
6740 /
6741
6742Set the current process's real and effective group ids.
6743[clinic start generated code]*/
6744
Larry Hastings2f936352014-08-05 14:04:04 +10006745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006746os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6747/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006748{
6749 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006750 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006751 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006752}
6753#endif /* HAVE_SETREGID */
6754
Larry Hastings2f936352014-08-05 14:04:04 +10006755
Guido van Rossumb6775db1994-08-01 11:34:53 +00006756#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006757/*[clinic input]
6758os.setgid
6759 gid: gid_t
6760 /
6761
6762Set the current process's group id.
6763[clinic start generated code]*/
6764
Larry Hastings2f936352014-08-05 14:04:04 +10006765static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006766os_setgid_impl(PyObject *module, gid_t gid)
6767/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006768{
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 if (setgid(gid) < 0)
6770 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006771 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006772}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006773#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006774
Larry Hastings2f936352014-08-05 14:04:04 +10006775
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006776#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006777/*[clinic input]
6778os.setgroups
6779
6780 groups: object
6781 /
6782
6783Set the groups of the current process to list.
6784[clinic start generated code]*/
6785
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006787os_setgroups(PyObject *module, PyObject *groups)
6788/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006789{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006790 Py_ssize_t i, len;
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006792
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 if (!PySequence_Check(groups)) {
6794 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6795 return NULL;
6796 }
6797 len = PySequence_Size(groups);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03006798 if (len < 0) {
6799 return NULL;
6800 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 if (len > MAX_GROUPS) {
6802 PyErr_SetString(PyExc_ValueError, "too many groups");
6803 return NULL;
6804 }
6805 for(i = 0; i < len; i++) {
6806 PyObject *elem;
6807 elem = PySequence_GetItem(groups, i);
6808 if (!elem)
6809 return NULL;
6810 if (!PyLong_Check(elem)) {
6811 PyErr_SetString(PyExc_TypeError,
6812 "groups must be integers");
6813 Py_DECREF(elem);
6814 return NULL;
6815 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006816 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 Py_DECREF(elem);
6818 return NULL;
6819 }
6820 }
6821 Py_DECREF(elem);
6822 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006823
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 if (setgroups(len, grouplist) < 0)
6825 return posix_error();
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02006826 Py_RETURN_NONE;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006827}
6828#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006829
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006830#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6831static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006832wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006833{
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 PyObject *result;
6835 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006836 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006837
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 if (pid == -1)
6839 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006840
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 if (struct_rusage == NULL) {
6842 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6843 if (m == NULL)
6844 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006845 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 Py_DECREF(m);
6847 if (struct_rusage == NULL)
6848 return NULL;
6849 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006850
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6852 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6853 if (!result)
6854 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855
6856#ifndef doubletime
6857#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6858#endif
6859
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006861 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006863 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006864#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6866 SET_INT(result, 2, ru->ru_maxrss);
6867 SET_INT(result, 3, ru->ru_ixrss);
6868 SET_INT(result, 4, ru->ru_idrss);
6869 SET_INT(result, 5, ru->ru_isrss);
6870 SET_INT(result, 6, ru->ru_minflt);
6871 SET_INT(result, 7, ru->ru_majflt);
6872 SET_INT(result, 8, ru->ru_nswap);
6873 SET_INT(result, 9, ru->ru_inblock);
6874 SET_INT(result, 10, ru->ru_oublock);
6875 SET_INT(result, 11, ru->ru_msgsnd);
6876 SET_INT(result, 12, ru->ru_msgrcv);
6877 SET_INT(result, 13, ru->ru_nsignals);
6878 SET_INT(result, 14, ru->ru_nvcsw);
6879 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880#undef SET_INT
6881
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 if (PyErr_Occurred()) {
6883 Py_DECREF(result);
6884 return NULL;
6885 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888}
6889#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6890
Larry Hastings2f936352014-08-05 14:04:04 +10006891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006893/*[clinic input]
6894os.wait3
6895
6896 options: int
6897Wait for completion of a child process.
6898
6899Returns a tuple of information about the child process:
6900 (pid, status, rusage)
6901[clinic start generated code]*/
6902
Larry Hastings2f936352014-08-05 14:04:04 +10006903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006904os_wait3_impl(PyObject *module, int options)
6905/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006906{
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006909 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 WAIT_TYPE status;
6911 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006912
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006913 do {
6914 Py_BEGIN_ALLOW_THREADS
6915 pid = wait3(&status, options, &ru);
6916 Py_END_ALLOW_THREADS
6917 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6918 if (pid < 0)
6919 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920
Victor Stinner4195b5c2012-02-08 23:03:19 +01006921 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006922}
6923#endif /* HAVE_WAIT3 */
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006926#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006927/*[clinic input]
6928
6929os.wait4
6930
6931 pid: pid_t
6932 options: int
6933
6934Wait for completion of a specific child process.
6935
6936Returns a tuple of information about the child process:
6937 (pid, status, rusage)
6938[clinic start generated code]*/
6939
Larry Hastings2f936352014-08-05 14:04:04 +10006940static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006941os_wait4_impl(PyObject *module, pid_t pid, int options)
6942/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006943{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006944 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 WAIT_TYPE status;
6948 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006949
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006950 do {
6951 Py_BEGIN_ALLOW_THREADS
6952 res = wait4(pid, &status, options, &ru);
6953 Py_END_ALLOW_THREADS
6954 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6955 if (res < 0)
6956 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006957
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006958 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006959}
6960#endif /* HAVE_WAIT4 */
6961
Larry Hastings2f936352014-08-05 14:04:04 +10006962
Ross Lagerwall7807c352011-03-17 20:20:30 +02006963#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006964/*[clinic input]
6965os.waitid
6966
6967 idtype: idtype_t
6968 Must be one of be P_PID, P_PGID or P_ALL.
6969 id: id_t
6970 The id to wait on.
6971 options: int
6972 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6973 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6974 /
6975
6976Returns the result of waiting for a process or processes.
6977
6978Returns either waitid_result or None if WNOHANG is specified and there are
6979no children in a waitable state.
6980[clinic start generated code]*/
6981
Larry Hastings2f936352014-08-05 14:04:04 +10006982static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006983os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6984/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006985{
6986 PyObject *result;
6987 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006988 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006989 siginfo_t si;
6990 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006991
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006992 do {
6993 Py_BEGIN_ALLOW_THREADS
6994 res = waitid(idtype, id, &si, options);
6995 Py_END_ALLOW_THREADS
6996 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6997 if (res < 0)
6998 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006999
7000 if (si.si_pid == 0)
7001 Py_RETURN_NONE;
7002
7003 result = PyStructSequence_New(&WaitidResultType);
7004 if (!result)
7005 return NULL;
7006
7007 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007008 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007009 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7010 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7011 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7012 if (PyErr_Occurred()) {
7013 Py_DECREF(result);
7014 return NULL;
7015 }
7016
7017 return result;
7018}
Larry Hastings2f936352014-08-05 14:04:04 +10007019#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007020
Larry Hastings2f936352014-08-05 14:04:04 +10007021
7022#if defined(HAVE_WAITPID)
7023/*[clinic input]
7024os.waitpid
7025 pid: pid_t
7026 options: int
7027 /
7028
7029Wait for completion of a given child process.
7030
7031Returns a tuple of information regarding the child process:
7032 (pid, status)
7033
7034The options argument is ignored on Windows.
7035[clinic start generated code]*/
7036
Larry Hastings2f936352014-08-05 14:04:04 +10007037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007038os_waitpid_impl(PyObject *module, pid_t pid, int options)
7039/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007040{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007041 pid_t res;
7042 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 WAIT_TYPE status;
7044 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007045
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007046 do {
7047 Py_BEGIN_ALLOW_THREADS
7048 res = waitpid(pid, &status, options);
7049 Py_END_ALLOW_THREADS
7050 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7051 if (res < 0)
7052 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007053
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007054 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007055}
Tim Petersab034fa2002-02-01 11:27:43 +00007056#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007057/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007058/*[clinic input]
7059os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007060 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007061 options: int
7062 /
7063
7064Wait for completion of a given process.
7065
7066Returns a tuple of information regarding the process:
7067 (pid, status << 8)
7068
7069The options argument is ignored on Windows.
7070[clinic start generated code]*/
7071
Larry Hastings2f936352014-08-05 14:04:04 +10007072static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007073os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007074/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007075{
7076 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007077 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007078 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007079
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007080 do {
7081 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007082 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007083 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007084 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007085 Py_END_ALLOW_THREADS
7086 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007087 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007088 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007089
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007091 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007092}
Larry Hastings2f936352014-08-05 14:04:04 +10007093#endif
7094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007095
Guido van Rossumad0ee831995-03-01 10:34:45 +00007096#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007097/*[clinic input]
7098os.wait
7099
7100Wait for completion of a child process.
7101
7102Returns a tuple of information about the child process:
7103 (pid, status)
7104[clinic start generated code]*/
7105
Larry Hastings2f936352014-08-05 14:04:04 +10007106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007107os_wait_impl(PyObject *module)
7108/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007109{
Victor Stinner8c62be82010-05-06 00:08:46 +00007110 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007111 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 WAIT_TYPE status;
7113 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007114
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007115 do {
7116 Py_BEGIN_ALLOW_THREADS
7117 pid = wait(&status);
7118 Py_END_ALLOW_THREADS
7119 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7120 if (pid < 0)
7121 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007122
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007124}
Larry Hastings2f936352014-08-05 14:04:04 +10007125#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007127
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7129PyDoc_STRVAR(readlink__doc__,
7130"readlink(path, *, dir_fd=None) -> path\n\n\
7131Return a string representing the path to which the symbolic link points.\n\
7132\n\
7133If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7134 and path should be relative; path will then be relative to that directory.\n\
7135dir_fd may not be implemented on your platform.\n\
7136 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007137#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007138
Guido van Rossumb6775db1994-08-01 11:34:53 +00007139#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007140
Larry Hastings2f936352014-08-05 14:04:04 +10007141/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007142static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007144{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007145 path_t path;
7146 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007147 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148 ssize_t length;
7149 PyObject *return_value = NULL;
7150 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007151
Larry Hastings9cf065c2012-06-22 16:30:09 -07007152 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007153 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7155 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007156 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007158
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160#ifdef HAVE_READLINKAT
7161 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007162 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007163 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007165 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166 Py_END_ALLOW_THREADS
7167
7168 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007169 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170 goto exit;
7171 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007172 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007173
7174 if (PyUnicode_Check(path.object))
7175 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7176 else
7177 return_value = PyBytes_FromStringAndSize(buffer, length);
7178exit:
7179 path_cleanup(&path);
7180 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007181}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007182
Guido van Rossumb6775db1994-08-01 11:34:53 +00007183#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007184
Larry Hastings2f936352014-08-05 14:04:04 +10007185#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7186
7187static PyObject *
7188win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7189{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007190 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007191 DWORD n_bytes_returned;
7192 DWORD io_result;
7193 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007194 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007195 HANDLE reparse_point_handle;
7196
Martin Panter70214ad2016-08-04 02:38:59 +00007197 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7198 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007199 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007200
7201 static char *keywords[] = {"path", "dir_fd", NULL};
7202
7203 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7204 &po,
7205 dir_fd_unavailable, &dir_fd
7206 ))
7207 return NULL;
7208
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03007209 path = _PyUnicode_AsUnicode(po);
Larry Hastings2f936352014-08-05 14:04:04 +10007210 if (path == NULL)
7211 return NULL;
7212
7213 /* First get a handle to the reparse point */
7214 Py_BEGIN_ALLOW_THREADS
7215 reparse_point_handle = CreateFileW(
7216 path,
7217 0,
7218 0,
7219 0,
7220 OPEN_EXISTING,
7221 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7222 0);
7223 Py_END_ALLOW_THREADS
7224
7225 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7226 return win32_error_object("readlink", po);
7227
7228 Py_BEGIN_ALLOW_THREADS
7229 /* New call DeviceIoControl to read the reparse point */
7230 io_result = DeviceIoControl(
7231 reparse_point_handle,
7232 FSCTL_GET_REPARSE_POINT,
7233 0, 0, /* in buffer */
7234 target_buffer, sizeof(target_buffer),
7235 &n_bytes_returned,
7236 0 /* we're not using OVERLAPPED_IO */
7237 );
7238 CloseHandle(reparse_point_handle);
7239 Py_END_ALLOW_THREADS
7240
7241 if (io_result==0)
7242 return win32_error_object("readlink", po);
7243
7244 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7245 {
7246 PyErr_SetString(PyExc_ValueError,
7247 "not a symbolic link");
7248 return NULL;
7249 }
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007250 print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
7251 rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
Larry Hastings2f936352014-08-05 14:04:04 +10007252
7253 result = PyUnicode_FromWideChar(print_name,
Miss Islington (bot)74ebbae2018-02-12 13:39:42 -08007254 rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
Larry Hastings2f936352014-08-05 14:04:04 +10007255 return result;
7256}
7257
7258#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7259
7260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007261
Larry Hastings9cf065c2012-06-22 16:30:09 -07007262#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007263
7264#if defined(MS_WINDOWS)
7265
7266/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007267static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007268
Larry Hastings9cf065c2012-06-22 16:30:09 -07007269static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007270check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007271{
7272 HINSTANCE hKernel32;
7273 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007274 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007275 return 1;
7276 hKernel32 = GetModuleHandleW(L"KERNEL32");
7277 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7278 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007279 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007280}
7281
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007282/* Remove the last portion of the path - return 0 on success */
7283static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007284_dirnameW(WCHAR *path)
7285{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007286 WCHAR *ptr;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007287 size_t length = wcsnlen_s(path, MAX_PATH);
7288 if (length == MAX_PATH) {
7289 return -1;
7290 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291
7292 /* walk the path from the end until a backslash is encountered */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007293 for(ptr = path + length; ptr != path; ptr--) {
7294 if (*ptr == L'\\' || *ptr == L'/') {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295 break;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007296 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297 }
7298 *ptr = 0;
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007299 return 0;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007300}
7301
Victor Stinner31b3b922013-06-05 01:49:17 +02007302/* Is this path absolute? */
7303static int
7304_is_absW(const WCHAR *path)
7305{
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007306 return path[0] == L'\\' || path[0] == L'/' ||
7307 (path[0] && path[1] == L':');
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308}
7309
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007310/* join root and rest with a backslash - return 0 on success */
7311static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007312_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7313{
Victor Stinner31b3b922013-06-05 01:49:17 +02007314 if (_is_absW(rest)) {
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007315 return wcscpy_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007316 }
7317
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007318 if (wcscpy_s(dest_path, MAX_PATH, root)) {
7319 return -1;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320 }
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007321
7322 if (dest_path[0] && wcscat_s(dest_path, MAX_PATH, L"\\")) {
7323 return -1;
7324 }
7325
7326 return wcscat_s(dest_path, MAX_PATH, rest);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007327}
7328
Victor Stinner31b3b922013-06-05 01:49:17 +02007329/* Return True if the path at src relative to dest is a directory */
7330static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007331_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007332{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333 WIN32_FILE_ATTRIBUTE_DATA src_info;
7334 WCHAR dest_parent[MAX_PATH];
7335 WCHAR src_resolved[MAX_PATH] = L"";
7336
7337 /* dest_parent = os.path.dirname(dest) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007338 if (wcscpy_s(dest_parent, MAX_PATH, dest) ||
7339 _dirnameW(dest_parent)) {
7340 return 0;
7341 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007342 /* src_resolved = os.path.join(dest_parent, src) */
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007343 if (_joinW(src_resolved, dest_parent, src)) {
7344 return 0;
7345 }
Jason R. Coombs3a092862013-05-27 23:21:28 -04007346 return (
7347 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7348 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7349 );
7350}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007351#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007352
Larry Hastings2f936352014-08-05 14:04:04 +10007353
7354/*[clinic input]
7355os.symlink
7356 src: path_t
7357 dst: path_t
7358 target_is_directory: bool = False
7359 *
7360 dir_fd: dir_fd(requires='symlinkat')=None
7361
7362# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7363
7364Create a symbolic link pointing to src named dst.
7365
7366target_is_directory is required on Windows if the target is to be
7367 interpreted as a directory. (On Windows, symlink requires
7368 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7369 target_is_directory is ignored on non-Windows platforms.
7370
7371If dir_fd is not None, it should be a file descriptor open to a directory,
7372 and path should be relative; path will then be relative to that directory.
7373dir_fd may not be implemented on your platform.
7374 If it is unavailable, using it will raise a NotImplementedError.
7375
7376[clinic start generated code]*/
7377
Larry Hastings2f936352014-08-05 14:04:04 +10007378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007379os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007380 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007381/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007382{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007383#ifdef MS_WINDOWS
7384 DWORD result;
7385#else
7386 int result;
7387#endif
7388
Larry Hastings9cf065c2012-06-22 16:30:09 -07007389#ifdef MS_WINDOWS
7390 if (!check_CreateSymbolicLink()) {
7391 PyErr_SetString(PyExc_NotImplementedError,
7392 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007393 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007394 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395 if (!win32_can_symlink) {
7396 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007397 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007398 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399#endif
7400
Larry Hastings9cf065c2012-06-22 16:30:09 -07007401#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007402
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007404 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07007405 /* if src is a directory, ensure target_is_directory==1 */
7406 target_is_directory |= _check_dirW(src->wide, dst->wide);
7407 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7408 target_is_directory);
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007409 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07007410 Py_END_ALLOW_THREADS
7411
Larry Hastings2f936352014-08-05 14:04:04 +10007412 if (!result)
7413 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007414
7415#else
7416
Miss Islington (bot)96fdbac2018-03-05 15:12:56 -08007417 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
7418 PyErr_SetString(PyExc_ValueError,
7419 "symlink: src and dst must be the same type");
7420 return NULL;
7421 }
7422
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423 Py_BEGIN_ALLOW_THREADS
7424#if HAVE_SYMLINKAT
7425 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007426 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007427 else
7428#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007429 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 Py_END_ALLOW_THREADS
7431
Larry Hastings2f936352014-08-05 14:04:04 +10007432 if (result)
7433 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434#endif
7435
Larry Hastings2f936352014-08-05 14:04:04 +10007436 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007437}
7438#endif /* HAVE_SYMLINK */
7439
Larry Hastings9cf065c2012-06-22 16:30:09 -07007440
Brian Curtind40e6f72010-07-08 21:39:08 +00007441
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007442
Larry Hastings605a62d2012-06-24 04:33:36 -07007443static PyStructSequence_Field times_result_fields[] = {
7444 {"user", "user time"},
7445 {"system", "system time"},
7446 {"children_user", "user time of children"},
7447 {"children_system", "system time of children"},
7448 {"elapsed", "elapsed time since an arbitrary point in the past"},
7449 {NULL}
7450};
7451
7452PyDoc_STRVAR(times_result__doc__,
7453"times_result: Result from os.times().\n\n\
7454This object may be accessed either as a tuple of\n\
7455 (user, system, children_user, children_system, elapsed),\n\
7456or via the attributes user, system, children_user, children_system,\n\
7457and elapsed.\n\
7458\n\
7459See os.times for more information.");
7460
7461static PyStructSequence_Desc times_result_desc = {
7462 "times_result", /* name */
7463 times_result__doc__, /* doc */
7464 times_result_fields,
7465 5
7466};
7467
7468static PyTypeObject TimesResultType;
7469
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007470#ifdef MS_WINDOWS
7471#define HAVE_TIMES /* mandatory, for the method table */
7472#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007473
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007474#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007475
7476static PyObject *
7477build_times_result(double user, double system,
7478 double children_user, double children_system,
7479 double elapsed)
7480{
7481 PyObject *value = PyStructSequence_New(&TimesResultType);
7482 if (value == NULL)
7483 return NULL;
7484
7485#define SET(i, field) \
7486 { \
7487 PyObject *o = PyFloat_FromDouble(field); \
7488 if (!o) { \
7489 Py_DECREF(value); \
7490 return NULL; \
7491 } \
7492 PyStructSequence_SET_ITEM(value, i, o); \
7493 } \
7494
7495 SET(0, user);
7496 SET(1, system);
7497 SET(2, children_user);
7498 SET(3, children_system);
7499 SET(4, elapsed);
7500
7501#undef SET
7502
7503 return value;
7504}
7505
Larry Hastings605a62d2012-06-24 04:33:36 -07007506
Larry Hastings2f936352014-08-05 14:04:04 +10007507#ifndef MS_WINDOWS
7508#define NEED_TICKS_PER_SECOND
7509static long ticks_per_second = -1;
7510#endif /* MS_WINDOWS */
7511
7512/*[clinic input]
7513os.times
7514
7515Return a collection containing process timing information.
7516
7517The object returned behaves like a named tuple with these fields:
7518 (utime, stime, cutime, cstime, elapsed_time)
7519All fields are floating point numbers.
7520[clinic start generated code]*/
7521
Larry Hastings2f936352014-08-05 14:04:04 +10007522static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007523os_times_impl(PyObject *module)
7524/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007525#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007526{
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 FILETIME create, exit, kernel, user;
7528 HANDLE hProc;
7529 hProc = GetCurrentProcess();
7530 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7531 /* The fields of a FILETIME structure are the hi and lo part
7532 of a 64-bit value expressed in 100 nanosecond units.
7533 1e7 is one second in such units; 1e-7 the inverse.
7534 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7535 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007536 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007537 (double)(user.dwHighDateTime*429.4967296 +
7538 user.dwLowDateTime*1e-7),
7539 (double)(kernel.dwHighDateTime*429.4967296 +
7540 kernel.dwLowDateTime*1e-7),
7541 (double)0,
7542 (double)0,
7543 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007544}
Larry Hastings2f936352014-08-05 14:04:04 +10007545#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007546{
Larry Hastings2f936352014-08-05 14:04:04 +10007547
7548
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007549 struct tms t;
7550 clock_t c;
7551 errno = 0;
7552 c = times(&t);
7553 if (c == (clock_t) -1)
7554 return posix_error();
7555 return build_times_result(
7556 (double)t.tms_utime / ticks_per_second,
7557 (double)t.tms_stime / ticks_per_second,
7558 (double)t.tms_cutime / ticks_per_second,
7559 (double)t.tms_cstime / ticks_per_second,
7560 (double)c / ticks_per_second);
7561}
Larry Hastings2f936352014-08-05 14:04:04 +10007562#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007563#endif /* HAVE_TIMES */
7564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007565
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007566#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007567/*[clinic input]
7568os.getsid
7569
7570 pid: pid_t
7571 /
7572
7573Call the system call getsid(pid) and return the result.
7574[clinic start generated code]*/
7575
Larry Hastings2f936352014-08-05 14:04:04 +10007576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007577os_getsid_impl(PyObject *module, pid_t pid)
7578/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007579{
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007581 sid = getsid(pid);
7582 if (sid < 0)
7583 return posix_error();
7584 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007585}
7586#endif /* HAVE_GETSID */
7587
7588
Guido van Rossumb6775db1994-08-01 11:34:53 +00007589#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007590/*[clinic input]
7591os.setsid
7592
7593Call the system call setsid().
7594[clinic start generated code]*/
7595
Larry Hastings2f936352014-08-05 14:04:04 +10007596static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007597os_setsid_impl(PyObject *module)
7598/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007599{
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 if (setsid() < 0)
7601 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007602 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007604#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007605
Larry Hastings2f936352014-08-05 14:04:04 +10007606
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007608/*[clinic input]
7609os.setpgid
7610
7611 pid: pid_t
7612 pgrp: pid_t
7613 /
7614
7615Call the system call setpgid(pid, pgrp).
7616[clinic start generated code]*/
7617
Larry Hastings2f936352014-08-05 14:04:04 +10007618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007619os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7620/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007621{
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 if (setpgid(pid, pgrp) < 0)
7623 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007624 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007625}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007626#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007627
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007628
Guido van Rossumb6775db1994-08-01 11:34:53 +00007629#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007630/*[clinic input]
7631os.tcgetpgrp
7632
7633 fd: int
7634 /
7635
7636Return the process group associated with the terminal specified by fd.
7637[clinic start generated code]*/
7638
Larry Hastings2f936352014-08-05 14:04:04 +10007639static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007640os_tcgetpgrp_impl(PyObject *module, int fd)
7641/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007642{
7643 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 if (pgid < 0)
7645 return posix_error();
7646 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007647}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007648#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007650
Guido van Rossumb6775db1994-08-01 11:34:53 +00007651#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007652/*[clinic input]
7653os.tcsetpgrp
7654
7655 fd: int
7656 pgid: pid_t
7657 /
7658
7659Set the process group associated with the terminal specified by fd.
7660[clinic start generated code]*/
7661
Larry Hastings2f936352014-08-05 14:04:04 +10007662static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007663os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7664/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007665{
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 if (tcsetpgrp(fd, pgid) < 0)
7667 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007668 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007669}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007670#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007671
Guido van Rossum687dd131993-05-17 08:34:16 +00007672/* Functions acting on file descriptors */
7673
Victor Stinnerdaf45552013-08-28 00:53:59 +02007674#ifdef O_CLOEXEC
7675extern int _Py_open_cloexec_works;
7676#endif
7677
Larry Hastings2f936352014-08-05 14:04:04 +10007678
7679/*[clinic input]
7680os.open -> int
7681 path: path_t
7682 flags: int
7683 mode: int = 0o777
7684 *
7685 dir_fd: dir_fd(requires='openat') = None
7686
7687# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7688
7689Open a file for low level IO. Returns a file descriptor (integer).
7690
7691If dir_fd is not None, it should be a file descriptor open to a directory,
7692 and path should be relative; path will then be relative to that directory.
7693dir_fd may not be implemented on your platform.
7694 If it is unavailable, using it will raise a NotImplementedError.
7695[clinic start generated code]*/
7696
Larry Hastings2f936352014-08-05 14:04:04 +10007697static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007698os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7699/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007700{
7701 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007703
Victor Stinnerdaf45552013-08-28 00:53:59 +02007704#ifdef O_CLOEXEC
7705 int *atomic_flag_works = &_Py_open_cloexec_works;
7706#elif !defined(MS_WINDOWS)
7707 int *atomic_flag_works = NULL;
7708#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007709
Victor Stinnerdaf45552013-08-28 00:53:59 +02007710#ifdef MS_WINDOWS
7711 flags |= O_NOINHERIT;
7712#elif defined(O_CLOEXEC)
7713 flags |= O_CLOEXEC;
7714#endif
7715
Steve Dower8fc89802015-04-12 00:26:27 -04007716 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007717 do {
7718 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007719#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007720 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007721#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007722#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007723 if (dir_fd != DEFAULT_DIR_FD)
7724 fd = openat(dir_fd, path->narrow, flags, mode);
7725 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007726#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007728#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007729 Py_END_ALLOW_THREADS
7730 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007731 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007732
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007733 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007734 if (!async_err)
7735 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007736 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007737 }
7738
Victor Stinnerdaf45552013-08-28 00:53:59 +02007739#ifndef MS_WINDOWS
7740 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7741 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007742 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007743 }
7744#endif
7745
Larry Hastings2f936352014-08-05 14:04:04 +10007746 return fd;
7747}
7748
7749
7750/*[clinic input]
7751os.close
7752
7753 fd: int
7754
7755Close a file descriptor.
7756[clinic start generated code]*/
7757
Barry Warsaw53699e91996-12-10 23:23:01 +00007758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007759os_close_impl(PyObject *module, int fd)
7760/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007761{
Larry Hastings2f936352014-08-05 14:04:04 +10007762 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007763 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7764 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7765 * for more details.
7766 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007768 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007770 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007771 Py_END_ALLOW_THREADS
7772 if (res < 0)
7773 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007774 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007775}
7776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007777
Larry Hastings2f936352014-08-05 14:04:04 +10007778/*[clinic input]
7779os.closerange
7780
7781 fd_low: int
7782 fd_high: int
7783 /
7784
7785Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7786[clinic start generated code]*/
7787
Larry Hastings2f936352014-08-05 14:04:04 +10007788static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007789os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7790/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007791{
7792 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007794 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007795 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007796 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007797 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 Py_END_ALLOW_THREADS
7799 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007800}
7801
7802
Larry Hastings2f936352014-08-05 14:04:04 +10007803/*[clinic input]
7804os.dup -> int
7805
7806 fd: int
7807 /
7808
7809Return a duplicate of a file descriptor.
7810[clinic start generated code]*/
7811
Larry Hastings2f936352014-08-05 14:04:04 +10007812static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007813os_dup_impl(PyObject *module, int fd)
7814/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007815{
7816 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007817}
7818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007819
Larry Hastings2f936352014-08-05 14:04:04 +10007820/*[clinic input]
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007821os.dup2 -> int
Larry Hastings2f936352014-08-05 14:04:04 +10007822 fd: int
7823 fd2: int
7824 inheritable: bool=True
7825
7826Duplicate file descriptor.
7827[clinic start generated code]*/
7828
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007829static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007830os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007831/*[clinic end generated code: output=bc059d34a73404d1 input=c3cddda8922b038d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007832{
Stéphane Wirtel3d86e482018-01-30 07:04:36 +01007833 int res = 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007834#if defined(HAVE_DUP3) && \
7835 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7836 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
Miss Islington (bot)bab4fe32018-02-19 23:46:47 -08007837 static int dup3_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007838#endif
7839
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007840 if (fd < 0 || fd2 < 0) {
7841 posix_error();
7842 return -1;
7843 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007844
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007845 /* dup2() can fail with EINTR if the target FD is already open, because it
7846 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7847 * upon close(), and therefore below.
7848 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007849#ifdef MS_WINDOWS
7850 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007851 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007853 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007854 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007855 if (res < 0) {
7856 posix_error();
7857 return -1;
7858 }
7859 res = fd2; // msvcrt dup2 returns 0 on success.
Victor Stinnerdaf45552013-08-28 00:53:59 +02007860
7861 /* Character files like console cannot be make non-inheritable */
7862 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7863 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007864 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007865 }
7866
7867#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7868 Py_BEGIN_ALLOW_THREADS
7869 if (!inheritable)
7870 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7871 else
7872 res = dup2(fd, fd2);
7873 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007874 if (res < 0) {
7875 posix_error();
7876 return -1;
7877 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007878
7879#else
7880
7881#ifdef HAVE_DUP3
7882 if (!inheritable && dup3_works != 0) {
7883 Py_BEGIN_ALLOW_THREADS
7884 res = dup3(fd, fd2, O_CLOEXEC);
7885 Py_END_ALLOW_THREADS
7886 if (res < 0) {
7887 if (dup3_works == -1)
7888 dup3_works = (errno != ENOSYS);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007889 if (dup3_works) {
7890 posix_error();
7891 return -1;
7892 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007893 }
7894 }
7895
7896 if (inheritable || dup3_works == 0)
7897 {
7898#endif
7899 Py_BEGIN_ALLOW_THREADS
7900 res = dup2(fd, fd2);
7901 Py_END_ALLOW_THREADS
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007902 if (res < 0) {
7903 posix_error();
7904 return -1;
7905 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02007906
7907 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7908 close(fd2);
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007909 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007910 }
7911#ifdef HAVE_DUP3
7912 }
7913#endif
7914
7915#endif
7916
Benjamin Petersonbbdb17d2017-12-29 13:13:06 -08007917 return res;
Guido van Rossum687dd131993-05-17 08:34:16 +00007918}
7919
Larry Hastings2f936352014-08-05 14:04:04 +10007920
Ross Lagerwall7807c352011-03-17 20:20:30 +02007921#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007922/*[clinic input]
7923os.lockf
7924
7925 fd: int
7926 An open file descriptor.
7927 command: int
7928 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7929 length: Py_off_t
7930 The number of bytes to lock, starting at the current position.
7931 /
7932
7933Apply, test or remove a POSIX lock on an open file descriptor.
7934
7935[clinic start generated code]*/
7936
Larry Hastings2f936352014-08-05 14:04:04 +10007937static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007938os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7939/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007940{
7941 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007942
7943 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007944 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007945 Py_END_ALLOW_THREADS
7946
7947 if (res < 0)
7948 return posix_error();
7949
7950 Py_RETURN_NONE;
7951}
Larry Hastings2f936352014-08-05 14:04:04 +10007952#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007954
Larry Hastings2f936352014-08-05 14:04:04 +10007955/*[clinic input]
7956os.lseek -> Py_off_t
7957
7958 fd: int
7959 position: Py_off_t
7960 how: int
7961 /
7962
7963Set the position of a file descriptor. Return the new position.
7964
7965Return the new cursor position in number of bytes
7966relative to the beginning of the file.
7967[clinic start generated code]*/
7968
Larry Hastings2f936352014-08-05 14:04:04 +10007969static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007970os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7971/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007972{
7973 Py_off_t result;
7974
Guido van Rossum687dd131993-05-17 08:34:16 +00007975#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7977 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007978 case 0: how = SEEK_SET; break;
7979 case 1: how = SEEK_CUR; break;
7980 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007982#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007983
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007985 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007986
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007988 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007989#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007990 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007991#else
Larry Hastings2f936352014-08-05 14:04:04 +10007992 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007993#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007994 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007996 if (result < 0)
7997 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007998
Larry Hastings2f936352014-08-05 14:04:04 +10007999 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008000}
8001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008002
Larry Hastings2f936352014-08-05 14:04:04 +10008003/*[clinic input]
8004os.read
8005 fd: int
8006 length: Py_ssize_t
8007 /
8008
8009Read from a file descriptor. Returns a bytes object.
8010[clinic start generated code]*/
8011
Larry Hastings2f936352014-08-05 14:04:04 +10008012static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008013os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8014/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008015{
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 Py_ssize_t n;
8017 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008018
8019 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 errno = EINVAL;
8021 return posix_error();
8022 }
Larry Hastings2f936352014-08-05 14:04:04 +10008023
8024#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008025 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008026 if (length > INT_MAX)
8027 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008028#endif
8029
8030 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 if (buffer == NULL)
8032 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008033
Victor Stinner66aab0c2015-03-19 22:53:20 +01008034 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8035 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008037 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008038 }
Larry Hastings2f936352014-08-05 14:04:04 +10008039
8040 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008041 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008042
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008044}
8045
Ross Lagerwall7807c352011-03-17 20:20:30 +02008046#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008047 || defined(__APPLE__))) \
8048 || defined(HAVE_READV) || defined(HAVE_PREADV) || defined (HAVE_PREADV2) \
8049 || defined(HAVE_WRITEV) || defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8050static int
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008051iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008052{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008053 Py_ssize_t i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008054
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055 *iov = PyMem_New(struct iovec, cnt);
8056 if (*iov == NULL) {
8057 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008058 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008060
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 *buf = PyMem_New(Py_buffer, cnt);
8062 if (*buf == NULL) {
8063 PyMem_Del(*iov);
8064 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008065 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 }
8067
8068 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008069 PyObject *item = PySequence_GetItem(seq, i);
8070 if (item == NULL)
8071 goto fail;
8072 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8073 Py_DECREF(item);
8074 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008076 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077 (*iov)[i].iov_base = (*buf)[i].buf;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008078 (*iov)[i].iov_len = (*buf)[i].len;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 }
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008080 return 0;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008081
8082fail:
8083 PyMem_Del(*iov);
8084 for (j = 0; j < i; j++) {
8085 PyBuffer_Release(&(*buf)[j]);
8086 }
8087 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008088 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008089}
8090
8091static void
8092iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8093{
8094 int i;
8095 PyMem_Del(iov);
8096 for (i = 0; i < cnt; i++) {
8097 PyBuffer_Release(&buf[i]);
8098 }
8099 PyMem_Del(buf);
8100}
8101#endif
8102
Larry Hastings2f936352014-08-05 14:04:04 +10008103
Ross Lagerwall7807c352011-03-17 20:20:30 +02008104#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008105/*[clinic input]
8106os.readv -> Py_ssize_t
8107
8108 fd: int
8109 buffers: object
8110 /
8111
8112Read from a file descriptor fd into an iterable of buffers.
8113
8114The buffers should be mutable buffers accepting bytes.
8115readv will transfer data into each buffer until it is full
8116and then move on to the next buffer in the sequence to hold
8117the rest of the data.
8118
8119readv returns the total number of bytes read,
8120which may be less than the total capacity of all the buffers.
8121[clinic start generated code]*/
8122
Larry Hastings2f936352014-08-05 14:04:04 +10008123static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008124os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8125/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008126{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008127 Py_ssize_t cnt, n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008128 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008129 struct iovec *iov;
8130 Py_buffer *buf;
8131
Larry Hastings2f936352014-08-05 14:04:04 +10008132 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133 PyErr_SetString(PyExc_TypeError,
8134 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008135 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008137
Larry Hastings2f936352014-08-05 14:04:04 +10008138 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008139 if (cnt < 0)
8140 return -1;
Larry Hastings2f936352014-08-05 14:04:04 +10008141
8142 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8143 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008144
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008145 do {
8146 Py_BEGIN_ALLOW_THREADS
8147 n = readv(fd, iov, cnt);
8148 Py_END_ALLOW_THREADS
8149 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150
8151 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008152 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008153 if (!async_err)
8154 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008155 return -1;
8156 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008157
Larry Hastings2f936352014-08-05 14:04:04 +10008158 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008159}
Larry Hastings2f936352014-08-05 14:04:04 +10008160#endif /* HAVE_READV */
8161
Ross Lagerwall7807c352011-03-17 20:20:30 +02008162
8163#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008164/*[clinic input]
8165# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8166os.pread
8167
8168 fd: int
8169 length: int
8170 offset: Py_off_t
8171 /
8172
8173Read a number of bytes from a file descriptor starting at a particular offset.
8174
8175Read length bytes from file descriptor fd, starting at offset bytes from
8176the beginning of the file. The file offset remains unchanged.
8177[clinic start generated code]*/
8178
Larry Hastings2f936352014-08-05 14:04:04 +10008179static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008180os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8181/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008182{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008183 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008184 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008185 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008186
Larry Hastings2f936352014-08-05 14:04:04 +10008187 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008188 errno = EINVAL;
8189 return posix_error();
8190 }
Larry Hastings2f936352014-08-05 14:04:04 +10008191 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192 if (buffer == NULL)
8193 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008194
8195 do {
8196 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008197 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008198 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008199 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008200 Py_END_ALLOW_THREADS
8201 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8202
Ross Lagerwall7807c352011-03-17 20:20:30 +02008203 if (n < 0) {
8204 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008205 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008206 }
Larry Hastings2f936352014-08-05 14:04:04 +10008207 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208 _PyBytes_Resize(&buffer, n);
8209 return buffer;
8210}
Larry Hastings2f936352014-08-05 14:04:04 +10008211#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008212
Pablo Galindo4defba32018-01-27 16:16:37 +00008213#if defined(HAVE_PREADV) || defined (HAVE_PREADV2)
8214/*[clinic input]
8215os.preadv -> Py_ssize_t
8216
8217 fd: int
8218 buffers: object
8219 offset: Py_off_t
8220 flags: int = 0
8221 /
8222
8223Reads from a file descriptor into a number of mutable bytes-like objects.
8224
8225Combines the functionality of readv() and pread(). As readv(), it will
8226transfer data into each buffer until it is full and then move on to the next
8227buffer in the sequence to hold the rest of the data. Its fourth argument,
8228specifies the file offset at which the input operation is to be performed. It
8229will return the total number of bytes read (which can be less than the total
8230capacity of all the objects).
8231
8232The flags argument contains a bitwise OR of zero or more of the following flags:
8233
8234- RWF_HIPRI
8235- RWF_NOWAIT
8236
8237Using non-zero flags requires Linux 4.6 or newer.
8238[clinic start generated code]*/
8239
8240static Py_ssize_t
8241os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8242 int flags)
8243/*[clinic end generated code: output=26fc9c6e58e7ada5 input=4173919dc1f7ed99]*/
8244{
8245 Py_ssize_t cnt, n;
8246 int async_err = 0;
8247 struct iovec *iov;
8248 Py_buffer *buf;
8249
8250 if (!PySequence_Check(buffers)) {
8251 PyErr_SetString(PyExc_TypeError,
8252 "preadv2() arg 2 must be a sequence");
8253 return -1;
8254 }
8255
8256 cnt = PySequence_Size(buffers);
8257 if (cnt < 0) {
8258 return -1;
8259 }
8260
8261#ifndef HAVE_PREADV2
8262 if(flags != 0) {
8263 argument_unavailable_error("preadv2", "flags");
8264 return -1;
8265 }
8266#endif
8267
8268 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) {
8269 return -1;
8270 }
8271#ifdef HAVE_PREADV2
8272 do {
8273 Py_BEGIN_ALLOW_THREADS
8274 _Py_BEGIN_SUPPRESS_IPH
8275 n = preadv2(fd, iov, cnt, offset, flags);
8276 _Py_END_SUPPRESS_IPH
8277 Py_END_ALLOW_THREADS
8278 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8279#else
8280 do {
8281 Py_BEGIN_ALLOW_THREADS
8282 _Py_BEGIN_SUPPRESS_IPH
8283 n = preadv(fd, iov, cnt, offset);
8284 _Py_END_SUPPRESS_IPH
8285 Py_END_ALLOW_THREADS
8286 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8287#endif
8288
8289 iov_cleanup(iov, buf, cnt);
8290 if (n < 0) {
8291 if (!async_err) {
8292 posix_error();
8293 }
8294 return -1;
8295 }
8296
8297 return n;
8298}
8299#endif /* HAVE_PREADV */
8300
Larry Hastings2f936352014-08-05 14:04:04 +10008301
8302/*[clinic input]
8303os.write -> Py_ssize_t
8304
8305 fd: int
8306 data: Py_buffer
8307 /
8308
8309Write a bytes object to a file descriptor.
8310[clinic start generated code]*/
8311
Larry Hastings2f936352014-08-05 14:04:04 +10008312static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008313os_write_impl(PyObject *module, int fd, Py_buffer *data)
8314/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008315{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008316 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008317}
8318
8319#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008320PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008321"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008322sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008324Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325
Larry Hastings2f936352014-08-05 14:04:04 +10008326/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008327static PyObject *
8328posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8329{
8330 int in, out;
8331 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008332 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008333 off_t offset;
8334
8335#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8336#ifndef __APPLE__
8337 Py_ssize_t len;
8338#endif
8339 PyObject *headers = NULL, *trailers = NULL;
8340 Py_buffer *hbuf, *tbuf;
8341 off_t sbytes;
8342 struct sf_hdtr sf;
8343 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008344 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008345 static char *keywords[] = {"out", "in",
8346 "offset", "count",
8347 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008348
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008349 sf.headers = NULL;
8350 sf.trailers = NULL;
8351
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008352#ifdef __APPLE__
8353 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008354 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008355#else
8356 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008357 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008358#endif
8359 &headers, &trailers, &flags))
8360 return NULL;
8361 if (headers != NULL) {
8362 if (!PySequence_Check(headers)) {
8363 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008364 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008365 return NULL;
8366 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008367 Py_ssize_t i = PySequence_Size(headers);
8368 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008369 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008370 if (i > INT_MAX) {
8371 PyErr_SetString(PyExc_OverflowError,
8372 "sendfile() header is too large");
8373 return NULL;
8374 }
8375 if (i > 0) {
8376 sf.hdr_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008377 if (iov_setup(&(sf.headers), &hbuf,
8378 headers, sf.hdr_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008379 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008380#ifdef __APPLE__
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008381 for (i = 0; i < sf.hdr_cnt; i++) {
8382 Py_ssize_t blen = sf.headers[i].iov_len;
8383# define OFF_T_MAX 0x7fffffffffffffff
8384 if (sbytes >= OFF_T_MAX - blen) {
8385 PyErr_SetString(PyExc_OverflowError,
8386 "sendfile() header is too large");
8387 return NULL;
8388 }
8389 sbytes += blen;
8390 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008391#endif
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008392 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008393 }
8394 }
8395 if (trailers != NULL) {
8396 if (!PySequence_Check(trailers)) {
8397 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008398 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008399 return NULL;
8400 } else {
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008401 Py_ssize_t i = PySequence_Size(trailers);
8402 if (i < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008403 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008404 if (i > INT_MAX) {
8405 PyErr_SetString(PyExc_OverflowError,
8406 "sendfile() trailer is too large");
8407 return NULL;
8408 }
8409 if (i > 0) {
8410 sf.trl_cnt = (int)i;
Miss Islington (bot)3e4b6882018-07-31 02:20:06 -07008411 if (iov_setup(&(sf.trailers), &tbuf,
8412 trailers, sf.trl_cnt, PyBUF_SIMPLE) < 0)
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008413 return NULL;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008414 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008415 }
8416 }
8417
Steve Dower8fc89802015-04-12 00:26:27 -04008418 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008419 do {
8420 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008421#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008423#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008424 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008425#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008426 Py_END_ALLOW_THREADS
8427 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008428 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008429
8430 if (sf.headers != NULL)
8431 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8432 if (sf.trailers != NULL)
8433 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8434
8435 if (ret < 0) {
8436 if ((errno == EAGAIN) || (errno == EBUSY)) {
8437 if (sbytes != 0) {
8438 // some data has been sent
8439 goto done;
8440 }
8441 else {
8442 // no data has been sent; upper application is supposed
8443 // to retry on EAGAIN or EBUSY
8444 return posix_error();
8445 }
8446 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008447 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008448 }
8449 goto done;
8450
8451done:
8452 #if !defined(HAVE_LARGEFILE_SUPPORT)
8453 return Py_BuildValue("l", sbytes);
8454 #else
8455 return Py_BuildValue("L", sbytes);
8456 #endif
8457
8458#else
8459 Py_ssize_t count;
8460 PyObject *offobj;
8461 static char *keywords[] = {"out", "in",
8462 "offset", "count", NULL};
8463 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8464 keywords, &out, &in, &offobj, &count))
8465 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008466#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008467 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008468 do {
8469 Py_BEGIN_ALLOW_THREADS
8470 ret = sendfile(out, in, NULL, count);
8471 Py_END_ALLOW_THREADS
8472 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008473 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008474 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008475 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008476 }
8477#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008478 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008479 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008480
8481 do {
8482 Py_BEGIN_ALLOW_THREADS
8483 ret = sendfile(out, in, &offset, count);
8484 Py_END_ALLOW_THREADS
8485 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008486 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008487 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008488 return Py_BuildValue("n", ret);
8489#endif
8490}
Larry Hastings2f936352014-08-05 14:04:04 +10008491#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008492
Larry Hastings2f936352014-08-05 14:04:04 +10008493
8494/*[clinic input]
8495os.fstat
8496
8497 fd : int
8498
8499Perform a stat system call on the given file descriptor.
8500
8501Like stat(), but for an open file descriptor.
8502Equivalent to os.stat(fd).
8503[clinic start generated code]*/
8504
Larry Hastings2f936352014-08-05 14:04:04 +10008505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008506os_fstat_impl(PyObject *module, int fd)
8507/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008508{
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 STRUCT_STAT st;
8510 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008511 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008512
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008513 do {
8514 Py_BEGIN_ALLOW_THREADS
8515 res = FSTAT(fd, &st);
8516 Py_END_ALLOW_THREADS
8517 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008519#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008520 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008521#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008522 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 }
Tim Peters5aa91602002-01-30 05:46:57 +00008525
Victor Stinner4195b5c2012-02-08 23:03:19 +01008526 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008527}
8528
Larry Hastings2f936352014-08-05 14:04:04 +10008529
8530/*[clinic input]
8531os.isatty -> bool
8532 fd: int
8533 /
8534
8535Return True if the fd is connected to a terminal.
8536
8537Return True if the file descriptor is an open file descriptor
8538connected to the slave end of a terminal.
8539[clinic start generated code]*/
8540
Larry Hastings2f936352014-08-05 14:04:04 +10008541static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008542os_isatty_impl(PyObject *module, int fd)
8543/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008544{
Steve Dower8fc89802015-04-12 00:26:27 -04008545 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008546 _Py_BEGIN_SUPPRESS_IPH
8547 return_value = isatty(fd);
8548 _Py_END_SUPPRESS_IPH
8549 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008550}
8551
8552
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008553#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008554/*[clinic input]
8555os.pipe
8556
8557Create a pipe.
8558
8559Returns a tuple of two file descriptors:
8560 (read_fd, write_fd)
8561[clinic start generated code]*/
8562
Larry Hastings2f936352014-08-05 14:04:04 +10008563static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008564os_pipe_impl(PyObject *module)
8565/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008566{
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008568#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008570 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008572#else
8573 int res;
8574#endif
8575
8576#ifdef MS_WINDOWS
8577 attr.nLength = sizeof(attr);
8578 attr.lpSecurityDescriptor = NULL;
8579 attr.bInheritHandle = FALSE;
8580
8581 Py_BEGIN_ALLOW_THREADS
Steve Dowerc3630612016-11-19 18:41:16 -08008582 _Py_BEGIN_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008583 ok = CreatePipe(&read, &write, &attr, 0);
8584 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008585 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8586 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008587 if (fds[0] == -1 || fds[1] == -1) {
8588 CloseHandle(read);
8589 CloseHandle(write);
8590 ok = 0;
8591 }
8592 }
Steve Dowerc3630612016-11-19 18:41:16 -08008593 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02008594 Py_END_ALLOW_THREADS
8595
Victor Stinner8c62be82010-05-06 00:08:46 +00008596 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008597 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008598#else
8599
8600#ifdef HAVE_PIPE2
8601 Py_BEGIN_ALLOW_THREADS
8602 res = pipe2(fds, O_CLOEXEC);
8603 Py_END_ALLOW_THREADS
8604
8605 if (res != 0 && errno == ENOSYS)
8606 {
8607#endif
8608 Py_BEGIN_ALLOW_THREADS
8609 res = pipe(fds);
8610 Py_END_ALLOW_THREADS
8611
8612 if (res == 0) {
8613 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8614 close(fds[0]);
8615 close(fds[1]);
8616 return NULL;
8617 }
8618 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8619 close(fds[0]);
8620 close(fds[1]);
8621 return NULL;
8622 }
8623 }
8624#ifdef HAVE_PIPE2
8625 }
8626#endif
8627
8628 if (res != 0)
8629 return PyErr_SetFromErrno(PyExc_OSError);
8630#endif /* !MS_WINDOWS */
8631 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008632}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008633#endif /* HAVE_PIPE */
8634
Larry Hastings2f936352014-08-05 14:04:04 +10008635
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008636#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008637/*[clinic input]
8638os.pipe2
8639
8640 flags: int
8641 /
8642
8643Create a pipe with flags set atomically.
8644
8645Returns a tuple of two file descriptors:
8646 (read_fd, write_fd)
8647
8648flags can be constructed by ORing together one or more of these values:
8649O_NONBLOCK, O_CLOEXEC.
8650[clinic start generated code]*/
8651
Larry Hastings2f936352014-08-05 14:04:04 +10008652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008653os_pipe2_impl(PyObject *module, int flags)
8654/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008655{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008656 int fds[2];
8657 int res;
8658
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008659 res = pipe2(fds, flags);
8660 if (res != 0)
8661 return posix_error();
8662 return Py_BuildValue("(ii)", fds[0], fds[1]);
8663}
8664#endif /* HAVE_PIPE2 */
8665
Larry Hastings2f936352014-08-05 14:04:04 +10008666
Ross Lagerwall7807c352011-03-17 20:20:30 +02008667#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008668/*[clinic input]
8669os.writev -> Py_ssize_t
8670 fd: int
8671 buffers: object
8672 /
8673
8674Iterate over buffers, and write the contents of each to a file descriptor.
8675
8676Returns the total number of bytes written.
8677buffers must be a sequence of bytes-like objects.
8678[clinic start generated code]*/
8679
Larry Hastings2f936352014-08-05 14:04:04 +10008680static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008681os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8682/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008683{
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008684 Py_ssize_t cnt;
Larry Hastings2f936352014-08-05 14:04:04 +10008685 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008686 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008687 struct iovec *iov;
8688 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008689
8690 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008691 PyErr_SetString(PyExc_TypeError,
8692 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008693 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008694 }
Larry Hastings2f936352014-08-05 14:04:04 +10008695 cnt = PySequence_Size(buffers);
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03008696 if (cnt < 0)
8697 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008698
Larry Hastings2f936352014-08-05 14:04:04 +10008699 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8700 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008701 }
8702
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008703 do {
8704 Py_BEGIN_ALLOW_THREADS
8705 result = writev(fd, iov, cnt);
8706 Py_END_ALLOW_THREADS
8707 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008708
8709 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008710 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008711 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008712
Georg Brandl306336b2012-06-24 12:55:33 +02008713 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008714}
Larry Hastings2f936352014-08-05 14:04:04 +10008715#endif /* HAVE_WRITEV */
8716
8717
8718#ifdef HAVE_PWRITE
8719/*[clinic input]
8720os.pwrite -> Py_ssize_t
8721
8722 fd: int
8723 buffer: Py_buffer
8724 offset: Py_off_t
8725 /
8726
8727Write bytes to a file descriptor starting at a particular offset.
8728
8729Write buffer to fd, starting at offset bytes from the beginning of
8730the file. Returns the number of bytes writte. Does not change the
8731current file offset.
8732[clinic start generated code]*/
8733
Larry Hastings2f936352014-08-05 14:04:04 +10008734static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008735os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8736/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008737{
8738 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008739 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008740
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008741 do {
8742 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008743 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008744 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008745 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008746 Py_END_ALLOW_THREADS
8747 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008748
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008749 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008750 posix_error();
8751 return size;
8752}
8753#endif /* HAVE_PWRITE */
8754
Pablo Galindo4defba32018-01-27 16:16:37 +00008755#if defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)
8756/*[clinic input]
8757os.pwritev -> Py_ssize_t
8758
8759 fd: int
8760 buffers: object
8761 offset: Py_off_t
8762 flags: int = 0
8763 /
8764
8765Writes the contents of bytes-like objects to a file descriptor at a given offset.
8766
8767Combines the functionality of writev() and pwrite(). All buffers must be a sequence
8768of bytes-like objects. Buffers are processed in array order. Entire contents of first
8769buffer is written before proceeding to second, and so on. The operating system may
8770set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used.
8771This function writes the contents of each object to the file descriptor and returns
8772the total number of bytes written.
8773
8774The flags argument contains a bitwise OR of zero or more of the following flags:
8775
8776- RWF_DSYNC
8777- RWF_SYNC
8778
8779Using non-zero flags requires Linux 4.7 or newer.
8780[clinic start generated code]*/
8781
8782static Py_ssize_t
8783os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset,
8784 int flags)
8785/*[clinic end generated code: output=e3dd3e9d11a6a5c7 input=803dc5ddbf0cfd3b]*/
8786{
8787 Py_ssize_t cnt;
8788 Py_ssize_t result;
8789 int async_err = 0;
8790 struct iovec *iov;
8791 Py_buffer *buf;
8792
8793 if (!PySequence_Check(buffers)) {
8794 PyErr_SetString(PyExc_TypeError,
8795 "pwritev() arg 2 must be a sequence");
8796 return -1;
8797 }
8798
8799 cnt = PySequence_Size(buffers);
8800 if (cnt < 0) {
8801 return -1;
8802 }
8803
8804#ifndef HAVE_PWRITEV2
8805 if(flags != 0) {
8806 argument_unavailable_error("pwritev2", "flags");
8807 return -1;
8808 }
8809#endif
8810
8811 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8812 return -1;
8813 }
8814#ifdef HAVE_PWRITEV2
8815 do {
8816 Py_BEGIN_ALLOW_THREADS
8817 _Py_BEGIN_SUPPRESS_IPH
8818 result = pwritev2(fd, iov, cnt, offset, flags);
8819 _Py_END_SUPPRESS_IPH
8820 Py_END_ALLOW_THREADS
8821 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8822#else
8823 do {
8824 Py_BEGIN_ALLOW_THREADS
8825 _Py_BEGIN_SUPPRESS_IPH
8826 result = pwritev(fd, iov, cnt, offset);
8827 _Py_END_SUPPRESS_IPH
8828 Py_END_ALLOW_THREADS
8829 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8830#endif
8831
8832 iov_cleanup(iov, buf, cnt);
8833 if (result < 0) {
8834 if (!async_err) {
8835 posix_error();
8836 }
8837 return -1;
8838 }
8839
8840 return result;
8841}
8842#endif /* HAVE_PWRITEV */
8843
8844
8845
Larry Hastings2f936352014-08-05 14:04:04 +10008846
8847#ifdef HAVE_MKFIFO
8848/*[clinic input]
8849os.mkfifo
8850
8851 path: path_t
8852 mode: int=0o666
8853 *
8854 dir_fd: dir_fd(requires='mkfifoat')=None
8855
8856Create a "fifo" (a POSIX named pipe).
8857
8858If dir_fd is not None, it should be a file descriptor open to a directory,
8859 and path should be relative; path will then be relative to that directory.
8860dir_fd may not be implemented on your platform.
8861 If it is unavailable, using it will raise a NotImplementedError.
8862[clinic start generated code]*/
8863
Larry Hastings2f936352014-08-05 14:04:04 +10008864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008865os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8866/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008867{
8868 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008869 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008870
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008871 do {
8872 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008873#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008874 if (dir_fd != DEFAULT_DIR_FD)
8875 result = mkfifoat(dir_fd, path->narrow, mode);
8876 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008877#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008878 result = mkfifo(path->narrow, mode);
8879 Py_END_ALLOW_THREADS
8880 } while (result != 0 && errno == EINTR &&
8881 !(async_err = PyErr_CheckSignals()));
8882 if (result != 0)
8883 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008884
8885 Py_RETURN_NONE;
8886}
8887#endif /* HAVE_MKFIFO */
8888
8889
8890#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8891/*[clinic input]
8892os.mknod
8893
8894 path: path_t
8895 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008896 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008897 *
8898 dir_fd: dir_fd(requires='mknodat')=None
8899
8900Create a node in the file system.
8901
8902Create a node in the file system (file, device special file or named pipe)
8903at path. mode specifies both the permissions to use and the
8904type of node to be created, being combined (bitwise OR) with one of
8905S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8906device defines the newly created device special file (probably using
8907os.makedev()). Otherwise device is ignored.
8908
8909If dir_fd is not None, it should be a file descriptor open to a directory,
8910 and path should be relative; path will then be relative to that directory.
8911dir_fd may not be implemented on your platform.
8912 If it is unavailable, using it will raise a NotImplementedError.
8913[clinic start generated code]*/
8914
Larry Hastings2f936352014-08-05 14:04:04 +10008915static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008916os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008917 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008918/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008919{
8920 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008921 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008922
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008923 do {
8924 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008925#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008926 if (dir_fd != DEFAULT_DIR_FD)
8927 result = mknodat(dir_fd, path->narrow, mode, device);
8928 else
Larry Hastings2f936352014-08-05 14:04:04 +10008929#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008930 result = mknod(path->narrow, mode, device);
8931 Py_END_ALLOW_THREADS
8932 } while (result != 0 && errno == EINTR &&
8933 !(async_err = PyErr_CheckSignals()));
8934 if (result != 0)
8935 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008936
8937 Py_RETURN_NONE;
8938}
8939#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8940
8941
8942#ifdef HAVE_DEVICE_MACROS
8943/*[clinic input]
8944os.major -> unsigned_int
8945
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008946 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008947 /
8948
8949Extracts a device major number from a raw device number.
8950[clinic start generated code]*/
8951
Larry Hastings2f936352014-08-05 14:04:04 +10008952static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008953os_major_impl(PyObject *module, dev_t device)
8954/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008955{
8956 return major(device);
8957}
8958
8959
8960/*[clinic input]
8961os.minor -> unsigned_int
8962
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008963 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008964 /
8965
8966Extracts a device minor number from a raw device number.
8967[clinic start generated code]*/
8968
Larry Hastings2f936352014-08-05 14:04:04 +10008969static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008970os_minor_impl(PyObject *module, dev_t device)
8971/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008972{
8973 return minor(device);
8974}
8975
8976
8977/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008978os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008979
8980 major: int
8981 minor: int
8982 /
8983
8984Composes a raw device number from the major and minor device numbers.
8985[clinic start generated code]*/
8986
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008987static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008988os_makedev_impl(PyObject *module, int major, int minor)
8989/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008990{
8991 return makedev(major, minor);
8992}
8993#endif /* HAVE_DEVICE_MACROS */
8994
8995
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008996#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008997/*[clinic input]
8998os.ftruncate
8999
9000 fd: int
9001 length: Py_off_t
9002 /
9003
9004Truncate a file, specified by file descriptor, to a specific length.
9005[clinic start generated code]*/
9006
Larry Hastings2f936352014-08-05 14:04:04 +10009007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009008os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
9009/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009010{
9011 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009012 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10009013
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009014 do {
9015 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009016 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009017#ifdef MS_WINDOWS
9018 result = _chsize_s(fd, length);
9019#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009020 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009021#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009022 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009023 Py_END_ALLOW_THREADS
9024 } while (result != 0 && errno == EINTR &&
9025 !(async_err = PyErr_CheckSignals()));
9026 if (result != 0)
9027 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10009028 Py_RETURN_NONE;
9029}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009030#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009031
9032
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009033#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009034/*[clinic input]
9035os.truncate
9036 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
9037 length: Py_off_t
9038
9039Truncate a file, specified by path, to a specific length.
9040
9041On some platforms, path may also be specified as an open file descriptor.
9042 If this functionality is unavailable, using it raises an exception.
9043[clinic start generated code]*/
9044
Larry Hastings2f936352014-08-05 14:04:04 +10009045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009046os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
9047/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009048{
9049 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009050#ifdef MS_WINDOWS
9051 int fd;
9052#endif
9053
9054 if (path->fd != -1)
9055 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009056
9057 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04009058 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009059#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07009060 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02009061 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009062 result = -1;
9063 else {
9064 result = _chsize_s(fd, length);
9065 close(fd);
9066 if (result < 0)
9067 errno = result;
9068 }
9069#else
9070 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10009071#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04009072 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10009073 Py_END_ALLOW_THREADS
9074 if (result < 0)
Miss Islington (bot)8f53dcd2018-10-19 17:46:25 -07009075 return posix_path_error(path);
Larry Hastings2f936352014-08-05 14:04:04 +10009076
9077 Py_RETURN_NONE;
9078}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07009079#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10009080
Ross Lagerwall7807c352011-03-17 20:20:30 +02009081
Victor Stinnerd6b17692014-09-30 12:20:05 +02009082/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
9083 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
9084 defined, which is the case in Python on AIX. AIX bug report:
9085 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
9086#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
9087# define POSIX_FADVISE_AIX_BUG
9088#endif
9089
Victor Stinnerec39e262014-09-30 12:35:58 +02009090
Victor Stinnerd6b17692014-09-30 12:20:05 +02009091#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009092/*[clinic input]
9093os.posix_fallocate
9094
9095 fd: int
9096 offset: Py_off_t
9097 length: Py_off_t
9098 /
9099
9100Ensure a file has allocated at least a particular number of bytes on disk.
9101
9102Ensure that the file specified by fd encompasses a range of bytes
9103starting at offset bytes from the beginning and continuing for length bytes.
9104[clinic start generated code]*/
9105
Larry Hastings2f936352014-08-05 14:04:04 +10009106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009107os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009108 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009109/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009110{
9111 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009112 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009113
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009114 do {
9115 Py_BEGIN_ALLOW_THREADS
9116 result = posix_fallocate(fd, offset, length);
9117 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009118 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9119
9120 if (result == 0)
9121 Py_RETURN_NONE;
9122
9123 if (async_err)
9124 return NULL;
9125
9126 errno = result;
9127 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009128}
Victor Stinnerec39e262014-09-30 12:35:58 +02009129#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009130
Ross Lagerwall7807c352011-03-17 20:20:30 +02009131
Victor Stinnerd6b17692014-09-30 12:20:05 +02009132#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009133/*[clinic input]
9134os.posix_fadvise
9135
9136 fd: int
9137 offset: Py_off_t
9138 length: Py_off_t
9139 advice: int
9140 /
9141
9142Announce an intention to access data in a specific pattern.
9143
9144Announce an intention to access data in a specific pattern, thus allowing
9145the kernel to make optimizations.
9146The advice applies to the region of the file specified by fd starting at
9147offset and continuing for length bytes.
9148advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9149POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9150POSIX_FADV_DONTNEED.
9151[clinic start generated code]*/
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009154os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009155 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009156/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009157{
9158 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009159 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009160
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009161 do {
9162 Py_BEGIN_ALLOW_THREADS
9163 result = posix_fadvise(fd, offset, length, advice);
9164 Py_END_ALLOW_THREADS
Коренберг Маркd4b93e22017-08-14 18:55:16 +05009165 } while (result == EINTR && !(async_err = PyErr_CheckSignals()));
9166
9167 if (result == 0)
9168 Py_RETURN_NONE;
9169
9170 if (async_err)
9171 return NULL;
9172
9173 errno = result;
9174 return posix_error();
Ross Lagerwall7807c352011-03-17 20:20:30 +02009175}
Victor Stinnerec39e262014-09-30 12:35:58 +02009176#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009177
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009178#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009179
Fred Drake762e2061999-08-26 17:23:54 +00009180/* Save putenv() parameters as values here, so we can collect them when they
9181 * get re-set with another call for the same key. */
9182static PyObject *posix_putenv_garbage;
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184static void
9185posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009186{
Larry Hastings2f936352014-08-05 14:04:04 +10009187 /* Install the first arg and newstr in posix_putenv_garbage;
9188 * this will cause previous value to be collected. This has to
9189 * happen after the real putenv() call because the old value
9190 * was still accessible until then. */
9191 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9192 /* really not much we can do; just leak */
9193 PyErr_Clear();
9194 else
9195 Py_DECREF(value);
9196}
9197
9198
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009199#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009200/*[clinic input]
9201os.putenv
9202
9203 name: unicode
9204 value: unicode
9205 /
9206
9207Change or add an environment variable.
9208[clinic start generated code]*/
9209
Larry Hastings2f936352014-08-05 14:04:04 +10009210static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009211os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9212/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009213{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009214 const wchar_t *env;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009215 Py_ssize_t size;
Larry Hastings2f936352014-08-05 14:04:04 +10009216
Serhiy Storchaka77703942017-06-25 07:33:01 +03009217 /* Search from index 1 because on Windows starting '=' is allowed for
9218 defining hidden environment variables. */
9219 if (PyUnicode_GET_LENGTH(name) == 0 ||
9220 PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
9221 {
9222 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9223 return NULL;
9224 }
Larry Hastings2f936352014-08-05 14:04:04 +10009225 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9226 if (unicode == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009227 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009228 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009229
9230 env = PyUnicode_AsUnicodeAndSize(unicode, &size);
9231 if (env == NULL)
9232 goto error;
9233 if (size > _MAX_ENV) {
Victor Stinner65170952011-11-22 22:16:17 +01009234 PyErr_Format(PyExc_ValueError,
9235 "the environment variable is longer than %u characters",
9236 _MAX_ENV);
9237 goto error;
9238 }
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009239 if (wcslen(env) != (size_t)size) {
9240 PyErr_SetString(PyExc_ValueError, "embedded null character");
Victor Stinnereb5657a2011-09-30 01:44:27 +02009241 goto error;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +03009242 }
9243
Larry Hastings2f936352014-08-05 14:04:04 +10009244 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009246 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009248
Larry Hastings2f936352014-08-05 14:04:04 +10009249 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009250 Py_RETURN_NONE;
9251
9252error:
Larry Hastings2f936352014-08-05 14:04:04 +10009253 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009254 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009255}
Larry Hastings2f936352014-08-05 14:04:04 +10009256#else /* MS_WINDOWS */
9257/*[clinic input]
9258os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009259
Larry Hastings2f936352014-08-05 14:04:04 +10009260 name: FSConverter
9261 value: FSConverter
9262 /
9263
9264Change or add an environment variable.
9265[clinic start generated code]*/
9266
Larry Hastings2f936352014-08-05 14:04:04 +10009267static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009268os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9269/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009270{
9271 PyObject *bytes = NULL;
9272 char *env;
Serhiy Storchaka77703942017-06-25 07:33:01 +03009273 const char *name_string = PyBytes_AS_STRING(name);
9274 const char *value_string = PyBytes_AS_STRING(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009275
Serhiy Storchaka77703942017-06-25 07:33:01 +03009276 if (strchr(name_string, '=') != NULL) {
9277 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
9278 return NULL;
9279 }
Larry Hastings2f936352014-08-05 14:04:04 +10009280 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9281 if (bytes == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009282 return NULL;
9283 }
9284
9285 env = PyBytes_AS_STRING(bytes);
9286 if (putenv(env)) {
9287 Py_DECREF(bytes);
9288 return posix_error();
9289 }
9290
9291 posix_putenv_garbage_setitem(name, bytes);
9292 Py_RETURN_NONE;
9293}
9294#endif /* MS_WINDOWS */
9295#endif /* HAVE_PUTENV */
9296
9297
9298#ifdef HAVE_UNSETENV
9299/*[clinic input]
9300os.unsetenv
9301 name: FSConverter
9302 /
9303
9304Delete an environment variable.
9305[clinic start generated code]*/
9306
Larry Hastings2f936352014-08-05 14:04:04 +10009307static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009308os_unsetenv_impl(PyObject *module, PyObject *name)
9309/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009310{
Victor Stinner984890f2011-11-24 13:53:38 +01009311#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009312 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009313#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009314
Victor Stinner984890f2011-11-24 13:53:38 +01009315#ifdef HAVE_BROKEN_UNSETENV
9316 unsetenv(PyBytes_AS_STRING(name));
9317#else
Victor Stinner65170952011-11-22 22:16:17 +01009318 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009319 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009320 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009321#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009322
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 /* Remove the key from posix_putenv_garbage;
9324 * this will cause it to be collected. This has to
9325 * happen after the real unsetenv() call because the
9326 * old value was still accessible until then.
9327 */
Victor Stinner65170952011-11-22 22:16:17 +01009328 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 /* really not much we can do; just leak */
9330 PyErr_Clear();
9331 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009332 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009333}
Larry Hastings2f936352014-08-05 14:04:04 +10009334#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009335
Larry Hastings2f936352014-08-05 14:04:04 +10009336
9337/*[clinic input]
9338os.strerror
9339
9340 code: int
9341 /
9342
9343Translate an error code to a message string.
9344[clinic start generated code]*/
9345
Larry Hastings2f936352014-08-05 14:04:04 +10009346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009347os_strerror_impl(PyObject *module, int code)
9348/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009349{
9350 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 if (message == NULL) {
9352 PyErr_SetString(PyExc_ValueError,
9353 "strerror() argument out of range");
9354 return NULL;
9355 }
Victor Stinner1b579672011-12-17 05:47:23 +01009356 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009357}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009358
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009359
Guido van Rossumc9641791998-08-04 15:26:23 +00009360#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009361#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009362/*[clinic input]
9363os.WCOREDUMP -> bool
9364
9365 status: int
9366 /
9367
9368Return True if the process returning status was dumped to a core file.
9369[clinic start generated code]*/
9370
Larry Hastings2f936352014-08-05 14:04:04 +10009371static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009372os_WCOREDUMP_impl(PyObject *module, int status)
9373/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009374{
9375 WAIT_TYPE wait_status;
9376 WAIT_STATUS_INT(wait_status) = status;
9377 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009378}
9379#endif /* WCOREDUMP */
9380
Larry Hastings2f936352014-08-05 14:04:04 +10009381
Fred Drake106c1a02002-04-23 15:58:02 +00009382#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009383/*[clinic input]
9384os.WIFCONTINUED -> bool
9385
9386 status: int
9387
9388Return True if a particular process was continued from a job control stop.
9389
9390Return True if the process returning status was continued from a
9391job control stop.
9392[clinic start generated code]*/
9393
Larry Hastings2f936352014-08-05 14:04:04 +10009394static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009395os_WIFCONTINUED_impl(PyObject *module, int status)
9396/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009397{
9398 WAIT_TYPE wait_status;
9399 WAIT_STATUS_INT(wait_status) = status;
9400 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009401}
9402#endif /* WIFCONTINUED */
9403
Larry Hastings2f936352014-08-05 14:04:04 +10009404
Guido van Rossumc9641791998-08-04 15:26:23 +00009405#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009406/*[clinic input]
9407os.WIFSTOPPED -> bool
9408
9409 status: int
9410
9411Return True if the process returning status was stopped.
9412[clinic start generated code]*/
9413
Larry Hastings2f936352014-08-05 14:04:04 +10009414static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009415os_WIFSTOPPED_impl(PyObject *module, int status)
9416/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009417{
9418 WAIT_TYPE wait_status;
9419 WAIT_STATUS_INT(wait_status) = status;
9420 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009421}
9422#endif /* WIFSTOPPED */
9423
Larry Hastings2f936352014-08-05 14:04:04 +10009424
Guido van Rossumc9641791998-08-04 15:26:23 +00009425#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009426/*[clinic input]
9427os.WIFSIGNALED -> bool
9428
9429 status: int
9430
9431Return True if the process returning status was terminated by a signal.
9432[clinic start generated code]*/
9433
Larry Hastings2f936352014-08-05 14:04:04 +10009434static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009435os_WIFSIGNALED_impl(PyObject *module, int status)
9436/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009437{
9438 WAIT_TYPE wait_status;
9439 WAIT_STATUS_INT(wait_status) = status;
9440 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009441}
9442#endif /* WIFSIGNALED */
9443
Larry Hastings2f936352014-08-05 14:04:04 +10009444
Guido van Rossumc9641791998-08-04 15:26:23 +00009445#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009446/*[clinic input]
9447os.WIFEXITED -> bool
9448
9449 status: int
9450
9451Return True if the process returning status exited via the exit() system call.
9452[clinic start generated code]*/
9453
Larry Hastings2f936352014-08-05 14:04:04 +10009454static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009455os_WIFEXITED_impl(PyObject *module, int status)
9456/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009457{
9458 WAIT_TYPE wait_status;
9459 WAIT_STATUS_INT(wait_status) = status;
9460 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009461}
9462#endif /* WIFEXITED */
9463
Larry Hastings2f936352014-08-05 14:04:04 +10009464
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009465#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009466/*[clinic input]
9467os.WEXITSTATUS -> int
9468
9469 status: int
9470
9471Return the process return code from status.
9472[clinic start generated code]*/
9473
Larry Hastings2f936352014-08-05 14:04:04 +10009474static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009475os_WEXITSTATUS_impl(PyObject *module, int status)
9476/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009477{
9478 WAIT_TYPE wait_status;
9479 WAIT_STATUS_INT(wait_status) = status;
9480 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009481}
9482#endif /* WEXITSTATUS */
9483
Larry Hastings2f936352014-08-05 14:04:04 +10009484
Guido van Rossumc9641791998-08-04 15:26:23 +00009485#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009486/*[clinic input]
9487os.WTERMSIG -> int
9488
9489 status: int
9490
9491Return the signal that terminated the process that provided the status value.
9492[clinic start generated code]*/
9493
Larry Hastings2f936352014-08-05 14:04:04 +10009494static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009495os_WTERMSIG_impl(PyObject *module, int status)
9496/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009497{
9498 WAIT_TYPE wait_status;
9499 WAIT_STATUS_INT(wait_status) = status;
9500 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009501}
9502#endif /* WTERMSIG */
9503
Larry Hastings2f936352014-08-05 14:04:04 +10009504
Guido van Rossumc9641791998-08-04 15:26:23 +00009505#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009506/*[clinic input]
9507os.WSTOPSIG -> int
9508
9509 status: int
9510
9511Return the signal that stopped the process that provided the status value.
9512[clinic start generated code]*/
9513
Larry Hastings2f936352014-08-05 14:04:04 +10009514static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009515os_WSTOPSIG_impl(PyObject *module, int status)
9516/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009517{
9518 WAIT_TYPE wait_status;
9519 WAIT_STATUS_INT(wait_status) = status;
9520 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009521}
9522#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009523#endif /* HAVE_SYS_WAIT_H */
9524
9525
Thomas Wouters477c8d52006-05-27 19:21:47 +00009526#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009527#ifdef _SCO_DS
9528/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9529 needed definitions in sys/statvfs.h */
9530#define _SVID3
9531#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009532#include <sys/statvfs.h>
9533
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009534static PyObject*
9535_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9537 if (v == NULL)
9538 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009539
9540#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9542 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9543 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9544 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9545 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9546 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9547 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9548 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9549 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9550 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009551#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9553 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9554 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009555 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009557 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009559 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009561 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009563 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009565 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9567 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009568#endif
Michael Felt502d5512018-01-05 13:01:58 +01009569/* The _ALL_SOURCE feature test macro defines f_fsid as a structure
9570 * (issue #32390). */
9571#if defined(_AIX) && defined(_ALL_SOURCE)
9572 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0]));
9573#else
Giuseppe Scrivano96a5e502017-12-14 23:46:46 +01009574 PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid));
Michael Felt502d5512018-01-05 13:01:58 +01009575#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009576 if (PyErr_Occurred()) {
9577 Py_DECREF(v);
9578 return NULL;
9579 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009580
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009582}
9583
Larry Hastings2f936352014-08-05 14:04:04 +10009584
9585/*[clinic input]
9586os.fstatvfs
9587 fd: int
9588 /
9589
9590Perform an fstatvfs system call on the given fd.
9591
9592Equivalent to statvfs(fd).
9593[clinic start generated code]*/
9594
Larry Hastings2f936352014-08-05 14:04:04 +10009595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009596os_fstatvfs_impl(PyObject *module, int fd)
9597/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009598{
9599 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009600 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009602
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009603 do {
9604 Py_BEGIN_ALLOW_THREADS
9605 result = fstatvfs(fd, &st);
9606 Py_END_ALLOW_THREADS
9607 } while (result != 0 && errno == EINTR &&
9608 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009609 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009610 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009611
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009613}
Larry Hastings2f936352014-08-05 14:04:04 +10009614#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009615
9616
Thomas Wouters477c8d52006-05-27 19:21:47 +00009617#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009618#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009619/*[clinic input]
9620os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009621
Larry Hastings2f936352014-08-05 14:04:04 +10009622 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9623
9624Perform a statvfs system call on the given path.
9625
9626path may always be specified as a string.
9627On some platforms, path may also be specified as an open file descriptor.
9628 If this functionality is unavailable, using it raises an exception.
9629[clinic start generated code]*/
9630
Larry Hastings2f936352014-08-05 14:04:04 +10009631static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009632os_statvfs_impl(PyObject *module, path_t *path)
9633/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009634{
9635 int result;
9636 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009637
9638 Py_BEGIN_ALLOW_THREADS
9639#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009640 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009641#ifdef __APPLE__
9642 /* handle weak-linking on Mac OS X 10.3 */
9643 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009644 fd_specified("statvfs", path->fd);
9645 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009646 }
9647#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009648 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009649 }
9650 else
9651#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009652 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009653 Py_END_ALLOW_THREADS
9654
9655 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009656 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009657 }
9658
Larry Hastings2f936352014-08-05 14:04:04 +10009659 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009660}
Larry Hastings2f936352014-08-05 14:04:04 +10009661#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9662
Guido van Rossum94f6f721999-01-06 18:42:14 +00009663
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009664#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009665/*[clinic input]
9666os._getdiskusage
9667
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009668 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10009669
9670Return disk usage statistics about the given path as a (total, free) tuple.
9671[clinic start generated code]*/
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673static PyObject *
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009674os__getdiskusage_impl(PyObject *module, path_t *path)
9675/*[clinic end generated code: output=3bd3991f5e5c5dfb input=6af8d1b7781cc042]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009676{
9677 BOOL retval;
9678 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009679
9680 Py_BEGIN_ALLOW_THREADS
Miss Islington (bot)01dd52f2018-02-22 11:02:12 -08009681 retval = GetDiskFreeSpaceExW(path->wide, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009682 Py_END_ALLOW_THREADS
9683 if (retval == 0)
9684 return PyErr_SetFromWindowsErr(0);
9685
9686 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9687}
Larry Hastings2f936352014-08-05 14:04:04 +10009688#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009689
9690
Fred Drakec9680921999-12-13 16:37:25 +00009691/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9692 * It maps strings representing configuration variable names to
9693 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009694 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009695 * rarely-used constants. There are three separate tables that use
9696 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009697 *
9698 * This code is always included, even if none of the interfaces that
9699 * need it are included. The #if hackery needed to avoid it would be
9700 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009701 */
9702struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009703 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009704 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009705};
9706
Fred Drake12c6e2d1999-12-14 21:25:03 +00009707static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009708conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009709 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009710{
Christian Heimes217cfd12007-12-02 14:31:20 +00009711 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009712 int value = _PyLong_AsInt(arg);
9713 if (value == -1 && PyErr_Occurred())
9714 return 0;
9715 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009716 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009717 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009718 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009719 /* look up the value in the table using a binary search */
9720 size_t lo = 0;
9721 size_t mid;
9722 size_t hi = tablesize;
9723 int cmp;
9724 const char *confname;
9725 if (!PyUnicode_Check(arg)) {
9726 PyErr_SetString(PyExc_TypeError,
9727 "configuration names must be strings or integers");
9728 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 }
Serhiy Storchaka06515832016-11-20 09:13:07 +02009730 confname = PyUnicode_AsUTF8(arg);
Stefan Krah0e803b32010-11-26 16:16:47 +00009731 if (confname == NULL)
9732 return 0;
9733 while (lo < hi) {
9734 mid = (lo + hi) / 2;
9735 cmp = strcmp(confname, table[mid].name);
9736 if (cmp < 0)
9737 hi = mid;
9738 else if (cmp > 0)
9739 lo = mid + 1;
9740 else {
9741 *valuep = table[mid].value;
9742 return 1;
9743 }
9744 }
9745 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9746 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009748}
9749
9750
9751#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9752static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009753#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009755#endif
9756#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009758#endif
Fred Drakec9680921999-12-13 16:37:25 +00009759#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009804#ifdef _PC_ACL_ENABLED
9805 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9806#endif
9807#ifdef _PC_MIN_HOLE_SIZE
9808 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9809#endif
9810#ifdef _PC_ALLOC_SIZE_MIN
9811 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9812#endif
9813#ifdef _PC_REC_INCR_XFER_SIZE
9814 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9815#endif
9816#ifdef _PC_REC_MAX_XFER_SIZE
9817 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9818#endif
9819#ifdef _PC_REC_MIN_XFER_SIZE
9820 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9821#endif
9822#ifdef _PC_REC_XFER_ALIGN
9823 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9824#endif
9825#ifdef _PC_SYMLINK_MAX
9826 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9827#endif
9828#ifdef _PC_XATTR_ENABLED
9829 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9830#endif
9831#ifdef _PC_XATTR_EXISTS
9832 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9833#endif
9834#ifdef _PC_TIMESTAMP_RESOLUTION
9835 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9836#endif
Fred Drakec9680921999-12-13 16:37:25 +00009837};
9838
Fred Drakec9680921999-12-13 16:37:25 +00009839static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009840conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009841{
9842 return conv_confname(arg, valuep, posix_constants_pathconf,
9843 sizeof(posix_constants_pathconf)
9844 / sizeof(struct constdef));
9845}
9846#endif
9847
Larry Hastings2f936352014-08-05 14:04:04 +10009848
Fred Drakec9680921999-12-13 16:37:25 +00009849#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009850/*[clinic input]
9851os.fpathconf -> long
9852
9853 fd: int
9854 name: path_confname
9855 /
9856
9857Return the configuration limit name for the file descriptor fd.
9858
9859If there is no limit, return -1.
9860[clinic start generated code]*/
9861
Larry Hastings2f936352014-08-05 14:04:04 +10009862static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009863os_fpathconf_impl(PyObject *module, int fd, int name)
9864/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009865{
9866 long limit;
9867
9868 errno = 0;
9869 limit = fpathconf(fd, name);
9870 if (limit == -1 && errno != 0)
9871 posix_error();
9872
9873 return limit;
9874}
9875#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009876
9877
9878#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009879/*[clinic input]
9880os.pathconf -> long
9881 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9882 name: path_confname
9883
9884Return the configuration limit name for the file or directory path.
9885
9886If there is no limit, return -1.
9887On some platforms, path may also be specified as an open file descriptor.
9888 If this functionality is unavailable, using it raises an exception.
9889[clinic start generated code]*/
9890
Larry Hastings2f936352014-08-05 14:04:04 +10009891static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009892os_pathconf_impl(PyObject *module, path_t *path, int name)
9893/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009894{
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009896
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009898#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009899 if (path->fd != -1)
9900 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009901 else
9902#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009903 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 if (limit == -1 && errno != 0) {
9905 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009906 /* could be a path or name problem */
9907 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009908 else
Larry Hastings2f936352014-08-05 14:04:04 +10009909 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 }
Larry Hastings2f936352014-08-05 14:04:04 +10009911
9912 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009913}
Larry Hastings2f936352014-08-05 14:04:04 +10009914#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009915
9916#ifdef HAVE_CONFSTR
9917static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009918#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009920#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009921#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009923#endif
9924#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009926#endif
Fred Draked86ed291999-12-15 15:34:33 +00009927#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009929#endif
9930#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009932#endif
9933#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009935#endif
9936#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009938#endif
Fred Drakec9680921999-12-13 16:37:25 +00009939#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
Fred Draked86ed291999-12-15 15:34:33 +00009963#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009965#endif
Fred Drakec9680921999-12-13 16:37:25 +00009966#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
Fred Draked86ed291999-12-15 15:34:33 +00009969#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009971#endif
9972#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009974#endif
9975#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009977#endif
9978#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009980#endif
Fred Drakec9680921999-12-13 16:37:25 +00009981#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
Fred Draked86ed291999-12-15 15:34:33 +000010029#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010031#endif
10032#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +000010034#endif
10035#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +000010037#endif
10038#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010040#endif
10041#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010043#endif
10044#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +000010046#endif
10047#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +000010049#endif
10050#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +000010052#endif
10053#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +000010055#endif
10056#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +000010058#endif
10059#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +000010061#endif
10062#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +000010064#endif
10065#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +000010067#endif
Fred Drakec9680921999-12-13 16:37:25 +000010068};
10069
10070static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010071conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010072{
10073 return conv_confname(arg, valuep, posix_constants_confstr,
10074 sizeof(posix_constants_confstr)
10075 / sizeof(struct constdef));
10076}
10077
Larry Hastings2f936352014-08-05 14:04:04 +100010078
10079/*[clinic input]
10080os.confstr
10081
10082 name: confstr_confname
10083 /
10084
10085Return a string-valued system configuration variable.
10086[clinic start generated code]*/
10087
Larry Hastings2f936352014-08-05 14:04:04 +100010088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010089os_confstr_impl(PyObject *module, int name)
10090/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +000010091{
10092 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +000010093 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010094 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +000010095
Victor Stinnercb043522010-09-10 23:49:04 +000010096 errno = 0;
10097 len = confstr(name, buffer, sizeof(buffer));
10098 if (len == 0) {
10099 if (errno) {
10100 posix_error();
10101 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +000010102 }
10103 else {
Victor Stinnercb043522010-09-10 23:49:04 +000010104 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +000010105 }
10106 }
Victor Stinnercb043522010-09-10 23:49:04 +000010107
Victor Stinnerdd3a6a52013-06-25 23:13:47 +020010108 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +010010109 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +000010110 char *buf = PyMem_Malloc(len);
10111 if (buf == NULL)
10112 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +010010113 len2 = confstr(name, buf, len);
10114 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +020010115 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +000010116 PyMem_Free(buf);
10117 }
10118 else
10119 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +000010120 return result;
10121}
Larry Hastings2f936352014-08-05 14:04:04 +100010122#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +000010123
10124
10125#ifdef HAVE_SYSCONF
10126static struct constdef posix_constants_sysconf[] = {
10127#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
Fred Draked86ed291999-12-15 15:34:33 +000010157#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010159#endif
10160#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010162#endif
Fred Drakec9680921999-12-13 16:37:25 +000010163#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
Fred Drakec9680921999-12-13 16:37:25 +000010166#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
Fred Draked86ed291999-12-15 15:34:33 +000010181#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010183#endif
Fred Drakec9680921999-12-13 16:37:25 +000010184#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
Fred Draked86ed291999-12-15 15:34:33 +000010199#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010201#endif
Fred Drakec9680921999-12-13 16:37:25 +000010202#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
Fred Draked86ed291999-12-15 15:34:33 +000010271#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
Fred Drakec9680921999-12-13 16:37:25 +000010274#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
Fred Draked86ed291999-12-15 15:34:33 +000010283#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010285#endif
Fred Drakec9680921999-12-13 16:37:25 +000010286#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
Fred Draked86ed291999-12-15 15:34:33 +000010289#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010291#endif
10292#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010294#endif
Fred Drakec9680921999-12-13 16:37:25 +000010295#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
Fred Draked86ed291999-12-15 15:34:33 +000010307#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010309#endif
Fred Drakec9680921999-12-13 16:37:25 +000010310#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
Fred Draked86ed291999-12-15 15:34:33 +000010331#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010333#endif
Fred Drakec9680921999-12-13 16:37:25 +000010334#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
Fred Draked86ed291999-12-15 15:34:33 +000010340#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010342#endif
Fred Drakec9680921999-12-13 16:37:25 +000010343#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
Fred Draked86ed291999-12-15 15:34:33 +000010370#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010372#endif
10373#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010375#endif
Fred Drakec9680921999-12-13 16:37:25 +000010376#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
10430#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010432#endif
10433#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
10448#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010450#endif
10451#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010453#endif
10454#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010456#endif
10457#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010459#endif
10460#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010462#endif
10463#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010465#endif
10466#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010468#endif
10469#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010471#endif
10472#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010474#endif
10475#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010477#endif
10478#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010480#endif
Fred Draked86ed291999-12-15 15:34:33 +000010481#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010483#endif
Fred Drakec9680921999-12-13 16:37:25 +000010484#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010489#endif
10490#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010492#endif
10493#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010495#endif
10496#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010498#endif
10499#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010501#endif
10502#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010504#endif
10505#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010507#endif
10508#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010510#endif
10511#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010513#endif
10514#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010515 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010516#endif
10517#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010518 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010519#endif
10520#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010521 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010522#endif
10523#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010525#endif
10526#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010528#endif
10529#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010531#endif
10532#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010534#endif
10535#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010537#endif
10538#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010540#endif
10541#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010543#endif
10544#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010546#endif
10547#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010549#endif
10550#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010552#endif
10553#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010555#endif
10556#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010558#endif
10559#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010561#endif
10562#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010564#endif
10565#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010567#endif
10568#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010570#endif
10571#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010573#endif
10574#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
10577#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010579#endif
10580#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010582#endif
10583#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010585#endif
10586#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010587 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010588#endif
10589#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010591#endif
10592#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010594#endif
10595#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010597#endif
10598#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010600#endif
10601#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010603#endif
10604#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010606#endif
10607#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010609#endif
10610#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010612#endif
10613#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010615#endif
10616#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010618#endif
10619};
10620
10621static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010622conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010623{
10624 return conv_confname(arg, valuep, posix_constants_sysconf,
10625 sizeof(posix_constants_sysconf)
10626 / sizeof(struct constdef));
10627}
10628
Larry Hastings2f936352014-08-05 14:04:04 +100010629
10630/*[clinic input]
10631os.sysconf -> long
10632 name: sysconf_confname
10633 /
10634
10635Return an integer-valued system configuration variable.
10636[clinic start generated code]*/
10637
Larry Hastings2f936352014-08-05 14:04:04 +100010638static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010639os_sysconf_impl(PyObject *module, int name)
10640/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010641{
10642 long value;
10643
10644 errno = 0;
10645 value = sysconf(name);
10646 if (value == -1 && errno != 0)
10647 posix_error();
10648 return value;
10649}
10650#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010651
10652
Fred Drakebec628d1999-12-15 18:31:10 +000010653/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010654 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010655 * the exported dictionaries that are used to publish information about the
10656 * names available on the host platform.
10657 *
10658 * Sorting the table at runtime ensures that the table is properly ordered
10659 * when used, even for platforms we're not able to test on. It also makes
10660 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010661 */
Fred Drakebec628d1999-12-15 18:31:10 +000010662
10663static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010664cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010665{
10666 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010667 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010668 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010670
10671 return strcmp(c1->name, c2->name);
10672}
10673
10674static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010675setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010676 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010677{
Fred Drakebec628d1999-12-15 18:31:10 +000010678 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010679 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010680
10681 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10682 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010683 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010685
Barry Warsaw3155db32000-04-13 15:20:40 +000010686 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 PyObject *o = PyLong_FromLong(table[i].value);
10688 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10689 Py_XDECREF(o);
10690 Py_DECREF(d);
10691 return -1;
10692 }
10693 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010694 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010695 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010696}
10697
Fred Drakebec628d1999-12-15 18:31:10 +000010698/* Return -1 on failure, 0 on success. */
10699static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010700setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010701{
10702#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010703 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010704 sizeof(posix_constants_pathconf)
10705 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010706 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010707 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010708#endif
10709#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010710 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010711 sizeof(posix_constants_confstr)
10712 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010713 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010714 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010715#endif
10716#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010717 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010718 sizeof(posix_constants_sysconf)
10719 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010720 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010721 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010722#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010723 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010724}
Fred Draked86ed291999-12-15 15:34:33 +000010725
10726
Larry Hastings2f936352014-08-05 14:04:04 +100010727/*[clinic input]
10728os.abort
10729
10730Abort the interpreter immediately.
10731
10732This function 'dumps core' or otherwise fails in the hardest way possible
10733on the hosting operating system. This function never returns.
10734[clinic start generated code]*/
10735
Larry Hastings2f936352014-08-05 14:04:04 +100010736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010737os_abort_impl(PyObject *module)
10738/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010739{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010740 abort();
10741 /*NOTREACHED*/
Victor Stinner9a2329f2016-12-05 17:56:36 +010010742#ifndef __clang__
10743 /* Issue #28152: abort() is declared with __attribute__((__noreturn__)).
10744 GCC emits a warning without "return NULL;" (compiler bug?), but Clang
10745 is smarter and emits a warning on the return. */
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010746 Py_FatalError("abort() called from Python code didn't abort!");
10747 return NULL;
Victor Stinner9a2329f2016-12-05 17:56:36 +010010748#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010749}
Fred Drakebec628d1999-12-15 18:31:10 +000010750
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010751#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010752/* Grab ShellExecute dynamically from shell32 */
10753static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010754static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10755 LPCWSTR, INT);
10756static int
10757check_ShellExecute()
10758{
10759 HINSTANCE hShell32;
10760
10761 /* only recheck */
10762 if (-1 == has_ShellExecute) {
10763 Py_BEGIN_ALLOW_THREADS
Victor Stinnera9912152017-10-13 13:46:57 -070010764 /* Security note: this call is not vulnerable to "DLL hijacking".
10765 SHELL32 is part of "KnownDLLs" and so Windows always load
10766 the system SHELL32.DLL, even if there is another SHELL32.DLL
10767 in the DLL search path. */
Steve Dower7d0e0c92015-01-24 08:18:24 -080010768 hShell32 = LoadLibraryW(L"SHELL32");
10769 Py_END_ALLOW_THREADS
10770 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010771 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10772 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010773 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010774 } else {
10775 has_ShellExecute = 0;
10776 }
10777 }
10778 return has_ShellExecute;
10779}
10780
10781
Steve Dowercc16be82016-09-08 10:35:16 -070010782/*[clinic input]
10783os.startfile
10784 filepath: path_t
10785 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010786
Steve Dowercc16be82016-09-08 10:35:16 -070010787startfile(filepath [, operation])
10788
10789Start a file with its associated application.
10790
10791When "operation" is not specified or "open", this acts like
10792double-clicking the file in Explorer, or giving the file name as an
10793argument to the DOS "start" command: the file is opened with whatever
10794application (if any) its extension is associated.
10795When another "operation" is given, it specifies what should be done with
10796the file. A typical operation is "print".
10797
10798startfile returns as soon as the associated application is launched.
10799There is no option to wait for the application to close, and no way
10800to retrieve the application's exit status.
10801
10802The filepath is relative to the current directory. If you want to use
10803an absolute path, make sure the first character is not a slash ("/");
10804the underlying Win32 ShellExecute function doesn't work if it is.
10805[clinic start generated code]*/
10806
10807static PyObject *
10808os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10809/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10810{
10811 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010812
10813 if(!check_ShellExecute()) {
10814 /* If the OS doesn't have ShellExecute, return a
10815 NotImplementedError. */
10816 return PyErr_Format(PyExc_NotImplementedError,
10817 "startfile not available on this platform");
10818 }
10819
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010821 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010822 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 Py_END_ALLOW_THREADS
10824
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010826 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010827 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 }
Steve Dowercc16be82016-09-08 10:35:16 -070010829 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010830}
Larry Hastings2f936352014-08-05 14:04:04 +100010831#endif /* MS_WINDOWS */
10832
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010833
Martin v. Löwis438b5342002-12-27 10:16:42 +000010834#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010835/*[clinic input]
10836os.getloadavg
10837
10838Return average recent system load information.
10839
10840Return the number of processes in the system run queue averaged over
10841the last 1, 5, and 15 minutes as a tuple of three floats.
10842Raises OSError if the load average was unobtainable.
10843[clinic start generated code]*/
10844
Larry Hastings2f936352014-08-05 14:04:04 +100010845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010846os_getloadavg_impl(PyObject *module)
10847/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010848{
10849 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010850 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010851 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10852 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010853 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010854 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010855}
Larry Hastings2f936352014-08-05 14:04:04 +100010856#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010857
Larry Hastings2f936352014-08-05 14:04:04 +100010858
10859/*[clinic input]
10860os.device_encoding
10861 fd: int
10862
10863Return a string describing the encoding of a terminal's file descriptor.
10864
10865The file descriptor must be attached to a terminal.
10866If the device is not a terminal, return None.
10867[clinic start generated code]*/
10868
Larry Hastings2f936352014-08-05 14:04:04 +100010869static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010870os_device_encoding_impl(PyObject *module, int fd)
10871/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010872{
Brett Cannonefb00c02012-02-29 18:31:31 -050010873 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010874}
10875
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010876
Larry Hastings2f936352014-08-05 14:04:04 +100010877#ifdef HAVE_SETRESUID
10878/*[clinic input]
10879os.setresuid
10880
10881 ruid: uid_t
10882 euid: uid_t
10883 suid: uid_t
10884 /
10885
10886Set the current process's real, effective, and saved user ids.
10887[clinic start generated code]*/
10888
Larry Hastings2f936352014-08-05 14:04:04 +100010889static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010890os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10891/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010892{
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 if (setresuid(ruid, euid, suid) < 0)
10894 return posix_error();
10895 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010896}
Larry Hastings2f936352014-08-05 14:04:04 +100010897#endif /* HAVE_SETRESUID */
10898
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010899
10900#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010901/*[clinic input]
10902os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010903
Larry Hastings2f936352014-08-05 14:04:04 +100010904 rgid: gid_t
10905 egid: gid_t
10906 sgid: gid_t
10907 /
10908
10909Set the current process's real, effective, and saved group ids.
10910[clinic start generated code]*/
10911
Larry Hastings2f936352014-08-05 14:04:04 +100010912static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010913os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10914/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010915{
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 if (setresgid(rgid, egid, sgid) < 0)
10917 return posix_error();
10918 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010919}
Larry Hastings2f936352014-08-05 14:04:04 +100010920#endif /* HAVE_SETRESGID */
10921
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010922
10923#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010924/*[clinic input]
10925os.getresuid
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 user ids.
10928[clinic start generated code]*/
10929
Larry Hastings2f936352014-08-05 14:04:04 +100010930static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010931os_getresuid_impl(PyObject *module)
10932/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010933{
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 if (getresuid(&ruid, &euid, &suid) < 0)
10936 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010937 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10938 _PyLong_FromUid(euid),
10939 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010940}
Larry Hastings2f936352014-08-05 14:04:04 +100010941#endif /* HAVE_GETRESUID */
10942
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010943
10944#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010945/*[clinic input]
10946os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010947
Larry Hastings2f936352014-08-05 14:04:04 +100010948Return a tuple of the current process's real, effective, and saved group ids.
10949[clinic start generated code]*/
10950
Larry Hastings2f936352014-08-05 14:04:04 +100010951static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010952os_getresgid_impl(PyObject *module)
10953/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010954{
10955 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 if (getresgid(&rgid, &egid, &sgid) < 0)
10957 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010958 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10959 _PyLong_FromGid(egid),
10960 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010961}
Larry Hastings2f936352014-08-05 14:04:04 +100010962#endif /* HAVE_GETRESGID */
10963
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010964
Benjamin Peterson9428d532011-09-14 11:45:52 -040010965#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010966/*[clinic input]
10967os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010968
Larry Hastings2f936352014-08-05 14:04:04 +100010969 path: path_t(allow_fd=True)
10970 attribute: path_t
10971 *
10972 follow_symlinks: bool = True
10973
10974Return the value of extended attribute attribute on path.
10975
10976path may be either a string or an open file descriptor.
10977If follow_symlinks is False, and the last element of the path is a symbolic
10978 link, getxattr will examine the symbolic link itself instead of the file
10979 the link points to.
10980
10981[clinic start generated code]*/
10982
Larry Hastings2f936352014-08-05 14:04:04 +100010983static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010984os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010985 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010986/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010987{
10988 Py_ssize_t i;
10989 PyObject *buffer = NULL;
10990
10991 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10992 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010993
Larry Hastings9cf065c2012-06-22 16:30:09 -070010994 for (i = 0; ; i++) {
10995 void *ptr;
10996 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010997 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010998 Py_ssize_t buffer_size = buffer_sizes[i];
10999 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100011000 path_error(path);
11001 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011002 }
11003 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
11004 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100011005 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011006 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011007
Larry Hastings9cf065c2012-06-22 16:30:09 -070011008 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011009 if (path->fd >= 0)
11010 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011012 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 else
Larry Hastings2f936352014-08-05 14:04:04 +100011014 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011015 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011016
Larry Hastings9cf065c2012-06-22 16:30:09 -070011017 if (result < 0) {
11018 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011019 if (errno == ERANGE)
11020 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100011021 path_error(path);
11022 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011023 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011024
Larry Hastings9cf065c2012-06-22 16:30:09 -070011025 if (result != buffer_size) {
11026 /* Can only shrink. */
11027 _PyBytes_Resize(&buffer, result);
11028 }
11029 break;
11030 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011031
Larry Hastings9cf065c2012-06-22 16:30:09 -070011032 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011033}
11034
Larry Hastings2f936352014-08-05 14:04:04 +100011035
11036/*[clinic input]
11037os.setxattr
11038
11039 path: path_t(allow_fd=True)
11040 attribute: path_t
11041 value: Py_buffer
11042 flags: int = 0
11043 *
11044 follow_symlinks: bool = True
11045
11046Set extended attribute attribute on path to value.
11047
11048path may be either a string or an open file descriptor.
11049If follow_symlinks is False, and the last element of the path is a symbolic
11050 link, setxattr will modify the symbolic link itself instead of the file
11051 the link points to.
11052
11053[clinic start generated code]*/
11054
Benjamin Peterson799bd802011-08-31 22:15:17 -040011055static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011056os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011057 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011058/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040011059{
Larry Hastings2f936352014-08-05 14:04:04 +100011060 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011061
Larry Hastings2f936352014-08-05 14:04:04 +100011062 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040011063 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011064
Benjamin Peterson799bd802011-08-31 22:15:17 -040011065 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011066 if (path->fd > -1)
11067 result = fsetxattr(path->fd, attribute->narrow,
11068 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011069 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100011070 result = setxattr(path->narrow, attribute->narrow,
11071 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011072 else
Larry Hastings2f936352014-08-05 14:04:04 +100011073 result = lsetxattr(path->narrow, attribute->narrow,
11074 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040011075 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011076
Larry Hastings9cf065c2012-06-22 16:30:09 -070011077 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100011078 path_error(path);
11079 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011080 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011081
Larry Hastings2f936352014-08-05 14:04:04 +100011082 Py_RETURN_NONE;
11083}
11084
11085
11086/*[clinic input]
11087os.removexattr
11088
11089 path: path_t(allow_fd=True)
11090 attribute: path_t
11091 *
11092 follow_symlinks: bool = True
11093
11094Remove extended attribute attribute on path.
11095
11096path may be either a string or an open file descriptor.
11097If follow_symlinks is False, and the last element of the path is a symbolic
11098 link, removexattr will modify the symbolic link itself instead of the file
11099 the link points to.
11100
11101[clinic start generated code]*/
11102
Larry Hastings2f936352014-08-05 14:04:04 +100011103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011104os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011105 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011106/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011107{
11108 ssize_t result;
11109
11110 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11111 return NULL;
11112
11113 Py_BEGIN_ALLOW_THREADS;
11114 if (path->fd > -1)
11115 result = fremovexattr(path->fd, attribute->narrow);
11116 else if (follow_symlinks)
11117 result = removexattr(path->narrow, attribute->narrow);
11118 else
11119 result = lremovexattr(path->narrow, attribute->narrow);
11120 Py_END_ALLOW_THREADS;
11121
11122 if (result) {
11123 return path_error(path);
11124 }
11125
11126 Py_RETURN_NONE;
11127}
11128
11129
11130/*[clinic input]
11131os.listxattr
11132
11133 path: path_t(allow_fd=True, nullable=True) = None
11134 *
11135 follow_symlinks: bool = True
11136
11137Return a list of extended attributes on path.
11138
11139path may be either None, a string, or an open file descriptor.
11140if path is None, listxattr will examine the current directory.
11141If follow_symlinks is False, and the last element of the path is a symbolic
11142 link, listxattr will examine the symbolic link itself instead of the file
11143 the link points to.
11144[clinic start generated code]*/
11145
Larry Hastings2f936352014-08-05 14:04:04 +100011146static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011147os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11148/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011149{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011150 Py_ssize_t i;
11151 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011152 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011153 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011154
Larry Hastings2f936352014-08-05 14:04:04 +100011155 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011156 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011157
Larry Hastings2f936352014-08-05 14:04:04 +100011158 name = path->narrow ? path->narrow : ".";
11159
Larry Hastings9cf065c2012-06-22 16:30:09 -070011160 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011161 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011162 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011163 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011164 Py_ssize_t buffer_size = buffer_sizes[i];
11165 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011166 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011167 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011168 break;
11169 }
11170 buffer = PyMem_MALLOC(buffer_size);
11171 if (!buffer) {
11172 PyErr_NoMemory();
11173 break;
11174 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011175
Larry Hastings9cf065c2012-06-22 16:30:09 -070011176 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011177 if (path->fd > -1)
11178 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011179 else if (follow_symlinks)
11180 length = listxattr(name, buffer, buffer_size);
11181 else
11182 length = llistxattr(name, buffer, buffer_size);
11183 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011184
Larry Hastings9cf065c2012-06-22 16:30:09 -070011185 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011186 if (errno == ERANGE) {
11187 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011188 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011189 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011190 }
Larry Hastings2f936352014-08-05 14:04:04 +100011191 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011192 break;
11193 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011194
Larry Hastings9cf065c2012-06-22 16:30:09 -070011195 result = PyList_New(0);
11196 if (!result) {
11197 goto exit;
11198 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011199
Larry Hastings9cf065c2012-06-22 16:30:09 -070011200 end = buffer + length;
11201 for (trace = start = buffer; trace != end; trace++) {
11202 if (!*trace) {
11203 int error;
11204 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11205 trace - start);
11206 if (!attribute) {
11207 Py_DECREF(result);
11208 result = NULL;
11209 goto exit;
11210 }
11211 error = PyList_Append(result, attribute);
11212 Py_DECREF(attribute);
11213 if (error) {
11214 Py_DECREF(result);
11215 result = NULL;
11216 goto exit;
11217 }
11218 start = trace + 1;
11219 }
11220 }
11221 break;
11222 }
11223exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011224 if (buffer)
11225 PyMem_FREE(buffer);
11226 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011227}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011228#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011229
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011230
Larry Hastings2f936352014-08-05 14:04:04 +100011231/*[clinic input]
11232os.urandom
11233
11234 size: Py_ssize_t
11235 /
11236
11237Return a bytes object containing random bytes suitable for cryptographic use.
11238[clinic start generated code]*/
11239
Larry Hastings2f936352014-08-05 14:04:04 +100011240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011241os_urandom_impl(PyObject *module, Py_ssize_t size)
11242/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011243{
11244 PyObject *bytes;
11245 int result;
11246
Georg Brandl2fb477c2012-02-21 00:33:36 +010011247 if (size < 0)
11248 return PyErr_Format(PyExc_ValueError,
11249 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011250 bytes = PyBytes_FromStringAndSize(NULL, size);
11251 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011252 return NULL;
11253
Victor Stinnere66987e2016-09-06 16:33:52 -070011254 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011255 if (result == -1) {
11256 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011257 return NULL;
11258 }
Larry Hastings2f936352014-08-05 14:04:04 +100011259 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011260}
11261
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011262/* Terminal size querying */
11263
11264static PyTypeObject TerminalSizeType;
11265
11266PyDoc_STRVAR(TerminalSize_docstring,
11267 "A tuple of (columns, lines) for holding terminal window size");
11268
11269static PyStructSequence_Field TerminalSize_fields[] = {
11270 {"columns", "width of the terminal window in characters"},
11271 {"lines", "height of the terminal window in characters"},
11272 {NULL, NULL}
11273};
11274
11275static PyStructSequence_Desc TerminalSize_desc = {
11276 "os.terminal_size",
11277 TerminalSize_docstring,
11278 TerminalSize_fields,
11279 2,
11280};
11281
11282#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011283/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011284PyDoc_STRVAR(termsize__doc__,
11285 "Return the size of the terminal window as (columns, lines).\n" \
11286 "\n" \
11287 "The optional argument fd (default standard output) specifies\n" \
11288 "which file descriptor should be queried.\n" \
11289 "\n" \
11290 "If the file descriptor is not connected to a terminal, an OSError\n" \
11291 "is thrown.\n" \
11292 "\n" \
11293 "This function will only be defined if an implementation is\n" \
11294 "available for this system.\n" \
11295 "\n" \
11296 "shutil.get_terminal_size is the high-level function which should \n" \
11297 "normally be used, os.get_terminal_size is the low-level implementation.");
11298
11299static PyObject*
11300get_terminal_size(PyObject *self, PyObject *args)
11301{
11302 int columns, lines;
11303 PyObject *termsize;
11304
11305 int fd = fileno(stdout);
11306 /* Under some conditions stdout may not be connected and
11307 * fileno(stdout) may point to an invalid file descriptor. For example
11308 * GUI apps don't have valid standard streams by default.
11309 *
11310 * If this happens, and the optional fd argument is not present,
11311 * the ioctl below will fail returning EBADF. This is what we want.
11312 */
11313
11314 if (!PyArg_ParseTuple(args, "|i", &fd))
11315 return NULL;
11316
11317#ifdef TERMSIZE_USE_IOCTL
11318 {
11319 struct winsize w;
11320 if (ioctl(fd, TIOCGWINSZ, &w))
11321 return PyErr_SetFromErrno(PyExc_OSError);
11322 columns = w.ws_col;
11323 lines = w.ws_row;
11324 }
11325#endif /* TERMSIZE_USE_IOCTL */
11326
11327#ifdef TERMSIZE_USE_CONIO
11328 {
11329 DWORD nhandle;
11330 HANDLE handle;
11331 CONSOLE_SCREEN_BUFFER_INFO csbi;
11332 switch (fd) {
11333 case 0: nhandle = STD_INPUT_HANDLE;
11334 break;
11335 case 1: nhandle = STD_OUTPUT_HANDLE;
11336 break;
11337 case 2: nhandle = STD_ERROR_HANDLE;
11338 break;
11339 default:
11340 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11341 }
11342 handle = GetStdHandle(nhandle);
11343 if (handle == NULL)
11344 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11345 if (handle == INVALID_HANDLE_VALUE)
11346 return PyErr_SetFromWindowsErr(0);
11347
11348 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11349 return PyErr_SetFromWindowsErr(0);
11350
11351 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11352 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11353 }
11354#endif /* TERMSIZE_USE_CONIO */
11355
11356 termsize = PyStructSequence_New(&TerminalSizeType);
11357 if (termsize == NULL)
11358 return NULL;
11359 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11360 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11361 if (PyErr_Occurred()) {
11362 Py_DECREF(termsize);
11363 return NULL;
11364 }
11365 return termsize;
11366}
11367#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11368
Larry Hastings2f936352014-08-05 14:04:04 +100011369
11370/*[clinic input]
11371os.cpu_count
11372
Charles-François Natali80d62e62015-08-13 20:37:08 +010011373Return the number of CPUs in the system; return None if indeterminable.
11374
11375This number is not equivalent to the number of CPUs the current process can
11376use. The number of usable CPUs can be obtained with
11377``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011378[clinic start generated code]*/
11379
Larry Hastings2f936352014-08-05 14:04:04 +100011380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011381os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011382/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011383{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011384 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011385#ifdef MS_WINDOWS
Christopher Wilcoxc67bae02017-08-30 05:01:08 -040011386 /* Vista is supported and the GetMaximumProcessorCount API is Win7+
11387 Need to fallback to Vista behavior if this call isn't present */
11388 HINSTANCE hKernel32;
11389 hKernel32 = GetModuleHandleW(L"KERNEL32");
11390
11391 static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
11392 *(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
11393 "GetMaximumProcessorCount");
11394 if (_GetMaximumProcessorCount != NULL) {
11395 ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
11396 }
11397 else {
11398 SYSTEM_INFO sysinfo;
11399 GetSystemInfo(&sysinfo);
11400 ncpu = sysinfo.dwNumberOfProcessors;
11401 }
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011402#elif defined(__hpux)
11403 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11404#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11405 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011406#elif defined(__DragonFly__) || \
11407 defined(__OpenBSD__) || \
11408 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011409 defined(__NetBSD__) || \
11410 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011411 int mib[2];
11412 size_t len = sizeof(ncpu);
11413 mib[0] = CTL_HW;
11414 mib[1] = HW_NCPU;
11415 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11416 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011417#endif
11418 if (ncpu >= 1)
11419 return PyLong_FromLong(ncpu);
11420 else
11421 Py_RETURN_NONE;
11422}
11423
Victor Stinnerdaf45552013-08-28 00:53:59 +020011424
Larry Hastings2f936352014-08-05 14:04:04 +100011425/*[clinic input]
11426os.get_inheritable -> bool
11427
11428 fd: int
11429 /
11430
11431Get the close-on-exe flag of the specified file descriptor.
11432[clinic start generated code]*/
11433
Larry Hastings2f936352014-08-05 14:04:04 +100011434static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011435os_get_inheritable_impl(PyObject *module, int fd)
11436/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011437{
Steve Dower8fc89802015-04-12 00:26:27 -040011438 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040011439 _Py_BEGIN_SUPPRESS_IPH
11440 return_value = _Py_get_inheritable(fd);
11441 _Py_END_SUPPRESS_IPH
11442 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011443}
11444
11445
11446/*[clinic input]
11447os.set_inheritable
11448 fd: int
11449 inheritable: int
11450 /
11451
11452Set the inheritable flag of the specified file descriptor.
11453[clinic start generated code]*/
11454
Larry Hastings2f936352014-08-05 14:04:04 +100011455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011456os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11457/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011458{
Steve Dower8fc89802015-04-12 00:26:27 -040011459 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011460
Steve Dower8fc89802015-04-12 00:26:27 -040011461 _Py_BEGIN_SUPPRESS_IPH
11462 result = _Py_set_inheritable(fd, inheritable, NULL);
11463 _Py_END_SUPPRESS_IPH
11464 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011465 return NULL;
11466 Py_RETURN_NONE;
11467}
11468
11469
11470#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011471/*[clinic input]
11472os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011473 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011474 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011475
Larry Hastings2f936352014-08-05 14:04:04 +100011476Get the close-on-exe flag of the specified file descriptor.
11477[clinic start generated code]*/
11478
Larry Hastings2f936352014-08-05 14:04:04 +100011479static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011480os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011481/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011482{
11483 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011484
11485 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11486 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011487 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011488 }
11489
Larry Hastings2f936352014-08-05 14:04:04 +100011490 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011491}
11492
Victor Stinnerdaf45552013-08-28 00:53:59 +020011493
Larry Hastings2f936352014-08-05 14:04:04 +100011494/*[clinic input]
11495os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011496 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011497 inheritable: bool
11498 /
11499
11500Set the inheritable flag of the specified handle.
11501[clinic start generated code]*/
11502
Larry Hastings2f936352014-08-05 14:04:04 +100011503static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011504os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011505 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011506/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011507{
11508 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011509 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11510 PyErr_SetFromWindowsErr(0);
11511 return NULL;
11512 }
11513 Py_RETURN_NONE;
11514}
Larry Hastings2f936352014-08-05 14:04:04 +100011515#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011516
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011517#ifndef MS_WINDOWS
11518PyDoc_STRVAR(get_blocking__doc__,
11519 "get_blocking(fd) -> bool\n" \
11520 "\n" \
11521 "Get the blocking mode of the file descriptor:\n" \
11522 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11523
11524static PyObject*
11525posix_get_blocking(PyObject *self, PyObject *args)
11526{
11527 int fd;
11528 int blocking;
11529
11530 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11531 return NULL;
11532
Steve Dower8fc89802015-04-12 00:26:27 -040011533 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011534 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011535 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011536 if (blocking < 0)
11537 return NULL;
11538 return PyBool_FromLong(blocking);
11539}
11540
11541PyDoc_STRVAR(set_blocking__doc__,
11542 "set_blocking(fd, blocking)\n" \
11543 "\n" \
11544 "Set the blocking mode of the specified file descriptor.\n" \
11545 "Set the O_NONBLOCK flag if blocking is False,\n" \
11546 "clear the O_NONBLOCK flag otherwise.");
11547
11548static PyObject*
11549posix_set_blocking(PyObject *self, PyObject *args)
11550{
Steve Dower8fc89802015-04-12 00:26:27 -040011551 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011552
11553 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11554 return NULL;
11555
Steve Dower8fc89802015-04-12 00:26:27 -040011556 _Py_BEGIN_SUPPRESS_IPH
11557 result = _Py_set_blocking(fd, blocking);
11558 _Py_END_SUPPRESS_IPH
11559 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011560 return NULL;
11561 Py_RETURN_NONE;
11562}
11563#endif /* !MS_WINDOWS */
11564
11565
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011566/*[clinic input]
11567class os.DirEntry "DirEntry *" "&DirEntryType"
11568[clinic start generated code]*/
11569/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011570
11571typedef struct {
11572 PyObject_HEAD
11573 PyObject *name;
11574 PyObject *path;
11575 PyObject *stat;
11576 PyObject *lstat;
11577#ifdef MS_WINDOWS
11578 struct _Py_stat_struct win32_lstat;
Victor Stinner0f6d7332017-03-09 17:34:28 +010011579 uint64_t win32_file_index;
Victor Stinner6036e442015-03-08 01:58:04 +010011580 int got_file_index;
11581#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011582#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011583 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011584#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011585 ino_t d_ino;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011586 int dir_fd;
Victor Stinner6036e442015-03-08 01:58:04 +010011587#endif
11588} DirEntry;
11589
11590static void
11591DirEntry_dealloc(DirEntry *entry)
11592{
11593 Py_XDECREF(entry->name);
11594 Py_XDECREF(entry->path);
11595 Py_XDECREF(entry->stat);
11596 Py_XDECREF(entry->lstat);
11597 Py_TYPE(entry)->tp_free((PyObject *)entry);
11598}
11599
11600/* Forward reference */
11601static int
11602DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11603
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011604/*[clinic input]
11605os.DirEntry.is_symlink -> bool
11606
11607Return True if the entry is a symbolic link; cached per entry.
11608[clinic start generated code]*/
11609
Victor Stinner6036e442015-03-08 01:58:04 +010011610static int
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011611os_DirEntry_is_symlink_impl(DirEntry *self)
11612/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011613{
11614#ifdef MS_WINDOWS
11615 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011616#elif defined(HAVE_DIRENT_D_TYPE)
11617 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011618 if (self->d_type != DT_UNKNOWN)
11619 return self->d_type == DT_LNK;
11620 else
11621 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011622#else
11623 /* POSIX without d_type */
11624 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011625#endif
11626}
11627
11628static PyObject *
Victor Stinner6036e442015-03-08 01:58:04 +010011629DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11630{
11631 int result;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011632 STRUCT_STAT st;
11633 PyObject *ub;
Victor Stinner6036e442015-03-08 01:58:04 +010011634
11635#ifdef MS_WINDOWS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011636 if (!PyUnicode_FSDecoder(self->path, &ub))
11637 return NULL;
11638 const wchar_t *path = PyUnicode_AsUnicode(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011639#else /* POSIX */
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011640 if (!PyUnicode_FSConverter(self->path, &ub))
11641 return NULL;
11642 const char *path = PyBytes_AS_STRING(ub);
11643 if (self->dir_fd != DEFAULT_DIR_FD) {
11644#ifdef HAVE_FSTATAT
11645 result = fstatat(self->dir_fd, path, &st,
11646 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
11647#else
11648 PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
11649 return NULL;
11650#endif /* HAVE_FSTATAT */
11651 }
11652 else
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011653#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011654 {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011655 if (follow_symlinks)
11656 result = STAT(path, &st);
11657 else
11658 result = LSTAT(path, &st);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030011659 }
11660 Py_DECREF(ub);
Victor Stinner6036e442015-03-08 01:58:04 +010011661
11662 if (result != 0)
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011663 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011664
11665 return _pystat_fromstructstat(&st);
11666}
11667
11668static PyObject *
11669DirEntry_get_lstat(DirEntry *self)
11670{
11671 if (!self->lstat) {
11672#ifdef MS_WINDOWS
11673 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11674#else /* POSIX */
11675 self->lstat = DirEntry_fetch_stat(self, 0);
11676#endif
11677 }
11678 Py_XINCREF(self->lstat);
11679 return self->lstat;
11680}
11681
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011682/*[clinic input]
11683os.DirEntry.stat
11684 *
11685 follow_symlinks: bool = True
11686
11687Return stat_result object for the entry; cached per entry.
11688[clinic start generated code]*/
11689
Victor Stinner6036e442015-03-08 01:58:04 +010011690static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011691os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
11692/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011693{
11694 if (!follow_symlinks)
11695 return DirEntry_get_lstat(self);
11696
11697 if (!self->stat) {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011698 int result = os_DirEntry_is_symlink_impl(self);
Victor Stinner6036e442015-03-08 01:58:04 +010011699 if (result == -1)
11700 return NULL;
11701 else if (result)
11702 self->stat = DirEntry_fetch_stat(self, 1);
11703 else
11704 self->stat = DirEntry_get_lstat(self);
11705 }
11706
11707 Py_XINCREF(self->stat);
11708 return self->stat;
11709}
11710
Victor Stinner6036e442015-03-08 01:58:04 +010011711/* Set exception and return -1 on error, 0 for False, 1 for True */
11712static int
11713DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11714{
11715 PyObject *stat = NULL;
11716 PyObject *st_mode = NULL;
11717 long mode;
11718 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011719#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011720 int is_symlink;
11721 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011722#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011723#ifdef MS_WINDOWS
11724 unsigned long dir_bits;
11725#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011726 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011727
11728#ifdef MS_WINDOWS
11729 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11730 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011731#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011732 is_symlink = self->d_type == DT_LNK;
11733 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11734#endif
11735
Victor Stinner35a97c02015-03-08 02:59:09 +010011736#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011737 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011738#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011739 stat = os_DirEntry_stat_impl(self, follow_symlinks);
Victor Stinner6036e442015-03-08 01:58:04 +010011740 if (!stat) {
11741 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11742 /* If file doesn't exist (anymore), then return False
11743 (i.e., say it's not a file/directory) */
11744 PyErr_Clear();
11745 return 0;
11746 }
11747 goto error;
11748 }
11749 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11750 if (!st_mode)
11751 goto error;
11752
11753 mode = PyLong_AsLong(st_mode);
11754 if (mode == -1 && PyErr_Occurred())
11755 goto error;
11756 Py_CLEAR(st_mode);
11757 Py_CLEAR(stat);
11758 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011759#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011760 }
11761 else if (is_symlink) {
11762 assert(mode_bits != S_IFLNK);
11763 result = 0;
11764 }
11765 else {
11766 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11767#ifdef MS_WINDOWS
11768 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11769 if (mode_bits == S_IFDIR)
11770 result = dir_bits != 0;
11771 else
11772 result = dir_bits == 0;
11773#else /* POSIX */
11774 if (mode_bits == S_IFDIR)
11775 result = self->d_type == DT_DIR;
11776 else
11777 result = self->d_type == DT_REG;
11778#endif
11779 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011780#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011781
11782 return result;
11783
11784error:
11785 Py_XDECREF(st_mode);
11786 Py_XDECREF(stat);
11787 return -1;
11788}
11789
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011790/*[clinic input]
11791os.DirEntry.is_dir -> bool
11792 *
11793 follow_symlinks: bool = True
Victor Stinner6036e442015-03-08 01:58:04 +010011794
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011795Return True if the entry is a directory; cached per entry.
11796[clinic start generated code]*/
11797
11798static int
11799os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
11800/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
11801{
11802 return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
Victor Stinner6036e442015-03-08 01:58:04 +010011803}
11804
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011805/*[clinic input]
11806os.DirEntry.is_file -> bool
11807 *
11808 follow_symlinks: bool = True
11809
11810Return True if the entry is a file; cached per entry.
11811[clinic start generated code]*/
11812
11813static int
11814os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
11815/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011816{
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011817 return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
Victor Stinner6036e442015-03-08 01:58:04 +010011818}
11819
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011820/*[clinic input]
11821os.DirEntry.inode
Victor Stinner6036e442015-03-08 01:58:04 +010011822
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011823Return inode of the entry; cached per entry.
11824[clinic start generated code]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011825
11826static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011827os_DirEntry_inode_impl(DirEntry *self)
11828/*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/
Victor Stinner6036e442015-03-08 01:58:04 +010011829{
11830#ifdef MS_WINDOWS
11831 if (!self->got_file_index) {
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011832 PyObject *unicode;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011833 const wchar_t *path;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011834 STRUCT_STAT stat;
11835 int result;
Victor Stinner6036e442015-03-08 01:58:04 +010011836
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011837 if (!PyUnicode_FSDecoder(self->path, &unicode))
Victor Stinner6036e442015-03-08 01:58:04 +010011838 return NULL;
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011839 path = PyUnicode_AsUnicode(unicode);
11840 result = LSTAT(path, &stat);
11841 Py_DECREF(unicode);
Victor Stinner6036e442015-03-08 01:58:04 +010011842
Serhiy Storchaka2674bc72016-10-08 20:16:57 +030011843 if (result != 0)
11844 return path_object_error(self->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011845
11846 self->win32_file_index = stat.st_ino;
11847 self->got_file_index = 1;
11848 }
Victor Stinner0f6d7332017-03-09 17:34:28 +010011849 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index));
11850 return PyLong_FromUnsignedLongLong(self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011851#else /* POSIX */
xdegaye50e86032017-05-22 11:15:08 +020011852 Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino));
11853 return PyLong_FromUnsignedLongLong(self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011854#endif
11855}
11856
11857static PyObject *
11858DirEntry_repr(DirEntry *self)
11859{
11860 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11861}
11862
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011863/*[clinic input]
11864os.DirEntry.__fspath__
11865
11866Returns the path for the entry.
11867[clinic start generated code]*/
11868
Brett Cannon96881cd2016-06-10 14:37:21 -070011869static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011870os_DirEntry___fspath___impl(DirEntry *self)
11871/*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/
Brett Cannon96881cd2016-06-10 14:37:21 -070011872{
11873 Py_INCREF(self->path);
11874 return self->path;
11875}
11876
Victor Stinner6036e442015-03-08 01:58:04 +010011877static PyMemberDef DirEntry_members[] = {
11878 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11879 "the entry's base filename, relative to scandir() \"path\" argument"},
11880 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11881 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11882 {NULL}
11883};
11884
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011885#include "clinic/posixmodule.c.h"
11886
Victor Stinner6036e442015-03-08 01:58:04 +010011887static PyMethodDef DirEntry_methods[] = {
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020011888 OS_DIRENTRY_IS_DIR_METHODDEF
11889 OS_DIRENTRY_IS_FILE_METHODDEF
11890 OS_DIRENTRY_IS_SYMLINK_METHODDEF
11891 OS_DIRENTRY_STAT_METHODDEF
11892 OS_DIRENTRY_INODE_METHODDEF
11893 OS_DIRENTRY___FSPATH___METHODDEF
Victor Stinner6036e442015-03-08 01:58:04 +010011894 {NULL}
11895};
11896
Benjamin Peterson5646de42015-04-12 17:56:34 -040011897static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011898 PyVarObject_HEAD_INIT(NULL, 0)
11899 MODNAME ".DirEntry", /* tp_name */
11900 sizeof(DirEntry), /* tp_basicsize */
11901 0, /* tp_itemsize */
11902 /* methods */
11903 (destructor)DirEntry_dealloc, /* tp_dealloc */
11904 0, /* tp_print */
11905 0, /* tp_getattr */
11906 0, /* tp_setattr */
11907 0, /* tp_compare */
11908 (reprfunc)DirEntry_repr, /* tp_repr */
11909 0, /* tp_as_number */
11910 0, /* tp_as_sequence */
11911 0, /* tp_as_mapping */
11912 0, /* tp_hash */
11913 0, /* tp_call */
11914 0, /* tp_str */
11915 0, /* tp_getattro */
11916 0, /* tp_setattro */
11917 0, /* tp_as_buffer */
11918 Py_TPFLAGS_DEFAULT, /* tp_flags */
11919 0, /* tp_doc */
11920 0, /* tp_traverse */
11921 0, /* tp_clear */
11922 0, /* tp_richcompare */
11923 0, /* tp_weaklistoffset */
11924 0, /* tp_iter */
11925 0, /* tp_iternext */
11926 DirEntry_methods, /* tp_methods */
11927 DirEntry_members, /* tp_members */
11928};
11929
11930#ifdef MS_WINDOWS
11931
11932static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011933join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011934{
11935 Py_ssize_t path_len;
11936 Py_ssize_t size;
11937 wchar_t *result;
11938 wchar_t ch;
11939
11940 if (!path_wide) { /* Default arg: "." */
11941 path_wide = L".";
11942 path_len = 1;
11943 }
11944 else {
11945 path_len = wcslen(path_wide);
11946 }
11947
11948 /* The +1's are for the path separator and the NUL */
11949 size = path_len + 1 + wcslen(filename) + 1;
11950 result = PyMem_New(wchar_t, size);
11951 if (!result) {
11952 PyErr_NoMemory();
11953 return NULL;
11954 }
11955 wcscpy(result, path_wide);
11956 if (path_len > 0) {
11957 ch = result[path_len - 1];
11958 if (ch != SEP && ch != ALTSEP && ch != L':')
11959 result[path_len++] = SEP;
11960 wcscpy(result + path_len, filename);
11961 }
11962 return result;
11963}
11964
11965static PyObject *
11966DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11967{
11968 DirEntry *entry;
11969 BY_HANDLE_FILE_INFORMATION file_info;
11970 ULONG reparse_tag;
11971 wchar_t *joined_path;
11972
11973 entry = PyObject_New(DirEntry, &DirEntryType);
11974 if (!entry)
11975 return NULL;
11976 entry->name = NULL;
11977 entry->path = NULL;
11978 entry->stat = NULL;
11979 entry->lstat = NULL;
11980 entry->got_file_index = 0;
11981
11982 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11983 if (!entry->name)
11984 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011985 if (path->narrow) {
11986 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11987 if (!entry->name)
11988 goto error;
11989 }
Victor Stinner6036e442015-03-08 01:58:04 +010011990
11991 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11992 if (!joined_path)
11993 goto error;
11994
11995 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11996 PyMem_Free(joined_path);
11997 if (!entry->path)
11998 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011999 if (path->narrow) {
12000 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
12001 if (!entry->path)
12002 goto error;
12003 }
Victor Stinner6036e442015-03-08 01:58:04 +010012004
Steve Dowercc16be82016-09-08 10:35:16 -070012005 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010012006 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
12007
12008 return (PyObject *)entry;
12009
12010error:
12011 Py_DECREF(entry);
12012 return NULL;
12013}
12014
12015#else /* POSIX */
12016
12017static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012018join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010012019{
12020 Py_ssize_t path_len;
12021 Py_ssize_t size;
12022 char *result;
12023
12024 if (!path_narrow) { /* Default arg: "." */
12025 path_narrow = ".";
12026 path_len = 1;
12027 }
12028 else {
12029 path_len = strlen(path_narrow);
12030 }
12031
12032 if (filename_len == -1)
12033 filename_len = strlen(filename);
12034
12035 /* The +1's are for the path separator and the NUL */
12036 size = path_len + 1 + filename_len + 1;
12037 result = PyMem_New(char, size);
12038 if (!result) {
12039 PyErr_NoMemory();
12040 return NULL;
12041 }
12042 strcpy(result, path_narrow);
12043 if (path_len > 0 && result[path_len - 1] != '/')
12044 result[path_len++] = '/';
12045 strcpy(result + path_len, filename);
12046 return result;
12047}
12048
12049static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020012050DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010012051 ino_t d_ino
12052#ifdef HAVE_DIRENT_D_TYPE
12053 , unsigned char d_type
12054#endif
12055 )
Victor Stinner6036e442015-03-08 01:58:04 +010012056{
12057 DirEntry *entry;
12058 char *joined_path;
12059
12060 entry = PyObject_New(DirEntry, &DirEntryType);
12061 if (!entry)
12062 return NULL;
12063 entry->name = NULL;
12064 entry->path = NULL;
12065 entry->stat = NULL;
12066 entry->lstat = NULL;
12067
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012068 if (path->fd != -1) {
12069 entry->dir_fd = path->fd;
12070 joined_path = NULL;
12071 }
12072 else {
12073 entry->dir_fd = DEFAULT_DIR_FD;
12074 joined_path = join_path_filename(path->narrow, name, name_len);
12075 if (!joined_path)
12076 goto error;
12077 }
Victor Stinner6036e442015-03-08 01:58:04 +010012078
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +030012079 if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
Victor Stinner6036e442015-03-08 01:58:04 +010012080 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012081 if (joined_path)
12082 entry->path = PyUnicode_DecodeFSDefault(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012083 }
12084 else {
12085 entry->name = PyBytes_FromStringAndSize(name, name_len);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012086 if (joined_path)
12087 entry->path = PyBytes_FromString(joined_path);
Victor Stinner6036e442015-03-08 01:58:04 +010012088 }
12089 PyMem_Free(joined_path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012090 if (!entry->name)
12091 goto error;
12092
12093 if (path->fd != -1) {
12094 entry->path = entry->name;
12095 Py_INCREF(entry->path);
12096 }
12097 else if (!entry->path)
Victor Stinner6036e442015-03-08 01:58:04 +010012098 goto error;
12099
Victor Stinner35a97c02015-03-08 02:59:09 +010012100#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012101 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012102#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012103 entry->d_ino = d_ino;
12104
12105 return (PyObject *)entry;
12106
12107error:
12108 Py_XDECREF(entry);
12109 return NULL;
12110}
12111
12112#endif
12113
12114
12115typedef struct {
12116 PyObject_HEAD
12117 path_t path;
12118#ifdef MS_WINDOWS
12119 HANDLE handle;
12120 WIN32_FIND_DATAW file_data;
12121 int first_time;
12122#else /* POSIX */
12123 DIR *dirp;
12124#endif
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012125#ifdef HAVE_FDOPENDIR
12126 int fd;
12127#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012128} ScandirIterator;
12129
12130#ifdef MS_WINDOWS
12131
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012132static int
12133ScandirIterator_is_closed(ScandirIterator *iterator)
12134{
12135 return iterator->handle == INVALID_HANDLE_VALUE;
12136}
12137
Victor Stinner6036e442015-03-08 01:58:04 +010012138static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012139ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012140{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012141 HANDLE handle = iterator->handle;
12142
12143 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012144 return;
12145
Victor Stinner6036e442015-03-08 01:58:04 +010012146 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012147 Py_BEGIN_ALLOW_THREADS
12148 FindClose(handle);
12149 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012150}
12151
12152static PyObject *
12153ScandirIterator_iternext(ScandirIterator *iterator)
12154{
12155 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12156 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012157 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012158
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012159 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012160 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012161 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012162
12163 while (1) {
12164 if (!iterator->first_time) {
12165 Py_BEGIN_ALLOW_THREADS
12166 success = FindNextFileW(iterator->handle, file_data);
12167 Py_END_ALLOW_THREADS
12168 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012169 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012170 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012171 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012172 break;
12173 }
12174 }
12175 iterator->first_time = 0;
12176
12177 /* Skip over . and .. */
12178 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012179 wcscmp(file_data->cFileName, L"..") != 0) {
12180 entry = DirEntry_from_find_data(&iterator->path, file_data);
12181 if (!entry)
12182 break;
12183 return entry;
12184 }
Victor Stinner6036e442015-03-08 01:58:04 +010012185
12186 /* Loop till we get a non-dot directory or finish iterating */
12187 }
12188
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012189 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012190 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012191 return NULL;
12192}
12193
12194#else /* POSIX */
12195
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012196static int
12197ScandirIterator_is_closed(ScandirIterator *iterator)
12198{
12199 return !iterator->dirp;
12200}
12201
Victor Stinner6036e442015-03-08 01:58:04 +010012202static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012203ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012204{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012205 DIR *dirp = iterator->dirp;
12206
12207 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012208 return;
12209
Victor Stinner6036e442015-03-08 01:58:04 +010012210 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012211 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012212#ifdef HAVE_FDOPENDIR
12213 if (iterator->path.fd != -1)
12214 rewinddir(dirp);
12215#endif
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012216 closedir(dirp);
12217 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012218 return;
12219}
12220
12221static PyObject *
12222ScandirIterator_iternext(ScandirIterator *iterator)
12223{
12224 struct dirent *direntp;
12225 Py_ssize_t name_len;
12226 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012227 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012228
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012229 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012230 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012231 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012232
12233 while (1) {
12234 errno = 0;
12235 Py_BEGIN_ALLOW_THREADS
12236 direntp = readdir(iterator->dirp);
12237 Py_END_ALLOW_THREADS
12238
12239 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012240 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012241 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012242 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012243 break;
12244 }
12245
12246 /* Skip over . and .. */
12247 name_len = NAMLEN(direntp);
12248 is_dot = direntp->d_name[0] == '.' &&
12249 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12250 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012251 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012252 name_len, direntp->d_ino
12253#ifdef HAVE_DIRENT_D_TYPE
12254 , direntp->d_type
12255#endif
12256 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012257 if (!entry)
12258 break;
12259 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012260 }
12261
12262 /* Loop till we get a non-dot directory or finish iterating */
12263 }
12264
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012265 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012266 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012267 return NULL;
12268}
12269
12270#endif
12271
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012272static PyObject *
12273ScandirIterator_close(ScandirIterator *self, PyObject *args)
12274{
12275 ScandirIterator_closedir(self);
12276 Py_RETURN_NONE;
12277}
12278
12279static PyObject *
12280ScandirIterator_enter(PyObject *self, PyObject *args)
12281{
12282 Py_INCREF(self);
12283 return self;
12284}
12285
12286static PyObject *
12287ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12288{
12289 ScandirIterator_closedir(self);
12290 Py_RETURN_NONE;
12291}
12292
Victor Stinner6036e442015-03-08 01:58:04 +010012293static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012294ScandirIterator_finalize(ScandirIterator *iterator)
12295{
12296 PyObject *error_type, *error_value, *error_traceback;
12297
12298 /* Save the current exception, if any. */
12299 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12300
12301 if (!ScandirIterator_is_closed(iterator)) {
12302 ScandirIterator_closedir(iterator);
12303
12304 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12305 "unclosed scandir iterator %R", iterator)) {
12306 /* Spurious errors can appear at shutdown */
12307 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12308 PyErr_WriteUnraisable((PyObject *) iterator);
12309 }
12310 }
12311 }
12312
Victor Stinner7bfa4092016-03-23 00:43:54 +010012313 path_cleanup(&iterator->path);
12314
12315 /* Restore the saved exception. */
12316 PyErr_Restore(error_type, error_value, error_traceback);
12317}
12318
12319static void
Victor Stinner6036e442015-03-08 01:58:04 +010012320ScandirIterator_dealloc(ScandirIterator *iterator)
12321{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012322 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12323 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012324
Victor Stinner6036e442015-03-08 01:58:04 +010012325 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12326}
12327
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012328static PyMethodDef ScandirIterator_methods[] = {
12329 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12330 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12331 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12332 {NULL}
12333};
12334
Benjamin Peterson5646de42015-04-12 17:56:34 -040012335static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012336 PyVarObject_HEAD_INIT(NULL, 0)
12337 MODNAME ".ScandirIterator", /* tp_name */
12338 sizeof(ScandirIterator), /* tp_basicsize */
12339 0, /* tp_itemsize */
12340 /* methods */
12341 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12342 0, /* tp_print */
12343 0, /* tp_getattr */
12344 0, /* tp_setattr */
12345 0, /* tp_compare */
12346 0, /* tp_repr */
12347 0, /* tp_as_number */
12348 0, /* tp_as_sequence */
12349 0, /* tp_as_mapping */
12350 0, /* tp_hash */
12351 0, /* tp_call */
12352 0, /* tp_str */
12353 0, /* tp_getattro */
12354 0, /* tp_setattro */
12355 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012356 Py_TPFLAGS_DEFAULT
12357 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012358 0, /* tp_doc */
12359 0, /* tp_traverse */
12360 0, /* tp_clear */
12361 0, /* tp_richcompare */
12362 0, /* tp_weaklistoffset */
12363 PyObject_SelfIter, /* tp_iter */
12364 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012365 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012366 0, /* tp_members */
12367 0, /* tp_getset */
12368 0, /* tp_base */
12369 0, /* tp_dict */
12370 0, /* tp_descr_get */
12371 0, /* tp_descr_set */
12372 0, /* tp_dictoffset */
12373 0, /* tp_init */
12374 0, /* tp_alloc */
12375 0, /* tp_new */
12376 0, /* tp_free */
12377 0, /* tp_is_gc */
12378 0, /* tp_bases */
12379 0, /* tp_mro */
12380 0, /* tp_cache */
12381 0, /* tp_subclasses */
12382 0, /* tp_weaklist */
12383 0, /* tp_del */
12384 0, /* tp_version_tag */
12385 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012386};
12387
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012388/*[clinic input]
12389os.scandir
12390
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012391 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012392
12393Return an iterator of DirEntry objects for given path.
12394
12395path can be specified as either str, bytes or path-like object. If path
12396is bytes, the names of yielded DirEntry objects will also be bytes; in
12397all other circumstances they will be str.
12398
12399If path is None, uses the path='.'.
12400[clinic start generated code]*/
12401
Victor Stinner6036e442015-03-08 01:58:04 +010012402static PyObject *
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012403os_scandir_impl(PyObject *module, path_t *path)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012404/*[clinic end generated code: output=6eb2668b675ca89e input=b139dc1c57f60846]*/
Victor Stinner6036e442015-03-08 01:58:04 +010012405{
12406 ScandirIterator *iterator;
Victor Stinner6036e442015-03-08 01:58:04 +010012407#ifdef MS_WINDOWS
12408 wchar_t *path_strW;
12409#else
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012410 const char *path_str;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012411#ifdef HAVE_FDOPENDIR
12412 int fd = -1;
12413#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012414#endif
12415
12416 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12417 if (!iterator)
12418 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012419
12420#ifdef MS_WINDOWS
12421 iterator->handle = INVALID_HANDLE_VALUE;
12422#else
12423 iterator->dirp = NULL;
12424#endif
12425
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012426 memcpy(&iterator->path, path, sizeof(path_t));
Serhiy Storchaka095ef732017-02-09 20:05:51 +020012427 /* Move the ownership to iterator->path */
12428 path->object = NULL;
12429 path->cleanup = NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012430
12431#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010012432 iterator->first_time = 1;
12433
12434 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12435 if (!path_strW)
12436 goto error;
12437
12438 Py_BEGIN_ALLOW_THREADS
12439 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12440 Py_END_ALLOW_THREADS
12441
12442 PyMem_Free(path_strW);
12443
12444 if (iterator->handle == INVALID_HANDLE_VALUE) {
12445 path_error(&iterator->path);
12446 goto error;
12447 }
12448#else /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010012449 errno = 0;
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012450#ifdef HAVE_FDOPENDIR
12451 if (path->fd != -1) {
12452 /* closedir() closes the FD, so we duplicate it */
12453 fd = _Py_dup(path->fd);
12454 if (fd == -1)
12455 goto error;
12456
12457 Py_BEGIN_ALLOW_THREADS
12458 iterator->dirp = fdopendir(fd);
12459 Py_END_ALLOW_THREADS
12460 }
12461 else
12462#endif
12463 {
12464 if (iterator->path.narrow)
12465 path_str = iterator->path.narrow;
12466 else
12467 path_str = ".";
12468
12469 Py_BEGIN_ALLOW_THREADS
12470 iterator->dirp = opendir(path_str);
12471 Py_END_ALLOW_THREADS
12472 }
Victor Stinner6036e442015-03-08 01:58:04 +010012473
12474 if (!iterator->dirp) {
12475 path_error(&iterator->path);
Serhiy Storchakaea720fe2017-03-30 09:12:31 +030012476#ifdef HAVE_FDOPENDIR
12477 if (fd != -1) {
12478 Py_BEGIN_ALLOW_THREADS
12479 close(fd);
12480 Py_END_ALLOW_THREADS
12481 }
12482#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012483 goto error;
12484 }
12485#endif
12486
12487 return (PyObject *)iterator;
12488
12489error:
12490 Py_DECREF(iterator);
12491 return NULL;
12492}
12493
Ethan Furman410ef8e2016-06-04 12:06:26 -070012494/*
12495 Return the file system path representation of the object.
12496
12497 If the object is str or bytes, then allow it to pass through with
12498 an incremented refcount. If the object defines __fspath__(), then
12499 return the result of that method. All other types raise a TypeError.
12500*/
12501PyObject *
12502PyOS_FSPath(PyObject *path)
12503{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012504 /* For error message reasons, this function is manually inlined in
12505 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012506 _Py_IDENTIFIER(__fspath__);
12507 PyObject *func = NULL;
12508 PyObject *path_repr = NULL;
12509
12510 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12511 Py_INCREF(path);
12512 return path;
12513 }
12514
12515 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12516 if (NULL == func) {
12517 return PyErr_Format(PyExc_TypeError,
12518 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012519 "not %.200s",
12520 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012521 }
12522
Victor Stinnerf17c3de2016-12-06 18:46:19 +010012523 path_repr = _PyObject_CallNoArg(func);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012524 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012525 if (NULL == path_repr) {
12526 return NULL;
12527 }
12528
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012529 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12530 PyErr_Format(PyExc_TypeError,
12531 "expected %.200s.__fspath__() to return str or bytes, "
12532 "not %.200s", Py_TYPE(path)->tp_name,
12533 Py_TYPE(path_repr)->tp_name);
12534 Py_DECREF(path_repr);
12535 return NULL;
12536 }
12537
Ethan Furman410ef8e2016-06-04 12:06:26 -070012538 return path_repr;
12539}
12540
12541/*[clinic input]
12542os.fspath
12543
12544 path: object
12545
12546Return the file system path representation of the object.
12547
Brett Cannonb4f43e92016-06-09 14:32:08 -070012548If the object is str or bytes, then allow it to pass through as-is. If the
12549object defines __fspath__(), then return the result of that method. All other
12550types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012551[clinic start generated code]*/
12552
12553static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012554os_fspath_impl(PyObject *module, PyObject *path)
12555/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012556{
12557 return PyOS_FSPath(path);
12558}
Victor Stinner6036e442015-03-08 01:58:04 +010012559
Victor Stinner9b1f4742016-09-06 16:18:52 -070012560#ifdef HAVE_GETRANDOM_SYSCALL
12561/*[clinic input]
12562os.getrandom
12563
12564 size: Py_ssize_t
12565 flags: int=0
12566
12567Obtain a series of random bytes.
12568[clinic start generated code]*/
12569
12570static PyObject *
12571os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12572/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12573{
Victor Stinner9b1f4742016-09-06 16:18:52 -070012574 PyObject *bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012575 Py_ssize_t n;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012576
12577 if (size < 0) {
12578 errno = EINVAL;
12579 return posix_error();
12580 }
12581
Victor Stinnerec2319c2016-09-20 23:00:59 +020012582 bytes = PyBytes_FromStringAndSize(NULL, size);
12583 if (bytes == NULL) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012584 PyErr_NoMemory();
12585 return NULL;
12586 }
12587
12588 while (1) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012589 n = syscall(SYS_getrandom,
12590 PyBytes_AS_STRING(bytes),
12591 PyBytes_GET_SIZE(bytes),
12592 flags);
Victor Stinner9b1f4742016-09-06 16:18:52 -070012593 if (n < 0 && errno == EINTR) {
12594 if (PyErr_CheckSignals() < 0) {
Victor Stinnerec2319c2016-09-20 23:00:59 +020012595 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012596 }
Victor Stinnerec2319c2016-09-20 23:00:59 +020012597
12598 /* getrandom() was interrupted by a signal: retry */
Victor Stinner9b1f4742016-09-06 16:18:52 -070012599 continue;
12600 }
12601 break;
12602 }
12603
12604 if (n < 0) {
Victor Stinner9b1f4742016-09-06 16:18:52 -070012605 PyErr_SetFromErrno(PyExc_OSError);
Victor Stinnerec2319c2016-09-20 23:00:59 +020012606 goto error;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012607 }
12608
Victor Stinnerec2319c2016-09-20 23:00:59 +020012609 if (n != size) {
12610 _PyBytes_Resize(&bytes, n);
12611 }
Victor Stinner9b1f4742016-09-06 16:18:52 -070012612
12613 return bytes;
Victor Stinnerec2319c2016-09-20 23:00:59 +020012614
12615error:
12616 Py_DECREF(bytes);
12617 return NULL;
Victor Stinner9b1f4742016-09-06 16:18:52 -070012618}
12619#endif /* HAVE_GETRANDOM_SYSCALL */
12620
Larry Hastings31826802013-10-19 00:09:25 -070012621
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012622static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012623
12624 OS_STAT_METHODDEF
12625 OS_ACCESS_METHODDEF
12626 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012627 OS_CHDIR_METHODDEF
12628 OS_CHFLAGS_METHODDEF
12629 OS_CHMOD_METHODDEF
12630 OS_FCHMOD_METHODDEF
12631 OS_LCHMOD_METHODDEF
12632 OS_CHOWN_METHODDEF
12633 OS_FCHOWN_METHODDEF
12634 OS_LCHOWN_METHODDEF
12635 OS_LCHFLAGS_METHODDEF
12636 OS_CHROOT_METHODDEF
12637 OS_CTERMID_METHODDEF
12638 OS_GETCWD_METHODDEF
12639 OS_GETCWDB_METHODDEF
12640 OS_LINK_METHODDEF
12641 OS_LISTDIR_METHODDEF
12642 OS_LSTAT_METHODDEF
12643 OS_MKDIR_METHODDEF
12644 OS_NICE_METHODDEF
12645 OS_GETPRIORITY_METHODDEF
12646 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012647#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012648 {"readlink", (PyCFunction)posix_readlink,
12649 METH_VARARGS | METH_KEYWORDS,
12650 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012651#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012652#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012653 {"readlink", (PyCFunction)win_readlink,
12654 METH_VARARGS | METH_KEYWORDS,
12655 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012656#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012657 OS_RENAME_METHODDEF
12658 OS_REPLACE_METHODDEF
12659 OS_RMDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012660 OS_SYMLINK_METHODDEF
12661 OS_SYSTEM_METHODDEF
12662 OS_UMASK_METHODDEF
12663 OS_UNAME_METHODDEF
12664 OS_UNLINK_METHODDEF
12665 OS_REMOVE_METHODDEF
12666 OS_UTIME_METHODDEF
12667 OS_TIMES_METHODDEF
12668 OS__EXIT_METHODDEF
12669 OS_EXECV_METHODDEF
12670 OS_EXECVE_METHODDEF
12671 OS_SPAWNV_METHODDEF
12672 OS_SPAWNVE_METHODDEF
12673 OS_FORK1_METHODDEF
12674 OS_FORK_METHODDEF
Antoine Pitrou346cbd32017-05-27 17:50:54 +020012675 OS_REGISTER_AT_FORK_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012676 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12677 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12678 OS_SCHED_GETPARAM_METHODDEF
12679 OS_SCHED_GETSCHEDULER_METHODDEF
12680 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12681 OS_SCHED_SETPARAM_METHODDEF
12682 OS_SCHED_SETSCHEDULER_METHODDEF
12683 OS_SCHED_YIELD_METHODDEF
12684 OS_SCHED_SETAFFINITY_METHODDEF
12685 OS_SCHED_GETAFFINITY_METHODDEF
12686 OS_OPENPTY_METHODDEF
12687 OS_FORKPTY_METHODDEF
12688 OS_GETEGID_METHODDEF
12689 OS_GETEUID_METHODDEF
12690 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012691#ifdef HAVE_GETGROUPLIST
12692 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12693#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012694 OS_GETGROUPS_METHODDEF
12695 OS_GETPID_METHODDEF
12696 OS_GETPGRP_METHODDEF
12697 OS_GETPPID_METHODDEF
12698 OS_GETUID_METHODDEF
12699 OS_GETLOGIN_METHODDEF
12700 OS_KILL_METHODDEF
12701 OS_KILLPG_METHODDEF
12702 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012703#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012704 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012705#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012706 OS_SETUID_METHODDEF
12707 OS_SETEUID_METHODDEF
12708 OS_SETREUID_METHODDEF
12709 OS_SETGID_METHODDEF
12710 OS_SETEGID_METHODDEF
12711 OS_SETREGID_METHODDEF
12712 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012713#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012714 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012715#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012716 OS_GETPGID_METHODDEF
12717 OS_SETPGRP_METHODDEF
12718 OS_WAIT_METHODDEF
12719 OS_WAIT3_METHODDEF
12720 OS_WAIT4_METHODDEF
12721 OS_WAITID_METHODDEF
12722 OS_WAITPID_METHODDEF
12723 OS_GETSID_METHODDEF
12724 OS_SETSID_METHODDEF
12725 OS_SETPGID_METHODDEF
12726 OS_TCGETPGRP_METHODDEF
12727 OS_TCSETPGRP_METHODDEF
12728 OS_OPEN_METHODDEF
12729 OS_CLOSE_METHODDEF
12730 OS_CLOSERANGE_METHODDEF
12731 OS_DEVICE_ENCODING_METHODDEF
12732 OS_DUP_METHODDEF
12733 OS_DUP2_METHODDEF
12734 OS_LOCKF_METHODDEF
12735 OS_LSEEK_METHODDEF
12736 OS_READ_METHODDEF
12737 OS_READV_METHODDEF
12738 OS_PREAD_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012739 OS_PREADV_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012740 OS_WRITE_METHODDEF
12741 OS_WRITEV_METHODDEF
12742 OS_PWRITE_METHODDEF
Pablo Galindo4defba32018-01-27 16:16:37 +000012743 OS_PWRITEV_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012744#ifdef HAVE_SENDFILE
12745 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12746 posix_sendfile__doc__},
12747#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012748 OS_FSTAT_METHODDEF
12749 OS_ISATTY_METHODDEF
12750 OS_PIPE_METHODDEF
12751 OS_PIPE2_METHODDEF
12752 OS_MKFIFO_METHODDEF
12753 OS_MKNOD_METHODDEF
12754 OS_MAJOR_METHODDEF
12755 OS_MINOR_METHODDEF
12756 OS_MAKEDEV_METHODDEF
12757 OS_FTRUNCATE_METHODDEF
12758 OS_TRUNCATE_METHODDEF
12759 OS_POSIX_FALLOCATE_METHODDEF
12760 OS_POSIX_FADVISE_METHODDEF
12761 OS_PUTENV_METHODDEF
12762 OS_UNSETENV_METHODDEF
12763 OS_STRERROR_METHODDEF
12764 OS_FCHDIR_METHODDEF
12765 OS_FSYNC_METHODDEF
12766 OS_SYNC_METHODDEF
12767 OS_FDATASYNC_METHODDEF
12768 OS_WCOREDUMP_METHODDEF
12769 OS_WIFCONTINUED_METHODDEF
12770 OS_WIFSTOPPED_METHODDEF
12771 OS_WIFSIGNALED_METHODDEF
12772 OS_WIFEXITED_METHODDEF
12773 OS_WEXITSTATUS_METHODDEF
12774 OS_WTERMSIG_METHODDEF
12775 OS_WSTOPSIG_METHODDEF
12776 OS_FSTATVFS_METHODDEF
12777 OS_STATVFS_METHODDEF
12778 OS_CONFSTR_METHODDEF
12779 OS_SYSCONF_METHODDEF
12780 OS_FPATHCONF_METHODDEF
12781 OS_PATHCONF_METHODDEF
12782 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012783 OS__GETFULLPATHNAME_METHODDEF
12784 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012785 OS__GETDISKUSAGE_METHODDEF
12786 OS__GETFINALPATHNAME_METHODDEF
12787 OS__GETVOLUMEPATHNAME_METHODDEF
12788 OS_GETLOADAVG_METHODDEF
12789 OS_URANDOM_METHODDEF
12790 OS_SETRESUID_METHODDEF
12791 OS_SETRESGID_METHODDEF
12792 OS_GETRESUID_METHODDEF
12793 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012794
Larry Hastings2f936352014-08-05 14:04:04 +100012795 OS_GETXATTR_METHODDEF
12796 OS_SETXATTR_METHODDEF
12797 OS_REMOVEXATTR_METHODDEF
12798 OS_LISTXATTR_METHODDEF
12799
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012800#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12801 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12802#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012803 OS_CPU_COUNT_METHODDEF
12804 OS_GET_INHERITABLE_METHODDEF
12805 OS_SET_INHERITABLE_METHODDEF
12806 OS_GET_HANDLE_INHERITABLE_METHODDEF
12807 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012808#ifndef MS_WINDOWS
12809 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12810 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12811#endif
Serhiy Storchaka49d02d12016-11-06 13:45:33 +020012812 OS_SCANDIR_METHODDEF
Ethan Furman410ef8e2016-06-04 12:06:26 -070012813 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012814 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012815 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012816};
12817
12818
Brian Curtin52173d42010-12-02 18:29:18 +000012819#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012820static int
Brian Curtin52173d42010-12-02 18:29:18 +000012821enable_symlink()
12822{
12823 HANDLE tok;
12824 TOKEN_PRIVILEGES tok_priv;
12825 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012826
12827 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012828 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012829
12830 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012831 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012832
12833 tok_priv.PrivilegeCount = 1;
12834 tok_priv.Privileges[0].Luid = luid;
12835 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12836
12837 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12838 sizeof(TOKEN_PRIVILEGES),
12839 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012840 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012841
Brian Curtin3b4499c2010-12-28 14:31:47 +000012842 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12843 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012844}
12845#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12846
Barry Warsaw4a342091996-12-19 23:50:02 +000012847static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012849{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012850#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012852#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012853#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012855#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012856#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012857 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012858#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012859#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012861#endif
Fred Drakec9680921999-12-13 16:37:25 +000012862#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012863 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012864#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012865#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012867#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012868#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012870#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012871#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012873#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012874#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012876#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012877#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012879#endif
12880#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012882#endif
12883#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012885#endif
12886#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012888#endif
12889#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012891#endif
12892#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012893 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012894#endif
12895#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012897#endif
12898#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012900#endif
12901#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012903#endif
12904#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012906#endif
12907#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012909#endif
12910#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012911 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012912#endif
12913#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012915#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012916#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012917 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012918#endif
12919#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012920 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012921#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012922#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012923 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012924#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012925#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012926 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012927#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012928#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012929#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012930 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012931#endif
12932#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012934#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012935#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012936#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012937 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012938#endif
12939#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012941#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012942#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012943 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012944#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012945#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012947#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012948#ifdef O_TMPFILE
12949 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12950#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012951#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012953#endif
12954#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012955 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012956#endif
12957#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012958 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012959#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012960#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012961 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012962#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012963#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012964 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012965#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012966
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012967
Jesus Cea94363612012-06-22 18:32:07 +020012968#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012969 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012970#endif
12971#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012972 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012973#endif
12974
Tim Peters5aa91602002-01-30 05:46:57 +000012975/* MS Windows */
12976#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012977 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012978 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012979#endif
12980#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012981 /* Optimize for short life (keep in memory). */
12982 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012983 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012984#endif
12985#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012987 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012988#endif
12989#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012990 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012991 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012992#endif
12993#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012994 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012995 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012996#endif
12997
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012998/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012999#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000013000 /* Send a SIGIO signal whenever input or output
13001 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013002 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000013003#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013004#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000013005 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013007#endif
13008#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000013009 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013010 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013011#endif
13012#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013014 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000013015#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020013016#ifdef O_NOLINKS
13017 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020013019#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013020#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000013021 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013022 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000013023#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000013024
Victor Stinner8c62be82010-05-06 00:08:46 +000013025 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013026#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013027 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013028#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013029#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013030 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013031#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013032#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013033 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013034#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013035#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013036 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013037#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013038#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013039 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013040#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013041#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013042 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013043#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013044#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013046#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013047#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013048 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013049#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013050#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013051 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013052#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013053#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013054 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013055#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013056#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013057 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013058#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013059#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013060 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013061#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013062#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013063 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013064#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013065#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013066 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013067#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013068#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013069 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013070#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013071#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013072 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013073#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013074#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013075 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000013076#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000013077
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000013078 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013079#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013080 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013081#endif /* ST_RDONLY */
13082#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013083 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000013084#endif /* ST_NOSUID */
13085
doko@ubuntu.comca616a22013-12-08 15:23:07 +010013086 /* GNU extensions */
13087#ifdef ST_NODEV
13088 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
13089#endif /* ST_NODEV */
13090#ifdef ST_NOEXEC
13091 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
13092#endif /* ST_NOEXEC */
13093#ifdef ST_SYNCHRONOUS
13094 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
13095#endif /* ST_SYNCHRONOUS */
13096#ifdef ST_MANDLOCK
13097 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
13098#endif /* ST_MANDLOCK */
13099#ifdef ST_WRITE
13100 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
13101#endif /* ST_WRITE */
13102#ifdef ST_APPEND
13103 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
13104#endif /* ST_APPEND */
13105#ifdef ST_NOATIME
13106 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
13107#endif /* ST_NOATIME */
13108#ifdef ST_NODIRATIME
13109 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
13110#endif /* ST_NODIRATIME */
13111#ifdef ST_RELATIME
13112 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
13113#endif /* ST_RELATIME */
13114
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013115 /* FreeBSD sendfile() constants */
13116#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013117 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013118#endif
13119#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013120 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013121#endif
13122#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013123 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000013124#endif
13125
Ross Lagerwall7807c352011-03-17 20:20:30 +020013126 /* constants for posix_fadvise */
13127#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013128 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013129#endif
13130#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013131 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013132#endif
13133#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013134 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013135#endif
13136#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013137 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013138#endif
13139#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013140 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013141#endif
13142#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013143 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013144#endif
13145
13146 /* constants for waitid */
13147#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013148 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13149 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13150 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013151#endif
13152#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013153 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013154#endif
13155#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013156 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013157#endif
13158#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013159 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013160#endif
13161#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013162 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013163#endif
13164#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013165 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013166#endif
13167#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013168 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013169#endif
13170#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013171 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013172#endif
13173
13174 /* constants for lockf */
13175#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013176 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013177#endif
13178#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013179 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013180#endif
13181#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013182 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013183#endif
13184#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013185 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013186#endif
13187
Pablo Galindo4defba32018-01-27 16:16:37 +000013188#ifdef RWF_DSYNC
13189 if (PyModule_AddIntConstant(m, "RWF_DSYNC", RWF_DSYNC)) return -1;
13190#endif
13191#ifdef RWF_HIPRI
13192 if (PyModule_AddIntConstant(m, "RWF_HIPRI", RWF_HIPRI)) return -1;
13193#endif
13194#ifdef RWF_SYNC
13195 if (PyModule_AddIntConstant(m, "RWF_SYNC", RWF_SYNC)) return -1;
13196#endif
13197#ifdef RWF_NOWAIT
13198 if (PyModule_AddIntConstant(m, "RWF_NOWAIT", RWF_NOWAIT)) return -1;
13199#endif
13200
Guido van Rossum246bc171999-02-01 23:54:31 +000013201#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013202 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13203 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13204 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13205 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13206 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013207#endif
13208
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013209#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013210#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013211 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013212#endif
13213#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013214 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013215#endif
13216#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013217 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013218#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013219#ifdef SCHED_SPORADIC
messi Liao0d322182017-06-13 22:30:43 +080013220 if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013221#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013222#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013223 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013224#endif
13225#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013226 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013227#endif
13228#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013229 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013230#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013231#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013232 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013233#endif
13234#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013235 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013236#endif
13237#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013238 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013239#endif
13240#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013241 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013242#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013243#endif
13244
Benjamin Peterson9428d532011-09-14 11:45:52 -040013245#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013246 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13247 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13248 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013249#endif
13250
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013251#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013252 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013253#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013254#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013255 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013256#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013257#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013258 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013259#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013260#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013261 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013262#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013263#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013264 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013265#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013266#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013267 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013268#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013269#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013270 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013271#endif
Michael Feltc5ae1692017-12-19 13:58:49 +010013272#if HAVE_DECL_RTLD_MEMBER
13273 if (PyModule_AddIntMacro(m, RTLD_MEMBER)) return -1;
13274#endif
Victor Stinner8b905bd2011-10-25 13:34:04 +020013275
Victor Stinner9b1f4742016-09-06 16:18:52 -070013276#ifdef HAVE_GETRANDOM_SYSCALL
13277 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13278 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13279#endif
13280
Victor Stinner8c62be82010-05-06 00:08:46 +000013281 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013282}
13283
13284
Martin v. Löwis1a214512008-06-11 05:26:20 +000013285static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013286 PyModuleDef_HEAD_INIT,
13287 MODNAME,
13288 posix__doc__,
13289 -1,
13290 posix_methods,
13291 NULL,
13292 NULL,
13293 NULL,
13294 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013295};
13296
13297
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013298static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013299
13300#ifdef HAVE_FACCESSAT
13301 "HAVE_FACCESSAT",
13302#endif
13303
13304#ifdef HAVE_FCHDIR
13305 "HAVE_FCHDIR",
13306#endif
13307
13308#ifdef HAVE_FCHMOD
13309 "HAVE_FCHMOD",
13310#endif
13311
13312#ifdef HAVE_FCHMODAT
13313 "HAVE_FCHMODAT",
13314#endif
13315
13316#ifdef HAVE_FCHOWN
13317 "HAVE_FCHOWN",
13318#endif
13319
Larry Hastings00964ed2013-08-12 13:49:30 -040013320#ifdef HAVE_FCHOWNAT
13321 "HAVE_FCHOWNAT",
13322#endif
13323
Larry Hastings9cf065c2012-06-22 16:30:09 -070013324#ifdef HAVE_FEXECVE
13325 "HAVE_FEXECVE",
13326#endif
13327
13328#ifdef HAVE_FDOPENDIR
13329 "HAVE_FDOPENDIR",
13330#endif
13331
Georg Brandl306336b2012-06-24 12:55:33 +020013332#ifdef HAVE_FPATHCONF
13333 "HAVE_FPATHCONF",
13334#endif
13335
Larry Hastings9cf065c2012-06-22 16:30:09 -070013336#ifdef HAVE_FSTATAT
13337 "HAVE_FSTATAT",
13338#endif
13339
13340#ifdef HAVE_FSTATVFS
13341 "HAVE_FSTATVFS",
13342#endif
13343
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013344#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013345 "HAVE_FTRUNCATE",
13346#endif
13347
Larry Hastings9cf065c2012-06-22 16:30:09 -070013348#ifdef HAVE_FUTIMENS
13349 "HAVE_FUTIMENS",
13350#endif
13351
13352#ifdef HAVE_FUTIMES
13353 "HAVE_FUTIMES",
13354#endif
13355
13356#ifdef HAVE_FUTIMESAT
13357 "HAVE_FUTIMESAT",
13358#endif
13359
13360#ifdef HAVE_LINKAT
13361 "HAVE_LINKAT",
13362#endif
13363
13364#ifdef HAVE_LCHFLAGS
13365 "HAVE_LCHFLAGS",
13366#endif
13367
13368#ifdef HAVE_LCHMOD
13369 "HAVE_LCHMOD",
13370#endif
13371
13372#ifdef HAVE_LCHOWN
13373 "HAVE_LCHOWN",
13374#endif
13375
13376#ifdef HAVE_LSTAT
13377 "HAVE_LSTAT",
13378#endif
13379
13380#ifdef HAVE_LUTIMES
13381 "HAVE_LUTIMES",
13382#endif
13383
13384#ifdef HAVE_MKDIRAT
13385 "HAVE_MKDIRAT",
13386#endif
13387
13388#ifdef HAVE_MKFIFOAT
13389 "HAVE_MKFIFOAT",
13390#endif
13391
13392#ifdef HAVE_MKNODAT
13393 "HAVE_MKNODAT",
13394#endif
13395
13396#ifdef HAVE_OPENAT
13397 "HAVE_OPENAT",
13398#endif
13399
13400#ifdef HAVE_READLINKAT
13401 "HAVE_READLINKAT",
13402#endif
13403
13404#ifdef HAVE_RENAMEAT
13405 "HAVE_RENAMEAT",
13406#endif
13407
13408#ifdef HAVE_SYMLINKAT
13409 "HAVE_SYMLINKAT",
13410#endif
13411
13412#ifdef HAVE_UNLINKAT
13413 "HAVE_UNLINKAT",
13414#endif
13415
13416#ifdef HAVE_UTIMENSAT
13417 "HAVE_UTIMENSAT",
13418#endif
13419
13420#ifdef MS_WINDOWS
13421 "MS_WINDOWS",
13422#endif
13423
13424 NULL
13425};
13426
13427
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013428PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013429INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013430{
Victor Stinner8c62be82010-05-06 00:08:46 +000013431 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013432 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013433 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013434
Brian Curtin52173d42010-12-02 18:29:18 +000013435#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013436 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013437#endif
13438
Victor Stinner8c62be82010-05-06 00:08:46 +000013439 m = PyModule_Create(&posixmodule);
13440 if (m == NULL)
13441 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013442
Victor Stinner8c62be82010-05-06 00:08:46 +000013443 /* Initialize environ dictionary */
13444 v = convertenviron();
13445 Py_XINCREF(v);
13446 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13447 return NULL;
13448 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013449
Victor Stinner8c62be82010-05-06 00:08:46 +000013450 if (all_ins(m))
13451 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013452
Victor Stinner8c62be82010-05-06 00:08:46 +000013453 if (setup_confname_tables(m))
13454 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013455
Victor Stinner8c62be82010-05-06 00:08:46 +000013456 Py_INCREF(PyExc_OSError);
13457 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013458
Guido van Rossumb3d39562000-01-31 18:41:26 +000013459#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013460 if (posix_putenv_garbage == NULL)
13461 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013462#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013463
Victor Stinner8c62be82010-05-06 00:08:46 +000013464 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013465#if defined(HAVE_WAITID) && !defined(__APPLE__)
13466 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013467 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13468 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013469#endif
13470
Christian Heimes25827622013-10-12 01:27:08 +020013471 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013472 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13473 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13474 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013475 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13476 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013477 structseq_new = StatResultType.tp_new;
13478 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013479
Christian Heimes25827622013-10-12 01:27:08 +020013480 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013481 if (PyStructSequence_InitType2(&StatVFSResultType,
13482 &statvfs_result_desc) < 0)
13483 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013484#ifdef NEED_TICKS_PER_SECOND
13485# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013486 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013487# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013488 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013489# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013490 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013491# endif
13492#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013493
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013494#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013495 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013496 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13497 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013498 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013499#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013500
13501 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013502 if (PyStructSequence_InitType2(&TerminalSizeType,
13503 &TerminalSize_desc) < 0)
13504 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013505
13506 /* initialize scandir types */
13507 if (PyType_Ready(&ScandirIteratorType) < 0)
13508 return NULL;
13509 if (PyType_Ready(&DirEntryType) < 0)
13510 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013511 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013512#if defined(HAVE_WAITID) && !defined(__APPLE__)
13513 Py_INCREF((PyObject*) &WaitidResultType);
13514 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13515#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013516 Py_INCREF((PyObject*) &StatResultType);
13517 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13518 Py_INCREF((PyObject*) &StatVFSResultType);
13519 PyModule_AddObject(m, "statvfs_result",
13520 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013521
13522#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013523 Py_INCREF(&SchedParamType);
13524 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013525#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013526
Larry Hastings605a62d2012-06-24 04:33:36 -070013527 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013528 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13529 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013530 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13531
13532 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013533 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13534 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013535 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13536
Thomas Wouters477c8d52006-05-27 19:21:47 +000013537#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013538 /*
13539 * Step 2 of weak-linking support on Mac OS X.
13540 *
13541 * The code below removes functions that are not available on the
13542 * currently active platform.
13543 *
13544 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013545 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013546 * OSX 10.4.
13547 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013548#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013549 if (fstatvfs == NULL) {
13550 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13551 return NULL;
13552 }
13553 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013554#endif /* HAVE_FSTATVFS */
13555
13556#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013557 if (statvfs == NULL) {
13558 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13559 return NULL;
13560 }
13561 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013562#endif /* HAVE_STATVFS */
13563
13564# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013565 if (lchown == NULL) {
13566 if (PyObject_DelAttrString(m, "lchown") == -1) {
13567 return NULL;
13568 }
13569 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013570#endif /* HAVE_LCHOWN */
13571
13572
13573#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013574
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013575 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013576 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13577
Larry Hastings6fe20b32012-04-19 15:07:49 -070013578 billion = PyLong_FromLong(1000000000);
13579 if (!billion)
13580 return NULL;
13581
Larry Hastings9cf065c2012-06-22 16:30:09 -070013582 /* suppress "function not used" warnings */
13583 {
13584 int ignored;
13585 fd_specified("", -1);
13586 follow_symlinks_specified("", 1);
13587 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13588 dir_fd_converter(Py_None, &ignored);
13589 dir_fd_unavailable(Py_None, &ignored);
13590 }
13591
13592 /*
13593 * provide list of locally available functions
13594 * so os.py can populate support_* lists
13595 */
13596 list = PyList_New(0);
13597 if (!list)
13598 return NULL;
13599 for (trace = have_functions; *trace; trace++) {
13600 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13601 if (!unicode)
13602 return NULL;
13603 if (PyList_Append(list, unicode))
13604 return NULL;
13605 Py_DECREF(unicode);
13606 }
13607 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013608
13609 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013610 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013611
13612 initialized = 1;
13613
Victor Stinner8c62be82010-05-06 00:08:46 +000013614 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013615}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013616
13617#ifdef __cplusplus
13618}
13619#endif