blob: 161704fcae4096ec2cb4a1bbcfd0c4b31250029c [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"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020035/* On android API level 21, 'AT_EACCESS' is not declared although
36 * HAVE_FACCESSAT is defined. */
37#ifdef __ANDROID__
38#undef HAVE_FACCESSAT
39#endif
40
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000041#include <stdio.h> /* needed for ctermid() */
42
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#ifdef __cplusplus
44extern "C" {
45#endif
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000048"This module provides access to operating system functionality that is\n\
49standardized by the C Standard and the POSIX standard (a thinly\n\
50disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000053
Ross Lagerwall4d076da2011-03-18 06:56:53 +020054#ifdef HAVE_SYS_UIO_H
55#include <sys/uio.h>
56#endif
57
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000059#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060#endif /* HAVE_SYS_TYPES_H */
61
62#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000065
Guido van Rossum36bc6801995-06-14 22:54:23 +000066#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000067#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000068#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000071#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000073
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#ifdef HAVE_FCNTL_H
75#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000076#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Guido van Rossuma6535fd2001-10-18 19:44:10 +000078#ifdef HAVE_GRP_H
79#include <grp.h>
80#endif
81
Barry Warsaw5676bd12003-01-07 20:57:09 +000082#ifdef HAVE_SYSEXITS_H
83#include <sysexits.h>
84#endif /* HAVE_SYSEXITS_H */
85
Anthony Baxter8a560de2004-10-13 15:30:56 +000086#ifdef HAVE_SYS_LOADAVG_H
87#include <sys/loadavg.h>
88#endif
89
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000090#ifdef HAVE_LANGINFO_H
91#include <langinfo.h>
92#endif
93
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000094#ifdef HAVE_SYS_SENDFILE_H
95#include <sys/sendfile.h>
96#endif
97
Benjamin Peterson94b580d2011-08-02 17:30:04 -050098#ifdef HAVE_SCHED_H
99#include <sched.h>
100#endif
101
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500102#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500103#undef HAVE_SCHED_SETAFFINITY
104#endif
105
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200106#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400107#define USE_XATTRS
108#endif
109
110#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400111#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400112#endif
113
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
115#ifdef HAVE_SYS_SOCKET_H
116#include <sys/socket.h>
117#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#endif
119
Victor Stinner8b905bd2011-10-25 13:34:04 +0200120#ifdef HAVE_DLFCN_H
121#include <dlfcn.h>
122#endif
123
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200124#ifdef __hpux
125#include <sys/mpctl.h>
126#endif
127
128#if defined(__DragonFly__) || \
129 defined(__OpenBSD__) || \
130 defined(__FreeBSD__) || \
131 defined(__NetBSD__) || \
132 defined(__APPLE__)
133#include <sys/sysctl.h>
134#endif
135
Victor Stinner9b1f4742016-09-06 16:18:52 -0700136#ifdef HAVE_LINUX_RANDOM_H
137# include <linux/random.h>
138#endif
139#ifdef HAVE_GETRANDOM_SYSCALL
140# include <sys/syscall.h>
141#endif
142
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100143#if defined(MS_WINDOWS)
144# define TERMSIZE_USE_CONIO
145#elif defined(HAVE_SYS_IOCTL_H)
146# include <sys/ioctl.h>
147# if defined(HAVE_TERMIOS_H)
148# include <termios.h>
149# endif
150# if defined(TIOCGWINSZ)
151# define TERMSIZE_USE_IOCTL
152# endif
153#endif /* MS_WINDOWS */
154
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000156/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#include <process.h>
161#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000163#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000164#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_EXECV 1
167#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000168#define HAVE_SYSTEM 1
169#define HAVE_CWAIT 1
170#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000171#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000172#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173/* Unix functions that the configure script doesn't check for */
174#define HAVE_EXECV 1
175#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000177#define HAVE_FORK1 1
178#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#define HAVE_GETEGID 1
180#define HAVE_GETEUID 1
181#define HAVE_GETGID 1
182#define HAVE_GETPPID 1
183#define HAVE_GETUID 1
184#define HAVE_KILL 1
185#define HAVE_OPENDIR 1
186#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000187#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000189#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000191#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000192
Victor Stinnera2f7c002012-02-08 03:36:25 +0100193
Larry Hastings61272b72014-01-07 12:41:53 -0800194/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000195# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800196module os
Larry Hastings61272b72014-01-07 12:41:53 -0800197[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000198/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100199
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000201
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000202#if defined(__sgi)&&_COMPILER_VERSION>=700
203/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
204 (default) */
205extern char *ctermid_r(char *);
206#endif
207
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000208#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000212#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000214#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000217#endif
218#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 VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
305#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000306#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000307#endif
308#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000309#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000310#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100311#ifndef IO_REPARSE_TAG_MOUNT_POINT
312#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
313#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000315#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000316#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000317#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000318#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000319#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
320#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000321static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000322#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000323#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000324
Tim Petersbc2e10e2002-03-03 23:17:02 +0000325#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000326#if defined(PATH_MAX) && PATH_MAX > 1024
327#define MAXPATHLEN PATH_MAX
328#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#endif /* MAXPATHLEN */
332
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000333#ifdef UNION_WAIT
334/* Emulate some macros on systems that have a union instead of macros */
335
336#ifndef WIFEXITED
337#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
338#endif
339
340#ifndef WEXITSTATUS
341#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
342#endif
343
344#ifndef WTERMSIG
345#define WTERMSIG(u_wait) ((u_wait).w_termsig)
346#endif
347
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000348#define WAIT_TYPE union wait
349#define WAIT_STATUS_INT(s) (s.w_status)
350
351#else /* !UNION_WAIT */
352#define WAIT_TYPE int
353#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000354#endif /* UNION_WAIT */
355
Greg Wardb48bc172000-03-01 21:51:56 +0000356/* Don't use the "_r" form if we don't need it (also, won't have a
357 prototype for it, at least on Solaris -- maybe others as well?). */
358#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
359#define USE_CTERMID_R
360#endif
361
Fred Drake699f3522000-06-29 21:12:41 +0000362/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000363#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000364#undef FSTAT
365#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200366#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700368# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200369# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800370# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000371#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000372# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700373# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define FSTAT fstat
375# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000376#endif
377
Tim Peters11b23062003-04-23 02:39:17 +0000378#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000379#include <sys/mkdev.h>
380#else
381#if defined(MAJOR_IN_SYSMACROS)
382#include <sys/sysmacros.h>
383#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000384#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
385#include <sys/mkdev.h>
386#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000387#endif
Fred Drake699f3522000-06-29 21:12:41 +0000388
Victor Stinner6edddfa2013-11-24 19:22:57 +0100389#define DWORD_MAX 4294967295U
390
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200391#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100392#define INITFUNC PyInit_nt
393#define MODNAME "nt"
394#else
395#define INITFUNC PyInit_posix
396#define MODNAME "posix"
397#endif
398
399#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200400/* defined in fileutils.c */
401PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
402PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
403 ULONG, struct _Py_stat_struct *);
404#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700405
406#ifdef MS_WINDOWS
407static int
408win32_warn_bytes_api()
409{
410 return PyErr_WarnEx(PyExc_DeprecationWarning,
411 "The Windows bytes API has been deprecated, "
412 "use Unicode filenames instead",
413 1);
414}
415#endif
416
417
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200418#ifndef MS_WINDOWS
419PyObject *
420_PyLong_FromUid(uid_t uid)
421{
422 if (uid == (uid_t)-1)
423 return PyLong_FromLong(-1);
424 return PyLong_FromUnsignedLong(uid);
425}
426
427PyObject *
428_PyLong_FromGid(gid_t gid)
429{
430 if (gid == (gid_t)-1)
431 return PyLong_FromLong(-1);
432 return PyLong_FromUnsignedLong(gid);
433}
434
435int
436_Py_Uid_Converter(PyObject *obj, void *p)
437{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700438 uid_t uid;
439 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200440 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200441 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700442 unsigned long uresult;
443
444 index = PyNumber_Index(obj);
445 if (index == NULL) {
446 PyErr_Format(PyExc_TypeError,
447 "uid should be integer, not %.200s",
448 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200449 return 0;
450 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700451
452 /*
453 * Handling uid_t is complicated for two reasons:
454 * * Although uid_t is (always?) unsigned, it still
455 * accepts -1.
456 * * We don't know its size in advance--it may be
457 * bigger than an int, or it may be smaller than
458 * a long.
459 *
460 * So a bit of defensive programming is in order.
461 * Start with interpreting the value passed
462 * in as a signed long and see if it works.
463 */
464
465 result = PyLong_AsLongAndOverflow(index, &overflow);
466
467 if (!overflow) {
468 uid = (uid_t)result;
469
470 if (result == -1) {
471 if (PyErr_Occurred())
472 goto fail;
473 /* It's a legitimate -1, we're done. */
474 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200475 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700476
477 /* Any other negative number is disallowed. */
478 if (result < 0)
479 goto underflow;
480
481 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200482 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700483 (long)uid != result)
484 goto underflow;
485 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200486 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700487
488 if (overflow < 0)
489 goto underflow;
490
491 /*
492 * Okay, the value overflowed a signed long. If it
493 * fits in an *unsigned* long, it may still be okay,
494 * as uid_t may be unsigned long on this platform.
495 */
496 uresult = PyLong_AsUnsignedLong(index);
497 if (PyErr_Occurred()) {
498 if (PyErr_ExceptionMatches(PyExc_OverflowError))
499 goto overflow;
500 goto fail;
501 }
502
503 uid = (uid_t)uresult;
504
505 /*
506 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
507 * but this value would get interpreted as (uid_t)-1 by chown
508 * and its siblings. That's not what the user meant! So we
509 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100510 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511 */
512 if (uid == (uid_t)-1)
513 goto overflow;
514
515 /* Ensure the value wasn't truncated. */
516 if (sizeof(uid_t) < sizeof(long) &&
517 (unsigned long)uid != uresult)
518 goto overflow;
519 /* fallthrough */
520
521success:
522 Py_DECREF(index);
523 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200524 return 1;
525
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200527 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528 "uid is less than minimum");
529 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200530
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700531overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533 "uid is greater than maximum");
534 /* fallthrough */
535
536fail:
537 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200538 return 0;
539}
540
541int
542_Py_Gid_Converter(PyObject *obj, void *p)
543{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700544 gid_t gid;
545 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200546 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200547 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700548 unsigned long uresult;
549
550 index = PyNumber_Index(obj);
551 if (index == NULL) {
552 PyErr_Format(PyExc_TypeError,
553 "gid should be integer, not %.200s",
554 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200555 return 0;
556 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700557
558 /*
559 * Handling gid_t is complicated for two reasons:
560 * * Although gid_t is (always?) unsigned, it still
561 * accepts -1.
562 * * We don't know its size in advance--it may be
563 * bigger than an int, or it may be smaller than
564 * a long.
565 *
566 * So a bit of defensive programming is in order.
567 * Start with interpreting the value passed
568 * in as a signed long and see if it works.
569 */
570
571 result = PyLong_AsLongAndOverflow(index, &overflow);
572
573 if (!overflow) {
574 gid = (gid_t)result;
575
576 if (result == -1) {
577 if (PyErr_Occurred())
578 goto fail;
579 /* It's a legitimate -1, we're done. */
580 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200581 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700582
583 /* Any other negative number is disallowed. */
584 if (result < 0) {
585 goto underflow;
586 }
587
588 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200589 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700590 (long)gid != result)
591 goto underflow;
592 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200593 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700594
595 if (overflow < 0)
596 goto underflow;
597
598 /*
599 * Okay, the value overflowed a signed long. If it
600 * fits in an *unsigned* long, it may still be okay,
601 * as gid_t may be unsigned long on this platform.
602 */
603 uresult = PyLong_AsUnsignedLong(index);
604 if (PyErr_Occurred()) {
605 if (PyErr_ExceptionMatches(PyExc_OverflowError))
606 goto overflow;
607 goto fail;
608 }
609
610 gid = (gid_t)uresult;
611
612 /*
613 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
614 * but this value would get interpreted as (gid_t)-1 by chown
615 * and its siblings. That's not what the user meant! So we
616 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100617 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618 */
619 if (gid == (gid_t)-1)
620 goto overflow;
621
622 /* Ensure the value wasn't truncated. */
623 if (sizeof(gid_t) < sizeof(long) &&
624 (unsigned long)gid != uresult)
625 goto overflow;
626 /* fallthrough */
627
628success:
629 Py_DECREF(index);
630 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200631 return 1;
632
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700633underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200634 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635 "gid is less than minimum");
636 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200637
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700638overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640 "gid is greater than maximum");
641 /* fallthrough */
642
643fail:
644 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200645 return 0;
646}
647#endif /* MS_WINDOWS */
648
649
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700650#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800651
652
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200653#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
654static int
655_Py_Dev_Converter(PyObject *obj, void *p)
656{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200657 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200658 if (PyErr_Occurred())
659 return 0;
660 return 1;
661}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800662#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200663
664
Larry Hastings9cf065c2012-06-22 16:30:09 -0700665#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400666/*
667 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
668 * without the int cast, the value gets interpreted as uint (4291925331),
669 * which doesn't play nicely with all the initializer lines in this file that
670 * look like this:
671 * int dir_fd = DEFAULT_DIR_FD;
672 */
673#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700674#else
675#define DEFAULT_DIR_FD (-100)
676#endif
677
678static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300679_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200680{
681 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700682 long long_value;
683
684 PyObject *index = PyNumber_Index(o);
685 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700686 return 0;
687 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700688
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300689 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690 long_value = PyLong_AsLongAndOverflow(index, &overflow);
691 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300692 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200693 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700694 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700695 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700696 return 0;
697 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200698 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700699 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700700 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701 return 0;
702 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700703
Larry Hastings9cf065c2012-06-22 16:30:09 -0700704 *p = (int)long_value;
705 return 1;
706}
707
708static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200709dir_fd_converter(PyObject *o, void *p)
710{
711 if (o == Py_None) {
712 *(int *)p = DEFAULT_DIR_FD;
713 return 1;
714 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300715 else if (PyIndex_Check(o)) {
716 return _fd_converter(o, (int *)p);
717 }
718 else {
719 PyErr_Format(PyExc_TypeError,
720 "argument should be integer or None, not %.200s",
721 Py_TYPE(o)->tp_name);
722 return 0;
723 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700724}
725
726
Larry Hastings9cf065c2012-06-22 16:30:09 -0700727/*
728 * A PyArg_ParseTuple "converter" function
729 * that handles filesystem paths in the manner
730 * preferred by the os module.
731 *
732 * path_converter accepts (Unicode) strings and their
733 * subclasses, and bytes and their subclasses. What
734 * it does with the argument depends on the platform:
735 *
736 * * On Windows, if we get a (Unicode) string we
737 * extract the wchar_t * and return it; if we get
738 * bytes we extract the char * and return that.
739 *
740 * * On all other platforms, strings are encoded
741 * to bytes using PyUnicode_FSConverter, then we
742 * extract the char * from the bytes object and
743 * return that.
744 *
745 * path_converter also optionally accepts signed
746 * integers (representing open file descriptors) instead
747 * of path strings.
748 *
749 * Input fields:
750 * path.nullable
751 * If nonzero, the path is permitted to be None.
752 * path.allow_fd
753 * If nonzero, the path is permitted to be a file handle
754 * (a signed int) instead of a string.
755 * path.function_name
756 * If non-NULL, path_converter will use that as the name
757 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700758 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700759 * path.argument_name
760 * If non-NULL, path_converter will use that as the name
761 * of the parameter in error messages.
762 * (If path.argument_name is NULL it uses "path".)
763 *
764 * Output fields:
765 * path.wide
766 * Points to the path if it was expressed as Unicode
767 * and was not encoded. (Only used on Windows.)
768 * path.narrow
769 * Points to the path if it was expressed as bytes,
770 * or it was Unicode and was encoded to bytes.
771 * path.fd
772 * Contains a file descriptor if path.accept_fd was true
773 * and the caller provided a signed integer instead of any
774 * sort of string.
775 *
776 * WARNING: if your "path" parameter is optional, and is
777 * unspecified, path_converter will never get called.
778 * So if you set allow_fd, you *MUST* initialize path.fd = -1
779 * yourself!
780 * path.length
781 * The length of the path in characters, if specified as
782 * a string.
783 * path.object
784 * The original object passed in.
785 * path.cleanup
786 * For internal use only. May point to a temporary object.
787 * (Pay no attention to the man behind the curtain.)
788 *
789 * At most one of path.wide or path.narrow will be non-NULL.
790 * If path was None and path.nullable was set,
791 * or if path was an integer and path.allow_fd was set,
792 * both path.wide and path.narrow will be NULL
793 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200794 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700795 * path_converter takes care to not write to the path_t
796 * unless it's successful. However it must reset the
797 * "cleanup" field each time it's called.
798 *
799 * Use as follows:
800 * path_t path;
801 * memset(&path, 0, sizeof(path));
802 * PyArg_ParseTuple(args, "O&", path_converter, &path);
803 * // ... use values from path ...
804 * path_cleanup(&path);
805 *
806 * (Note that if PyArg_Parse fails you don't need to call
807 * path_cleanup(). However it is safe to do so.)
808 */
809typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100810 const char *function_name;
811 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700812 int nullable;
813 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300814 const wchar_t *wide;
815 const char *narrow;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816 int fd;
817 Py_ssize_t length;
818 PyObject *object;
819 PyObject *cleanup;
820} path_t;
821
Larry Hastings2f936352014-08-05 14:04:04 +1000822#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
823 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700824
Larry Hastings9cf065c2012-06-22 16:30:09 -0700825static void
826path_cleanup(path_t *path) {
827 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200828 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700829 }
830}
831
832static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300833path_converter(PyObject *o, void *p)
834{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700835 path_t *path = (path_t *)p;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700836 PyObject *bytes, *to_cleanup = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700837 Py_ssize_t length;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700838 int is_index, is_buffer, is_bytes, is_unicode;
839 /* Default to failure, forcing explicit signaling of succcess. */
840 int ret = 0;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300841 const char *narrow;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700842
843#define FORMAT_EXCEPTION(exc, fmt) \
844 PyErr_Format(exc, "%s%s" fmt, \
845 path->function_name ? path->function_name : "", \
846 path->function_name ? ": " : "", \
847 path->argument_name ? path->argument_name : "path")
848
849 /* Py_CLEANUP_SUPPORTED support */
850 if (o == NULL) {
851 path_cleanup(path);
852 return 1;
853 }
854
Brett Cannon3f9183b2016-08-26 14:44:48 -0700855 /* Ensure it's always safe to call path_cleanup(). */
Larry Hastings9cf065c2012-06-22 16:30:09 -0700856 path->cleanup = NULL;
857
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300858 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859 path->wide = NULL;
860 path->narrow = NULL;
861 path->length = 0;
862 path->object = o;
863 path->fd = -1;
864 return 1;
865 }
866
Brett Cannon3f9183b2016-08-26 14:44:48 -0700867 /* Only call this here so that we don't treat the return value of
868 os.fspath() as an fd or buffer. */
869 is_index = path->allow_fd && PyIndex_Check(o);
870 is_buffer = PyObject_CheckBuffer(o);
871 is_bytes = PyBytes_Check(o);
872 is_unicode = PyUnicode_Check(o);
873
874 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
875 /* Inline PyOS_FSPath() for better error messages. */
876 _Py_IDENTIFIER(__fspath__);
877 PyObject *func = NULL;
878
879 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
880 if (NULL == func) {
881 goto error_exit;
882 }
883
884 o = to_cleanup = PyObject_CallFunctionObjArgs(func, NULL);
885 Py_DECREF(func);
886 if (NULL == o) {
887 goto error_exit;
888 }
889 else if (PyUnicode_Check(o)) {
890 is_unicode = 1;
891 }
892 else if (PyBytes_Check(o)) {
893 is_bytes = 1;
894 }
895 else {
896 goto error_exit;
897 }
898 }
899
900 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700901#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300902 const wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100903
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300904 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100905 if (!wide) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700906 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700907 }
Victor Stinner59799a82013-11-13 14:17:30 +0100908 if (length > 32767) {
909 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700910 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700911 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300912 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300913 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700914 goto exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300915 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700916
917 path->wide = wide;
918 path->narrow = NULL;
919 path->length = length;
920 path->object = o;
921 path->fd = -1;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700922 ret = 1;
923 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700924#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300925 if (!PyUnicode_FSConverter(o, &bytes)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700926 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300927 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700928#endif
929 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700930 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300931#ifdef MS_WINDOWS
932 if (win32_warn_bytes_api()) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700933 goto exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300934 }
935#endif
936 bytes = o;
937 Py_INCREF(bytes);
938 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700939 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300940 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
941 "%s%s%s should be %s, not %.200s",
942 path->function_name ? path->function_name : "",
943 path->function_name ? ": " : "",
944 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700945 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
946 "integer or None" :
947 path->allow_fd ? "string, bytes, os.PathLike or integer" :
948 path->nullable ? "string, bytes, os.PathLike or None" :
949 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300950 Py_TYPE(o)->tp_name)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700951 goto exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300952 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300953#ifdef MS_WINDOWS
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300954 if (win32_warn_bytes_api()) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700955 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300956 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300957#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300958 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700959 if (!bytes) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700960 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700961 }
962 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300963 else if (path->allow_fd && PyIndex_Check(o)) {
964 if (!_fd_converter(o, &path->fd)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700965 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300966 }
967 path->wide = NULL;
968 path->narrow = NULL;
969 path->length = 0;
970 path->object = o;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700971 ret = 1;
972 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300973 }
974 else {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700975 error_exit:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300976 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
977 path->function_name ? path->function_name : "",
978 path->function_name ? ": " : "",
979 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700980 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
981 "integer or None" :
982 path->allow_fd ? "string, bytes, os.PathLike or integer" :
983 path->nullable ? "string, bytes, os.PathLike or None" :
984 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300985 Py_TYPE(o)->tp_name);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700986 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700987 }
988
Larry Hastings9cf065c2012-06-22 16:30:09 -0700989 length = PyBytes_GET_SIZE(bytes);
990#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100991 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700992 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
993 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700994 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 }
996#endif
997
998 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200999 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001000 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001002 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003 }
1004
1005 path->wide = NULL;
1006 path->narrow = narrow;
1007 path->length = length;
1008 path->object = o;
1009 path->fd = -1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001010 if (bytes == o) {
1011 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001012 ret = 1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001013 }
1014 else {
1015 path->cleanup = bytes;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001016 ret = Py_CLEANUP_SUPPORTED;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001017 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001018 exit:
1019 Py_XDECREF(to_cleanup);
1020 return ret;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021}
1022
1023static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001024argument_unavailable_error(const char *function_name, const char *argument_name)
1025{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001026 PyErr_Format(PyExc_NotImplementedError,
1027 "%s%s%s unavailable on this platform",
1028 (function_name != NULL) ? function_name : "",
1029 (function_name != NULL) ? ": ": "",
1030 argument_name);
1031}
1032
1033static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001034dir_fd_unavailable(PyObject *o, void *p)
1035{
1036 int dir_fd;
1037 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001039 if (dir_fd != DEFAULT_DIR_FD) {
1040 argument_unavailable_error(NULL, "dir_fd");
1041 return 0;
1042 }
1043 *(int *)p = dir_fd;
1044 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001045}
1046
1047static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001048fd_specified(const char *function_name, int fd)
1049{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 if (fd == -1)
1051 return 0;
1052
1053 argument_unavailable_error(function_name, "fd");
1054 return 1;
1055}
1056
1057static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001058follow_symlinks_specified(const char *function_name, int follow_symlinks)
1059{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001060 if (follow_symlinks)
1061 return 0;
1062
1063 argument_unavailable_error(function_name, "follow_symlinks");
1064 return 1;
1065}
1066
1067static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001068path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1069{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001070 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
1071 PyErr_Format(PyExc_ValueError,
1072 "%s: can't specify dir_fd without matching path",
1073 function_name);
1074 return 1;
1075 }
1076 return 0;
1077}
1078
1079static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001080dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1081{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001082 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1083 PyErr_Format(PyExc_ValueError,
1084 "%s: can't specify both dir_fd and fd",
1085 function_name);
1086 return 1;
1087 }
1088 return 0;
1089}
1090
1091static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001092fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1093 int follow_symlinks)
1094{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001095 if ((fd > 0) && (!follow_symlinks)) {
1096 PyErr_Format(PyExc_ValueError,
1097 "%s: cannot use fd and follow_symlinks together",
1098 function_name);
1099 return 1;
1100 }
1101 return 0;
1102}
1103
1104static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001105dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1106 int follow_symlinks)
1107{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001108 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1109 PyErr_Format(PyExc_ValueError,
1110 "%s: cannot use dir_fd and follow_symlinks together",
1111 function_name);
1112 return 1;
1113 }
1114 return 0;
1115}
1116
Larry Hastings2f936352014-08-05 14:04:04 +10001117#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001118 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001119#else
Larry Hastings2f936352014-08-05 14:04:04 +10001120 typedef off_t Py_off_t;
1121#endif
1122
1123static int
1124Py_off_t_converter(PyObject *arg, void *addr)
1125{
1126#ifdef HAVE_LARGEFILE_SUPPORT
1127 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1128#else
1129 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001130#endif
1131 if (PyErr_Occurred())
1132 return 0;
1133 return 1;
1134}
Larry Hastings2f936352014-08-05 14:04:04 +10001135
1136static PyObject *
1137PyLong_FromPy_off_t(Py_off_t offset)
1138{
1139#ifdef HAVE_LARGEFILE_SUPPORT
1140 return PyLong_FromLongLong(offset);
1141#else
1142 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001143#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001144}
1145
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001146
Steve Dowerd81431f2015-03-06 14:47:02 -08001147#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1148/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1149 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001150 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001151#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001152#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001153#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001154#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001155#define _NO_CONSOLE_FILENO (intptr_t)-2
1156
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001157/* the special case of checking dup2. The target fd must be in a sensible range */
1158static int
1159_PyVerify_fd_dup2(int fd1, int fd2)
1160{
Victor Stinner8c62be82010-05-06 00:08:46 +00001161 if (!_PyVerify_fd(fd1))
1162 return 0;
1163 if (fd2 == _NO_CONSOLE_FILENO)
1164 return 0;
1165 if ((unsigned)fd2 < _NHANDLE_)
1166 return 1;
1167 else
1168 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001169}
1170#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001171#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001172#endif
1173
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001174#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001175
1176static int
Brian Curtind25aef52011-06-13 15:16:04 -05001177win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001178{
Martin Panter70214ad2016-08-04 02:38:59 +00001179 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1180 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001181 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001182
1183 if (0 == DeviceIoControl(
1184 reparse_point_handle,
1185 FSCTL_GET_REPARSE_POINT,
1186 NULL, 0, /* in buffer */
1187 target_buffer, sizeof(target_buffer),
1188 &n_bytes_returned,
1189 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001190 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001191
1192 if (reparse_tag)
1193 *reparse_tag = rdb->ReparseTag;
1194
Brian Curtind25aef52011-06-13 15:16:04 -05001195 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001196}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001197
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001198#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001199
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001201#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001202/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001203** environ directly, we must obtain it with _NSGetEnviron(). See also
1204** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001205*/
1206#include <crt_externs.h>
1207static char **environ;
1208#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001209extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211
Barry Warsaw53699e91996-12-10 23:23:01 +00001212static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001213convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214{
Victor Stinner8c62be82010-05-06 00:08:46 +00001215 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001216#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001217 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001218#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001219 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001220#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221
Victor Stinner8c62be82010-05-06 00:08:46 +00001222 d = PyDict_New();
1223 if (d == NULL)
1224 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001225#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 if (environ == NULL)
1227 environ = *_NSGetEnviron();
1228#endif
1229#ifdef MS_WINDOWS
1230 /* _wenviron must be initialized in this way if the program is started
1231 through main() instead of wmain(). */
1232 _wgetenv(L"");
1233 if (_wenviron == NULL)
1234 return d;
1235 /* This part ignores errors */
1236 for (e = _wenviron; *e != NULL; e++) {
1237 PyObject *k;
1238 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001239 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001240 if (p == NULL)
1241 continue;
1242 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1243 if (k == NULL) {
1244 PyErr_Clear();
1245 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001246 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001247 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1248 if (v == NULL) {
1249 PyErr_Clear();
1250 Py_DECREF(k);
1251 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001252 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 if (PyDict_GetItem(d, k) == NULL) {
1254 if (PyDict_SetItem(d, k, v) != 0)
1255 PyErr_Clear();
1256 }
1257 Py_DECREF(k);
1258 Py_DECREF(v);
1259 }
1260#else
1261 if (environ == NULL)
1262 return d;
1263 /* This part ignores errors */
1264 for (e = environ; *e != NULL; e++) {
1265 PyObject *k;
1266 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001267 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001268 if (p == NULL)
1269 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001270 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001271 if (k == NULL) {
1272 PyErr_Clear();
1273 continue;
1274 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001275 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 if (v == NULL) {
1277 PyErr_Clear();
1278 Py_DECREF(k);
1279 continue;
1280 }
1281 if (PyDict_GetItem(d, k) == NULL) {
1282 if (PyDict_SetItem(d, k, v) != 0)
1283 PyErr_Clear();
1284 }
1285 Py_DECREF(k);
1286 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001287 }
1288#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001289 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290}
1291
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292/* Set a POSIX-specific error from errno, and return NULL */
1293
Barry Warsawd58d7641998-07-23 16:14:40 +00001294static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001295posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001296{
Victor Stinner8c62be82010-05-06 00:08:46 +00001297 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298}
Mark Hammondef8b6542001-05-13 08:04:26 +00001299
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001300#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001301static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001302win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001303{
Victor Stinner8c62be82010-05-06 00:08:46 +00001304 /* XXX We should pass the function name along in the future.
1305 (winreg.c also wants to pass the function name.)
1306 This would however require an additional param to the
1307 Windows error object, which is non-trivial.
1308 */
1309 errno = GetLastError();
1310 if (filename)
1311 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1312 else
1313 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001314}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001315
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001316static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001317win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001318{
1319 /* XXX - see win32_error for comments on 'function' */
1320 errno = GetLastError();
1321 if (filename)
1322 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001323 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001324 errno,
1325 filename);
1326 else
1327 return PyErr_SetFromWindowsErr(errno);
1328}
1329
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001330#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331
Larry Hastings9cf065c2012-06-22 16:30:09 -07001332static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001333path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001334{
1335#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001336 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1337 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001338#else
Victor Stinner292c8352012-10-30 02:17:38 +01001339 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001340#endif
1341}
1342
Larry Hastings31826802013-10-19 00:09:25 -07001343
Larry Hastingsb0827312014-02-09 22:05:19 -08001344static PyObject *
1345path_error2(path_t *path, path_t *path2)
1346{
1347#ifdef MS_WINDOWS
1348 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1349 0, path->object, path2->object);
1350#else
1351 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1352 path->object, path2->object);
1353#endif
1354}
1355
1356
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357/* POSIX generic methods */
1358
Larry Hastings2f936352014-08-05 14:04:04 +10001359static int
1360fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001361{
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001363 int *pointer = (int *)p;
1364 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001365 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001366 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001367 *pointer = fd;
1368 return 1;
1369}
1370
1371static PyObject *
1372posix_fildes_fd(int fd, int (*func)(int))
1373{
1374 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001375 int async_err = 0;
1376
Steve Dower8fc89802015-04-12 00:26:27 -04001377 if (!_PyVerify_fd(fd))
1378 return posix_error();
1379
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001380 do {
1381 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001382 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001383 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001384 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001385 Py_END_ALLOW_THREADS
1386 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1387 if (res != 0)
1388 return (!async_err) ? posix_error() : NULL;
1389 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001390}
Guido van Rossum21142a01999-01-08 21:05:37 +00001391
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001393#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001394/* This is a reimplementation of the C library's chdir function,
1395 but one that produces Win32 errors instead of DOS error codes.
1396 chdir is essentially a wrapper around SetCurrentDirectory; however,
1397 it also needs to set "magic" environment variables indicating
1398 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001399static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400win32_chdir(LPCSTR path)
1401{
Victor Stinner75875072013-11-24 19:23:25 +01001402 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001403 int result;
1404 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 if(!SetCurrentDirectoryA(path))
1407 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001408 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001409 if (!result)
1410 return FALSE;
1411 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001412 than MAX_PATH-1 (not including the final null character). */
1413 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001414 if (strncmp(new_path, "\\\\", 2) == 0 ||
1415 strncmp(new_path, "//", 2) == 0)
1416 /* UNC path, nothing to do. */
1417 return TRUE;
1418 env[1] = new_path[0];
1419 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001420}
1421
1422/* The Unicode version differs from the ANSI version
1423 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001424static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001425win32_wchdir(LPCWSTR path)
1426{
Victor Stinnered537822015-12-13 21:40:26 +01001427 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001428 int result;
1429 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 if(!SetCurrentDirectoryW(path))
1432 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001433 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001434 if (!result)
1435 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001436 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001437 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 if (!new_path) {
1439 SetLastError(ERROR_OUTOFMEMORY);
1440 return FALSE;
1441 }
1442 result = GetCurrentDirectoryW(result, new_path);
1443 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001444 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 return FALSE;
1446 }
1447 }
1448 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1449 wcsncmp(new_path, L"//", 2) == 0)
1450 /* UNC path, nothing to do. */
1451 return TRUE;
1452 env[1] = new_path[0];
1453 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001454 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001455 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001456 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001457}
1458#endif
1459
Martin v. Löwis14694662006-02-03 12:54:16 +00001460#ifdef MS_WINDOWS
1461/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1462 - time stamps are restricted to second resolution
1463 - file modification times suffer from forth-and-back conversions between
1464 UTC and local time
1465 Therefore, we implement our own stat, based on the Win32 API directly.
1466*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001467#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001468#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001469
Guido van Rossumd8faa362007-04-27 19:54:29 +00001470static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001471attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001472{
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 HANDLE hFindFile;
1474 WIN32_FIND_DATAA FileData;
1475 hFindFile = FindFirstFileA(pszFile, &FileData);
1476 if (hFindFile == INVALID_HANDLE_VALUE)
1477 return FALSE;
1478 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001479 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001480 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001481 info->dwFileAttributes = FileData.dwFileAttributes;
1482 info->ftCreationTime = FileData.ftCreationTime;
1483 info->ftLastAccessTime = FileData.ftLastAccessTime;
1484 info->ftLastWriteTime = FileData.ftLastWriteTime;
1485 info->nFileSizeHigh = FileData.nFileSizeHigh;
1486 info->nFileSizeLow = FileData.nFileSizeLow;
1487/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001488 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1489 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001490 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001491}
1492
Victor Stinner6036e442015-03-08 01:58:04 +01001493static void
1494find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1495 BY_HANDLE_FILE_INFORMATION *info,
1496 ULONG *reparse_tag)
1497{
1498 memset(info, 0, sizeof(*info));
1499 info->dwFileAttributes = pFileData->dwFileAttributes;
1500 info->ftCreationTime = pFileData->ftCreationTime;
1501 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1502 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1503 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1504 info->nFileSizeLow = pFileData->nFileSizeLow;
1505/* info->nNumberOfLinks = 1; */
1506 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1507 *reparse_tag = pFileData->dwReserved0;
1508 else
1509 *reparse_tag = 0;
1510}
1511
Guido van Rossumd8faa362007-04-27 19:54:29 +00001512static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001513attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001514{
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 HANDLE hFindFile;
1516 WIN32_FIND_DATAW FileData;
1517 hFindFile = FindFirstFileW(pszFile, &FileData);
1518 if (hFindFile == INVALID_HANDLE_VALUE)
1519 return FALSE;
1520 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001521 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001522 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001523}
1524
Brian Curtind25aef52011-06-13 15:16:04 -05001525static BOOL
1526get_target_path(HANDLE hdl, wchar_t **target_path)
1527{
1528 int buf_size, result_length;
1529 wchar_t *buf;
1530
1531 /* We have a good handle to the target, use it to determine
1532 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001533 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1534 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001535 if(!buf_size)
1536 return FALSE;
1537
Victor Stinnerc36674a2016-03-16 14:30:16 +01001538 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001539 if (!buf) {
1540 SetLastError(ERROR_OUTOFMEMORY);
1541 return FALSE;
1542 }
1543
Steve Dower2ea51c92015-03-20 21:49:12 -07001544 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001545 buf, buf_size, VOLUME_NAME_DOS);
1546
1547 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001548 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001549 return FALSE;
1550 }
1551
1552 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001553 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001554 return FALSE;
1555 }
1556
1557 buf[result_length] = 0;
1558
1559 *target_path = buf;
1560 return TRUE;
1561}
1562
1563static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001564win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001565 BOOL traverse);
1566static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001567win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001568 BOOL traverse)
1569{
Victor Stinner26de69d2011-06-17 15:15:38 +02001570 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001571 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001572 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001573 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001574 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575 const char *dot;
1576
1577 hFile = CreateFileA(
1578 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001579 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001580 0, /* share mode */
1581 NULL, /* security attributes */
1582 OPEN_EXISTING,
1583 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001584 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1585 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001586 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001587 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1588 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001589 NULL);
1590
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001591 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001592 /* Either the target doesn't exist, or we don't have access to
1593 get a handle to it. If the former, we need to return an error.
1594 If the latter, we can use attributes_from_dir. */
1595 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001596 return -1;
1597 /* Could not get attributes on open file. Fall back to
1598 reading the directory. */
1599 if (!attributes_from_dir(path, &info, &reparse_tag))
1600 /* Very strange. This should not fail now */
1601 return -1;
1602 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1603 if (traverse) {
1604 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001605 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001606 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001608 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001609 } else {
1610 if (!GetFileInformationByHandle(hFile, &info)) {
1611 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001612 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 }
1614 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001615 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1616 return -1;
1617
1618 /* Close the outer open file handle now that we're about to
1619 reopen it with different flags. */
1620 if (!CloseHandle(hFile))
1621 return -1;
1622
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001624 /* In order to call GetFinalPathNameByHandle we need to open
1625 the file without the reparse handling flag set. */
1626 hFile2 = CreateFileA(
1627 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1628 NULL, OPEN_EXISTING,
1629 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1630 NULL);
1631 if (hFile2 == INVALID_HANDLE_VALUE)
1632 return -1;
1633
1634 if (!get_target_path(hFile2, &target_path))
1635 return -1;
1636
1637 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001638 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001639 return code;
1640 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001641 } else
1642 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001643 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001644 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001645
1646 /* Set S_IEXEC if it is an .exe, .bat, ... */
1647 dot = strrchr(path, '.');
1648 if (dot) {
1649 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1650 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1651 result->st_mode |= 0111;
1652 }
1653 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001654}
1655
1656static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001657win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001658 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659{
1660 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001661 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001663 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001664 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001665 const wchar_t *dot;
1666
1667 hFile = CreateFileW(
1668 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001669 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001670 0, /* share mode */
1671 NULL, /* security attributes */
1672 OPEN_EXISTING,
1673 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001674 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1675 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001676 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001677 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001678 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 NULL);
1680
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001681 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 /* Either the target doesn't exist, or we don't have access to
1683 get a handle to it. If the former, we need to return an error.
1684 If the latter, we can use attributes_from_dir. */
1685 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686 return -1;
1687 /* Could not get attributes on open file. Fall back to
1688 reading the directory. */
1689 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1690 /* Very strange. This should not fail now */
1691 return -1;
1692 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1693 if (traverse) {
1694 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001695 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001696 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001698 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001699 } else {
1700 if (!GetFileInformationByHandle(hFile, &info)) {
1701 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001702 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001703 }
1704 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001705 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1706 return -1;
1707
1708 /* Close the outer open file handle now that we're about to
1709 reopen it with different flags. */
1710 if (!CloseHandle(hFile))
1711 return -1;
1712
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001713 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001714 /* In order to call GetFinalPathNameByHandle we need to open
1715 the file without the reparse handling flag set. */
1716 hFile2 = CreateFileW(
1717 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1718 NULL, OPEN_EXISTING,
1719 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1720 NULL);
1721 if (hFile2 == INVALID_HANDLE_VALUE)
1722 return -1;
1723
1724 if (!get_target_path(hFile2, &target_path))
1725 return -1;
1726
1727 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001728 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001729 return code;
1730 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001731 } else
1732 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001733 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001734 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001735
1736 /* Set S_IEXEC if it is an .exe, .bat, ... */
1737 dot = wcsrchr(path, '.');
1738 if (dot) {
1739 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1740 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1741 result->st_mode |= 0111;
1742 }
1743 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001744}
1745
1746static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001747win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001749 /* Protocol violation: we explicitly clear errno, instead of
1750 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001751 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001752 errno = 0;
1753 return code;
1754}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001755
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001756static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001757win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001758{
1759 /* Protocol violation: we explicitly clear errno, instead of
1760 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001761 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001762 errno = 0;
1763 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001764}
Brian Curtind25aef52011-06-13 15:16:04 -05001765/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001766
1767 In Posix, stat automatically traverses symlinks and returns the stat
1768 structure for the target. In Windows, the equivalent GetFileAttributes by
1769 default does not traverse symlinks and instead returns attributes for
1770 the symlink.
1771
1772 Therefore, win32_lstat will get the attributes traditionally, and
1773 win32_stat will first explicitly resolve the symlink target and then will
1774 call win32_lstat on that result.
1775
Ezio Melotti4969f702011-03-15 05:59:46 +02001776 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001777
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001778static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001779win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001780{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001781 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001782}
1783
Victor Stinner8c62be82010-05-06 00:08:46 +00001784static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001785win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001786{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001787 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001788}
1789
1790static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001791win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001792{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001793 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001794}
1795
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001796static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001797win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001798{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001799 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001800}
1801
Martin v. Löwis14694662006-02-03 12:54:16 +00001802#endif /* MS_WINDOWS */
1803
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001804PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001805"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001807 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001808or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1809\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001810Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1811or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001813See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001814
1815static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001816 {"st_mode", "protection bits"},
1817 {"st_ino", "inode"},
1818 {"st_dev", "device"},
1819 {"st_nlink", "number of hard links"},
1820 {"st_uid", "user ID of owner"},
1821 {"st_gid", "group ID of owner"},
1822 {"st_size", "total size, in bytes"},
1823 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1824 {NULL, "integer time of last access"},
1825 {NULL, "integer time of last modification"},
1826 {NULL, "integer time of last change"},
1827 {"st_atime", "time of last access"},
1828 {"st_mtime", "time of last modification"},
1829 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001830 {"st_atime_ns", "time of last access in nanoseconds"},
1831 {"st_mtime_ns", "time of last modification in nanoseconds"},
1832 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001833#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001835#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001836#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001838#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001839#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001842#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001844#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001845#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001847#endif
1848#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001849 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001850#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001851#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1852 {"st_file_attributes", "Windows file attribute bits"},
1853#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001854 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001855};
1856
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001857#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001858#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001859#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001860#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861#endif
1862
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001863#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1865#else
1866#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1867#endif
1868
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001869#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001870#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1871#else
1872#define ST_RDEV_IDX ST_BLOCKS_IDX
1873#endif
1874
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001875#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1876#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1877#else
1878#define ST_FLAGS_IDX ST_RDEV_IDX
1879#endif
1880
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001881#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001882#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001883#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001884#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001885#endif
1886
1887#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1888#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1889#else
1890#define ST_BIRTHTIME_IDX ST_GEN_IDX
1891#endif
1892
Zachary Ware63f277b2014-06-19 09:46:37 -05001893#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1894#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1895#else
1896#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1897#endif
1898
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001899static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001900 "stat_result", /* name */
1901 stat_result__doc__, /* doc */
1902 stat_result_fields,
1903 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001904};
1905
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001906PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001907"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1908This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001909 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001910or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001911\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001912See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001913
1914static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 {"f_bsize", },
1916 {"f_frsize", },
1917 {"f_blocks", },
1918 {"f_bfree", },
1919 {"f_bavail", },
1920 {"f_files", },
1921 {"f_ffree", },
1922 {"f_favail", },
1923 {"f_flag", },
1924 {"f_namemax",},
1925 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001926};
1927
1928static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 "statvfs_result", /* name */
1930 statvfs_result__doc__, /* doc */
1931 statvfs_result_fields,
1932 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001933};
1934
Ross Lagerwall7807c352011-03-17 20:20:30 +02001935#if defined(HAVE_WAITID) && !defined(__APPLE__)
1936PyDoc_STRVAR(waitid_result__doc__,
1937"waitid_result: Result from waitid.\n\n\
1938This object may be accessed either as a tuple of\n\
1939 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1940or via the attributes si_pid, si_uid, and so on.\n\
1941\n\
1942See os.waitid for more information.");
1943
1944static PyStructSequence_Field waitid_result_fields[] = {
1945 {"si_pid", },
1946 {"si_uid", },
1947 {"si_signo", },
1948 {"si_status", },
1949 {"si_code", },
1950 {0}
1951};
1952
1953static PyStructSequence_Desc waitid_result_desc = {
1954 "waitid_result", /* name */
1955 waitid_result__doc__, /* doc */
1956 waitid_result_fields,
1957 5
1958};
1959static PyTypeObject WaitidResultType;
1960#endif
1961
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001962static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001963static PyTypeObject StatResultType;
1964static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001965#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001966static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001967#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001968static newfunc structseq_new;
1969
1970static PyObject *
1971statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1972{
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 PyStructSequence *result;
1974 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001975
Victor Stinner8c62be82010-05-06 00:08:46 +00001976 result = (PyStructSequence*)structseq_new(type, args, kwds);
1977 if (!result)
1978 return NULL;
1979 /* If we have been initialized from a tuple,
1980 st_?time might be set to None. Initialize it
1981 from the int slots. */
1982 for (i = 7; i <= 9; i++) {
1983 if (result->ob_item[i+3] == Py_None) {
1984 Py_DECREF(Py_None);
1985 Py_INCREF(result->ob_item[i]);
1986 result->ob_item[i+3] = result->ob_item[i];
1987 }
1988 }
1989 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001990}
1991
1992
1993
1994/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001995static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001996
1997PyDoc_STRVAR(stat_float_times__doc__,
1998"stat_float_times([newval]) -> oldval\n\n\
1999Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10002000\n\
2001If value is True, future calls to stat() return floats; if it is False,\n\
2002future calls return ints.\n\
2003If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002004
Larry Hastings2f936352014-08-05 14:04:04 +10002005/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002006static PyObject*
2007stat_float_times(PyObject* self, PyObject *args)
2008{
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 int newval = -1;
2010 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2011 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002012 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2013 "stat_float_times() is deprecated",
2014 1))
2015 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002016 if (newval == -1)
2017 /* Return old value */
2018 return PyBool_FromLong(_stat_float_times);
2019 _stat_float_times = newval;
2020 Py_INCREF(Py_None);
2021 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002022}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002023
Larry Hastings6fe20b32012-04-19 15:07:49 -07002024static PyObject *billion = NULL;
2025
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002026static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002027fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002028{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002029 PyObject *s = _PyLong_FromTime_t(sec);
2030 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2031 PyObject *s_in_ns = NULL;
2032 PyObject *ns_total = NULL;
2033 PyObject *float_s = NULL;
2034
2035 if (!(s && ns_fractional))
2036 goto exit;
2037
2038 s_in_ns = PyNumber_Multiply(s, billion);
2039 if (!s_in_ns)
2040 goto exit;
2041
2042 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2043 if (!ns_total)
2044 goto exit;
2045
Victor Stinner4195b5c2012-02-08 23:03:19 +01002046 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002047 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2048 if (!float_s)
2049 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002051 else {
2052 float_s = s;
2053 Py_INCREF(float_s);
2054 }
2055
2056 PyStructSequence_SET_ITEM(v, index, s);
2057 PyStructSequence_SET_ITEM(v, index+3, float_s);
2058 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2059 s = NULL;
2060 float_s = NULL;
2061 ns_total = NULL;
2062exit:
2063 Py_XDECREF(s);
2064 Py_XDECREF(ns_fractional);
2065 Py_XDECREF(s_in_ns);
2066 Py_XDECREF(ns_total);
2067 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002068}
2069
Tim Peters5aa91602002-01-30 05:46:57 +00002070/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002071 (used by posix_stat() and posix_fstat()) */
2072static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002073_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002074{
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 unsigned long ansec, mnsec, cnsec;
2076 PyObject *v = PyStructSequence_New(&StatResultType);
2077 if (v == NULL)
2078 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002079
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002081#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07002083 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002084#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002085 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002086#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002087#ifdef MS_WINDOWS
2088 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002089#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002090 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002091#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002093#if defined(MS_WINDOWS)
2094 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2095 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2096#else
2097 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2098 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2099#endif
Fred Drake699f3522000-06-29 21:12:41 +00002100#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002101 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07002102 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002103#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002104 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002105#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002106
Martin v. Löwis14694662006-02-03 12:54:16 +00002107#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002108 ansec = st->st_atim.tv_nsec;
2109 mnsec = st->st_mtim.tv_nsec;
2110 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002111#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 ansec = st->st_atimespec.tv_nsec;
2113 mnsec = st->st_mtimespec.tv_nsec;
2114 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002115#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002116 ansec = st->st_atime_nsec;
2117 mnsec = st->st_mtime_nsec;
2118 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002119#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002120 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002121#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002122 fill_time(v, 7, st->st_atime, ansec);
2123 fill_time(v, 8, st->st_mtime, mnsec);
2124 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002125
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002126#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002127 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2128 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002129#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002130#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002131 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2132 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002133#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002134#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2136 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002137#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002138#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002139 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2140 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002141#endif
2142#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002143 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002144 PyObject *val;
2145 unsigned long bsec,bnsec;
2146 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002147#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002148 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002149#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002150 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002151#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002152 if (_stat_float_times) {
2153 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2154 } else {
2155 val = PyLong_FromLong((long)bsec);
2156 }
2157 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2158 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002159 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002160#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002161#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002162 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2163 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002164#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002165#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2166 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2167 PyLong_FromUnsignedLong(st->st_file_attributes));
2168#endif
Fred Drake699f3522000-06-29 21:12:41 +00002169
Victor Stinner8c62be82010-05-06 00:08:46 +00002170 if (PyErr_Occurred()) {
2171 Py_DECREF(v);
2172 return NULL;
2173 }
Fred Drake699f3522000-06-29 21:12:41 +00002174
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002176}
2177
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002178/* POSIX methods */
2179
Guido van Rossum94f6f721999-01-06 18:42:14 +00002180
2181static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002182posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002183 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002184{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002185 STRUCT_STAT st;
2186 int result;
2187
2188#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2189 if (follow_symlinks_specified(function_name, follow_symlinks))
2190 return NULL;
2191#endif
2192
2193 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2194 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2195 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2196 return NULL;
2197
2198 Py_BEGIN_ALLOW_THREADS
2199 if (path->fd != -1)
2200 result = FSTAT(path->fd, &st);
2201 else
2202#ifdef MS_WINDOWS
2203 if (path->wide) {
2204 if (follow_symlinks)
2205 result = win32_stat_w(path->wide, &st);
2206 else
2207 result = win32_lstat_w(path->wide, &st);
2208 }
2209 else
2210#endif
2211#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2212 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2213 result = LSTAT(path->narrow, &st);
2214 else
2215#endif
2216#ifdef HAVE_FSTATAT
2217 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2218 result = fstatat(dir_fd, path->narrow, &st,
2219 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2220 else
2221#endif
2222 result = STAT(path->narrow, &st);
2223 Py_END_ALLOW_THREADS
2224
Victor Stinner292c8352012-10-30 02:17:38 +01002225 if (result != 0) {
2226 return path_error(path);
2227 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002228
2229 return _pystat_fromstructstat(&st);
2230}
2231
Larry Hastings2f936352014-08-05 14:04:04 +10002232/*[python input]
2233
2234for s in """
2235
2236FACCESSAT
2237FCHMODAT
2238FCHOWNAT
2239FSTATAT
2240LINKAT
2241MKDIRAT
2242MKFIFOAT
2243MKNODAT
2244OPENAT
2245READLINKAT
2246SYMLINKAT
2247UNLINKAT
2248
2249""".strip().split():
2250 s = s.strip()
2251 print("""
2252#ifdef HAVE_{s}
2253 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002254#else
Larry Hastings2f936352014-08-05 14:04:04 +10002255 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002256#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002257""".rstrip().format(s=s))
2258
2259for s in """
2260
2261FCHDIR
2262FCHMOD
2263FCHOWN
2264FDOPENDIR
2265FEXECVE
2266FPATHCONF
2267FSTATVFS
2268FTRUNCATE
2269
2270""".strip().split():
2271 s = s.strip()
2272 print("""
2273#ifdef HAVE_{s}
2274 #define PATH_HAVE_{s} 1
2275#else
2276 #define PATH_HAVE_{s} 0
2277#endif
2278
2279""".rstrip().format(s=s))
2280[python start generated code]*/
2281
2282#ifdef HAVE_FACCESSAT
2283 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2284#else
2285 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2286#endif
2287
2288#ifdef HAVE_FCHMODAT
2289 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2290#else
2291 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2292#endif
2293
2294#ifdef HAVE_FCHOWNAT
2295 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2296#else
2297 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2298#endif
2299
2300#ifdef HAVE_FSTATAT
2301 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2302#else
2303 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2304#endif
2305
2306#ifdef HAVE_LINKAT
2307 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2308#else
2309 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2310#endif
2311
2312#ifdef HAVE_MKDIRAT
2313 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2314#else
2315 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2316#endif
2317
2318#ifdef HAVE_MKFIFOAT
2319 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2320#else
2321 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2322#endif
2323
2324#ifdef HAVE_MKNODAT
2325 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2326#else
2327 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2328#endif
2329
2330#ifdef HAVE_OPENAT
2331 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2332#else
2333 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2334#endif
2335
2336#ifdef HAVE_READLINKAT
2337 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2338#else
2339 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2340#endif
2341
2342#ifdef HAVE_SYMLINKAT
2343 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2344#else
2345 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2346#endif
2347
2348#ifdef HAVE_UNLINKAT
2349 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2350#else
2351 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2352#endif
2353
2354#ifdef HAVE_FCHDIR
2355 #define PATH_HAVE_FCHDIR 1
2356#else
2357 #define PATH_HAVE_FCHDIR 0
2358#endif
2359
2360#ifdef HAVE_FCHMOD
2361 #define PATH_HAVE_FCHMOD 1
2362#else
2363 #define PATH_HAVE_FCHMOD 0
2364#endif
2365
2366#ifdef HAVE_FCHOWN
2367 #define PATH_HAVE_FCHOWN 1
2368#else
2369 #define PATH_HAVE_FCHOWN 0
2370#endif
2371
2372#ifdef HAVE_FDOPENDIR
2373 #define PATH_HAVE_FDOPENDIR 1
2374#else
2375 #define PATH_HAVE_FDOPENDIR 0
2376#endif
2377
2378#ifdef HAVE_FEXECVE
2379 #define PATH_HAVE_FEXECVE 1
2380#else
2381 #define PATH_HAVE_FEXECVE 0
2382#endif
2383
2384#ifdef HAVE_FPATHCONF
2385 #define PATH_HAVE_FPATHCONF 1
2386#else
2387 #define PATH_HAVE_FPATHCONF 0
2388#endif
2389
2390#ifdef HAVE_FSTATVFS
2391 #define PATH_HAVE_FSTATVFS 1
2392#else
2393 #define PATH_HAVE_FSTATVFS 0
2394#endif
2395
2396#ifdef HAVE_FTRUNCATE
2397 #define PATH_HAVE_FTRUNCATE 1
2398#else
2399 #define PATH_HAVE_FTRUNCATE 0
2400#endif
2401/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002402
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002403#ifdef MS_WINDOWS
2404 #undef PATH_HAVE_FTRUNCATE
2405 #define PATH_HAVE_FTRUNCATE 1
2406#endif
Larry Hastings31826802013-10-19 00:09:25 -07002407
Larry Hastings61272b72014-01-07 12:41:53 -08002408/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002409
2410class path_t_converter(CConverter):
2411
2412 type = "path_t"
2413 impl_by_reference = True
2414 parse_by_reference = True
2415
2416 converter = 'path_converter'
2417
2418 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002419 # right now path_t doesn't support default values.
2420 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002421 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002422 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002423
Larry Hastings2f936352014-08-05 14:04:04 +10002424 if self.c_default not in (None, 'Py_None'):
2425 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002426
2427 self.nullable = nullable
2428 self.allow_fd = allow_fd
2429
Larry Hastings7726ac92014-01-31 22:03:12 -08002430 def pre_render(self):
2431 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002432 if isinstance(value, str):
2433 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002434 return str(int(bool(value)))
2435
2436 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002437 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002438 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002439 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002440 strify(self.nullable),
2441 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002442 )
2443
2444 def cleanup(self):
2445 return "path_cleanup(&" + self.name + ");\n"
2446
2447
2448class dir_fd_converter(CConverter):
2449 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002450
Larry Hastings2f936352014-08-05 14:04:04 +10002451 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002452 if self.default in (unspecified, None):
2453 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002454 if isinstance(requires, str):
2455 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2456 else:
2457 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002458
Larry Hastings2f936352014-08-05 14:04:04 +10002459class fildes_converter(CConverter):
2460 type = 'int'
2461 converter = 'fildes_converter'
2462
2463class uid_t_converter(CConverter):
2464 type = "uid_t"
2465 converter = '_Py_Uid_Converter'
2466
2467class gid_t_converter(CConverter):
2468 type = "gid_t"
2469 converter = '_Py_Gid_Converter'
2470
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002471class dev_t_converter(CConverter):
2472 type = 'dev_t'
2473 converter = '_Py_Dev_Converter'
2474
2475class dev_t_return_converter(unsigned_long_return_converter):
2476 type = 'dev_t'
2477 conversion_fn = '_PyLong_FromDev'
2478 unsigned_cast = '(dev_t)'
2479
Larry Hastings2f936352014-08-05 14:04:04 +10002480class FSConverter_converter(CConverter):
2481 type = 'PyObject *'
2482 converter = 'PyUnicode_FSConverter'
2483 def converter_init(self):
2484 if self.default is not unspecified:
2485 fail("FSConverter_converter does not support default values")
2486 self.c_default = 'NULL'
2487
2488 def cleanup(self):
2489 return "Py_XDECREF(" + self.name + ");\n"
2490
2491class pid_t_converter(CConverter):
2492 type = 'pid_t'
2493 format_unit = '" _Py_PARSE_PID "'
2494
2495class idtype_t_converter(int_converter):
2496 type = 'idtype_t'
2497
2498class id_t_converter(CConverter):
2499 type = 'id_t'
2500 format_unit = '" _Py_PARSE_PID "'
2501
Benjamin Petersonca470632016-09-06 13:47:26 -07002502class intptr_t_converter(CConverter):
2503 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002504 format_unit = '" _Py_PARSE_INTPTR "'
2505
2506class Py_off_t_converter(CConverter):
2507 type = 'Py_off_t'
2508 converter = 'Py_off_t_converter'
2509
2510class Py_off_t_return_converter(long_return_converter):
2511 type = 'Py_off_t'
2512 conversion_fn = 'PyLong_FromPy_off_t'
2513
2514class path_confname_converter(CConverter):
2515 type="int"
2516 converter="conv_path_confname"
2517
2518class confstr_confname_converter(path_confname_converter):
2519 converter='conv_confstr_confname'
2520
2521class sysconf_confname_converter(path_confname_converter):
2522 converter="conv_sysconf_confname"
2523
2524class sched_param_converter(CConverter):
2525 type = 'struct sched_param'
2526 converter = 'convert_sched_param'
2527 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002528
Larry Hastings61272b72014-01-07 12:41:53 -08002529[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002530/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002531
Larry Hastings61272b72014-01-07 12:41:53 -08002532/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002533
Larry Hastings2a727912014-01-16 11:32:01 -08002534os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002535
2536 path : path_t(allow_fd=True)
2537 Path to be examined; can be string, bytes, or open-file-descriptor int.
2538
2539 *
2540
Larry Hastings2f936352014-08-05 14:04:04 +10002541 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002542 If not None, it should be a file descriptor open to a directory,
2543 and path should be a relative string; path will then be relative to
2544 that directory.
2545
2546 follow_symlinks: bool = True
2547 If False, and the last element of the path is a symbolic link,
2548 stat will examine the symbolic link itself instead of the file
2549 the link points to.
2550
2551Perform a stat system call on the given path.
2552
2553dir_fd and follow_symlinks may not be implemented
2554 on your platform. If they are unavailable, using them will raise a
2555 NotImplementedError.
2556
2557It's an error to use dir_fd or follow_symlinks when specifying path as
2558 an open file descriptor.
2559
Larry Hastings61272b72014-01-07 12:41:53 -08002560[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002561
Larry Hastings31826802013-10-19 00:09:25 -07002562static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002563os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2564/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002565{
2566 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2567}
2568
Larry Hastings2f936352014-08-05 14:04:04 +10002569
2570/*[clinic input]
2571os.lstat
2572
2573 path : path_t
2574
2575 *
2576
2577 dir_fd : dir_fd(requires='fstatat') = None
2578
2579Perform a stat system call on the given path, without following symbolic links.
2580
2581Like stat(), but do not follow symbolic links.
2582Equivalent to stat(path, follow_symlinks=False).
2583[clinic start generated code]*/
2584
Larry Hastings2f936352014-08-05 14:04:04 +10002585static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002586os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2587/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002588{
2589 int follow_symlinks = 0;
2590 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2591}
Larry Hastings31826802013-10-19 00:09:25 -07002592
Larry Hastings2f936352014-08-05 14:04:04 +10002593
Larry Hastings61272b72014-01-07 12:41:53 -08002594/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002595os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002596
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002597 path: path_t
2598 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002599
2600 mode: int
2601 Operating-system mode bitfield. Can be F_OK to test existence,
2602 or the inclusive-OR of R_OK, W_OK, and X_OK.
2603
2604 *
2605
Larry Hastings2f936352014-08-05 14:04:04 +10002606 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002607 If not None, it should be a file descriptor open to a directory,
2608 and path should be relative; path will then be relative to that
2609 directory.
2610
2611 effective_ids: bool = False
2612 If True, access will use the effective uid/gid instead of
2613 the real uid/gid.
2614
2615 follow_symlinks: bool = True
2616 If False, and the last element of the path is a symbolic link,
2617 access will examine the symbolic link itself instead of the file
2618 the link points to.
2619
2620Use the real uid/gid to test for access to a path.
2621
2622{parameters}
2623dir_fd, effective_ids, and follow_symlinks may not be implemented
2624 on your platform. If they are unavailable, using them will raise a
2625 NotImplementedError.
2626
2627Note that most operations will use the effective uid/gid, therefore this
2628 routine can be used in a suid/sgid environment to test if the invoking user
2629 has the specified access to the path.
2630
Larry Hastings61272b72014-01-07 12:41:53 -08002631[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002632
Larry Hastings2f936352014-08-05 14:04:04 +10002633static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002634os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002635 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002636/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002637{
Larry Hastings2f936352014-08-05 14:04:04 +10002638 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002639
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002640#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002641 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002642#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002644#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002645
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646#ifndef HAVE_FACCESSAT
2647 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002648 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002649
2650 if (effective_ids) {
2651 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002652 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653 }
2654#endif
2655
2656#ifdef MS_WINDOWS
2657 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002658 if (path->wide != NULL)
2659 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002661 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002662 Py_END_ALLOW_THREADS
2663
2664 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002665 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002666 * * we didn't get a -1, and
2667 * * write access wasn't requested,
2668 * * or the file isn't read-only,
2669 * * or it's a directory.
2670 * (Directories cannot be read-only on Windows.)
2671 */
Larry Hastings2f936352014-08-05 14:04:04 +10002672 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002673 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002675 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002676#else
2677
2678 Py_BEGIN_ALLOW_THREADS
2679#ifdef HAVE_FACCESSAT
2680 if ((dir_fd != DEFAULT_DIR_FD) ||
2681 effective_ids ||
2682 !follow_symlinks) {
2683 int flags = 0;
2684 if (!follow_symlinks)
2685 flags |= AT_SYMLINK_NOFOLLOW;
2686 if (effective_ids)
2687 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002688 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689 }
2690 else
2691#endif
Larry Hastings31826802013-10-19 00:09:25 -07002692 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002693 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002694 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002695#endif
2696
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002698}
2699
Guido van Rossumd371ff11999-01-25 16:12:23 +00002700#ifndef F_OK
2701#define F_OK 0
2702#endif
2703#ifndef R_OK
2704#define R_OK 4
2705#endif
2706#ifndef W_OK
2707#define W_OK 2
2708#endif
2709#ifndef X_OK
2710#define X_OK 1
2711#endif
2712
Larry Hastings31826802013-10-19 00:09:25 -07002713
Guido van Rossumd371ff11999-01-25 16:12:23 +00002714#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002715/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002716os.ttyname -> DecodeFSDefault
2717
2718 fd: int
2719 Integer file descriptor handle.
2720
2721 /
2722
2723Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002724[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002725
Larry Hastings31826802013-10-19 00:09:25 -07002726static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002727os_ttyname_impl(PyObject *module, int fd)
2728/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002729{
2730 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002731
Larry Hastings31826802013-10-19 00:09:25 -07002732 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002733 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002734 posix_error();
2735 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002736}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002737#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002738
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002739#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002740/*[clinic input]
2741os.ctermid
2742
2743Return the name of the controlling terminal for this process.
2744[clinic start generated code]*/
2745
Larry Hastings2f936352014-08-05 14:04:04 +10002746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002747os_ctermid_impl(PyObject *module)
2748/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002749{
Victor Stinner8c62be82010-05-06 00:08:46 +00002750 char *ret;
2751 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002752
Greg Wardb48bc172000-03-01 21:51:56 +00002753#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002754 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002755#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002756 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002757#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002758 if (ret == NULL)
2759 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002760 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002761}
Larry Hastings2f936352014-08-05 14:04:04 +10002762#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002763
Larry Hastings2f936352014-08-05 14:04:04 +10002764
2765/*[clinic input]
2766os.chdir
2767
2768 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2769
2770Change the current working directory to the specified path.
2771
2772path may always be specified as a string.
2773On some platforms, path may also be specified as an open file descriptor.
2774 If this functionality is unavailable, using it raises an exception.
2775[clinic start generated code]*/
2776
Larry Hastings2f936352014-08-05 14:04:04 +10002777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002778os_chdir_impl(PyObject *module, path_t *path)
2779/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002780{
2781 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782
2783 Py_BEGIN_ALLOW_THREADS
2784#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002785 if (path->wide)
2786 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787 else
Larry Hastings2f936352014-08-05 14:04:04 +10002788 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002789 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790#else
2791#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002792 if (path->fd != -1)
2793 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794 else
2795#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002796 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797#endif
2798 Py_END_ALLOW_THREADS
2799
2800 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002801 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802 }
2803
Larry Hastings2f936352014-08-05 14:04:04 +10002804 Py_RETURN_NONE;
2805}
2806
2807
2808#ifdef HAVE_FCHDIR
2809/*[clinic input]
2810os.fchdir
2811
2812 fd: fildes
2813
2814Change to the directory of the given file descriptor.
2815
2816fd must be opened on a directory, not a file.
2817Equivalent to os.chdir(fd).
2818
2819[clinic start generated code]*/
2820
Fred Drake4d1e64b2002-04-15 19:40:07 +00002821static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002822os_fchdir_impl(PyObject *module, int fd)
2823/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002824{
Larry Hastings2f936352014-08-05 14:04:04 +10002825 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002826}
2827#endif /* HAVE_FCHDIR */
2828
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002829
Larry Hastings2f936352014-08-05 14:04:04 +10002830/*[clinic input]
2831os.chmod
2832
2833 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2834 Path to be modified. May always be specified as a str or bytes.
2835 On some platforms, path may also be specified as an open file descriptor.
2836 If this functionality is unavailable, using it raises an exception.
2837
2838 mode: int
2839 Operating-system mode bitfield.
2840
2841 *
2842
2843 dir_fd : dir_fd(requires='fchmodat') = None
2844 If not None, it should be a file descriptor open to a directory,
2845 and path should be relative; path will then be relative to that
2846 directory.
2847
2848 follow_symlinks: bool = True
2849 If False, and the last element of the path is a symbolic link,
2850 chmod will modify the symbolic link itself instead of the file
2851 the link points to.
2852
2853Change the access permissions of a file.
2854
2855It is an error to use dir_fd or follow_symlinks when specifying path as
2856 an open file descriptor.
2857dir_fd and follow_symlinks may not be implemented on your platform.
2858 If they are unavailable, using them will raise a NotImplementedError.
2859
2860[clinic start generated code]*/
2861
Larry Hastings2f936352014-08-05 14:04:04 +10002862static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002863os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002864 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002865/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002866{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002868
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002869#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002871#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002872
Larry Hastings9cf065c2012-06-22 16:30:09 -07002873#ifdef HAVE_FCHMODAT
2874 int fchmodat_nofollow_unsupported = 0;
2875#endif
2876
Larry Hastings9cf065c2012-06-22 16:30:09 -07002877#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2878 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002879 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002880#endif
2881
2882#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002883 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002884 if (path->wide)
2885 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886 else
Larry Hastings2f936352014-08-05 14:04:04 +10002887 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002888 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002889 result = 0;
2890 else {
2891 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002892 attr &= ~FILE_ATTRIBUTE_READONLY;
2893 else
2894 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002895 if (path->wide)
2896 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002897 else
Larry Hastings2f936352014-08-05 14:04:04 +10002898 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002899 }
2900 Py_END_ALLOW_THREADS
2901
2902 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002903 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002904 }
2905#else /* MS_WINDOWS */
2906 Py_BEGIN_ALLOW_THREADS
2907#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002908 if (path->fd != -1)
2909 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910 else
2911#endif
2912#ifdef HAVE_LCHMOD
2913 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002914 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002915 else
2916#endif
2917#ifdef HAVE_FCHMODAT
2918 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2919 /*
2920 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2921 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002922 * and then says it isn't implemented yet.
2923 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002924 *
2925 * Once it is supported, os.chmod will automatically
2926 * support dir_fd and follow_symlinks=False. (Hopefully.)
2927 * Until then, we need to be careful what exception we raise.
2928 */
Larry Hastings2f936352014-08-05 14:04:04 +10002929 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002930 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2931 /*
2932 * But wait! We can't throw the exception without allowing threads,
2933 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2934 */
2935 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002936 result &&
2937 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2938 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 }
2940 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002941#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002942 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002943 Py_END_ALLOW_THREADS
2944
2945 if (result) {
2946#ifdef HAVE_FCHMODAT
2947 if (fchmodat_nofollow_unsupported) {
2948 if (dir_fd != DEFAULT_DIR_FD)
2949 dir_fd_and_follow_symlinks_invalid("chmod",
2950 dir_fd, follow_symlinks);
2951 else
2952 follow_symlinks_specified("chmod", follow_symlinks);
2953 }
2954 else
2955#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002956 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957 }
2958#endif
2959
Larry Hastings2f936352014-08-05 14:04:04 +10002960 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002961}
2962
Larry Hastings9cf065c2012-06-22 16:30:09 -07002963
Christian Heimes4e30a842007-11-30 22:12:06 +00002964#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002965/*[clinic input]
2966os.fchmod
2967
2968 fd: int
2969 mode: int
2970
2971Change the access permissions of the file given by file descriptor fd.
2972
2973Equivalent to os.chmod(fd, mode).
2974[clinic start generated code]*/
2975
Larry Hastings2f936352014-08-05 14:04:04 +10002976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002977os_fchmod_impl(PyObject *module, int fd, int mode)
2978/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002979{
2980 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002981 int async_err = 0;
2982
2983 do {
2984 Py_BEGIN_ALLOW_THREADS
2985 res = fchmod(fd, mode);
2986 Py_END_ALLOW_THREADS
2987 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2988 if (res != 0)
2989 return (!async_err) ? posix_error() : NULL;
2990
Victor Stinner8c62be82010-05-06 00:08:46 +00002991 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002992}
2993#endif /* HAVE_FCHMOD */
2994
Larry Hastings2f936352014-08-05 14:04:04 +10002995
Christian Heimes4e30a842007-11-30 22:12:06 +00002996#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002997/*[clinic input]
2998os.lchmod
2999
3000 path: path_t
3001 mode: int
3002
3003Change the access permissions of a file, without following symbolic links.
3004
3005If path is a symlink, this affects the link itself rather than the target.
3006Equivalent to chmod(path, mode, follow_symlinks=False)."
3007[clinic start generated code]*/
3008
Larry Hastings2f936352014-08-05 14:04:04 +10003009static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003010os_lchmod_impl(PyObject *module, path_t *path, int mode)
3011/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003012{
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003014 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003015 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003017 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003018 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003019 return NULL;
3020 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003021 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003022}
3023#endif /* HAVE_LCHMOD */
3024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003025
Thomas Wouterscf297e42007-02-23 15:07:44 +00003026#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003027/*[clinic input]
3028os.chflags
3029
3030 path: path_t
3031 flags: unsigned_long(bitwise=True)
3032 follow_symlinks: bool=True
3033
3034Set file flags.
3035
3036If follow_symlinks is False, and the last element of the path is a symbolic
3037 link, chflags will change flags on the symbolic link itself instead of the
3038 file the link points to.
3039follow_symlinks may not be implemented on your platform. If it is
3040unavailable, using it will raise a NotImplementedError.
3041
3042[clinic start generated code]*/
3043
Larry Hastings2f936352014-08-05 14:04:04 +10003044static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003045os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003046 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003047/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003048{
3049 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003050
3051#ifndef HAVE_LCHFLAGS
3052 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003053 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003054#endif
3055
Victor Stinner8c62be82010-05-06 00:08:46 +00003056 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003057#ifdef HAVE_LCHFLAGS
3058 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003059 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060 else
3061#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003062 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003063 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003064
Larry Hastings2f936352014-08-05 14:04:04 +10003065 if (result)
3066 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003067
Larry Hastings2f936352014-08-05 14:04:04 +10003068 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003069}
3070#endif /* HAVE_CHFLAGS */
3071
Larry Hastings2f936352014-08-05 14:04:04 +10003072
Thomas Wouterscf297e42007-02-23 15:07:44 +00003073#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003074/*[clinic input]
3075os.lchflags
3076
3077 path: path_t
3078 flags: unsigned_long(bitwise=True)
3079
3080Set file flags.
3081
3082This function will not follow symbolic links.
3083Equivalent to chflags(path, flags, follow_symlinks=False).
3084[clinic start generated code]*/
3085
Larry Hastings2f936352014-08-05 14:04:04 +10003086static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003087os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3088/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003089{
Victor Stinner8c62be82010-05-06 00:08:46 +00003090 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003092 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003094 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003095 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003096 }
Victor Stinner292c8352012-10-30 02:17:38 +01003097 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003098}
3099#endif /* HAVE_LCHFLAGS */
3100
Larry Hastings2f936352014-08-05 14:04:04 +10003101
Martin v. Löwis244edc82001-10-04 22:44:26 +00003102#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003103/*[clinic input]
3104os.chroot
3105 path: path_t
3106
3107Change root directory to path.
3108
3109[clinic start generated code]*/
3110
Larry Hastings2f936352014-08-05 14:04:04 +10003111static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003112os_chroot_impl(PyObject *module, path_t *path)
3113/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003114{
3115 int res;
3116 Py_BEGIN_ALLOW_THREADS
3117 res = chroot(path->narrow);
3118 Py_END_ALLOW_THREADS
3119 if (res < 0)
3120 return path_error(path);
3121 Py_RETURN_NONE;
3122}
3123#endif /* HAVE_CHROOT */
3124
Martin v. Löwis244edc82001-10-04 22:44:26 +00003125
Guido van Rossum21142a01999-01-08 21:05:37 +00003126#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003127/*[clinic input]
3128os.fsync
3129
3130 fd: fildes
3131
3132Force write of fd to disk.
3133[clinic start generated code]*/
3134
Larry Hastings2f936352014-08-05 14:04:04 +10003135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003136os_fsync_impl(PyObject *module, int fd)
3137/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003138{
3139 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003140}
3141#endif /* HAVE_FSYNC */
3142
Larry Hastings2f936352014-08-05 14:04:04 +10003143
Ross Lagerwall7807c352011-03-17 20:20:30 +02003144#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003145/*[clinic input]
3146os.sync
3147
3148Force write of everything to disk.
3149[clinic start generated code]*/
3150
Larry Hastings2f936352014-08-05 14:04:04 +10003151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003152os_sync_impl(PyObject *module)
3153/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003154{
3155 Py_BEGIN_ALLOW_THREADS
3156 sync();
3157 Py_END_ALLOW_THREADS
3158 Py_RETURN_NONE;
3159}
Larry Hastings2f936352014-08-05 14:04:04 +10003160#endif /* HAVE_SYNC */
3161
Ross Lagerwall7807c352011-03-17 20:20:30 +02003162
Guido van Rossum21142a01999-01-08 21:05:37 +00003163#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003164#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003165extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3166#endif
3167
Larry Hastings2f936352014-08-05 14:04:04 +10003168/*[clinic input]
3169os.fdatasync
3170
3171 fd: fildes
3172
3173Force write of fd to disk without forcing update of metadata.
3174[clinic start generated code]*/
3175
Larry Hastings2f936352014-08-05 14:04:04 +10003176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003177os_fdatasync_impl(PyObject *module, int fd)
3178/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003179{
3180 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003181}
3182#endif /* HAVE_FDATASYNC */
3183
3184
Fredrik Lundh10723342000-07-10 16:38:09 +00003185#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003186/*[clinic input]
3187os.chown
3188
3189 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3190 Path to be examined; can be string, bytes, or open-file-descriptor int.
3191
3192 uid: uid_t
3193
3194 gid: gid_t
3195
3196 *
3197
3198 dir_fd : dir_fd(requires='fchownat') = None
3199 If not None, it should be a file descriptor open to a directory,
3200 and path should be relative; path will then be relative to that
3201 directory.
3202
3203 follow_symlinks: bool = True
3204 If False, and the last element of the path is a symbolic link,
3205 stat will examine the symbolic link itself instead of the file
3206 the link points to.
3207
3208Change the owner and group id of path to the numeric uid and gid.\
3209
3210path may always be specified as a string.
3211On some platforms, path may also be specified as an open file descriptor.
3212 If this functionality is unavailable, using it raises an exception.
3213If dir_fd is not None, it should be a file descriptor open to a directory,
3214 and path should be relative; path will then be relative to that directory.
3215If follow_symlinks is False, and the last element of the path is a symbolic
3216 link, chown will modify the symbolic link itself instead of the file the
3217 link points to.
3218It is an error to use dir_fd or follow_symlinks when specifying path as
3219 an open file descriptor.
3220dir_fd and follow_symlinks may not be implemented on your platform.
3221 If they are unavailable, using them will raise a NotImplementedError.
3222
3223[clinic start generated code]*/
3224
Larry Hastings2f936352014-08-05 14:04:04 +10003225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003226os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003227 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003228/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003229{
3230 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003231
3232#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3233 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003234 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003236 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3237 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3238 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003239
3240#ifdef __APPLE__
3241 /*
3242 * This is for Mac OS X 10.3, which doesn't have lchown.
3243 * (But we still have an lchown symbol because of weak-linking.)
3244 * It doesn't have fchownat either. So there's no possibility
3245 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003246 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003247 if ((!follow_symlinks) && (lchown == NULL)) {
3248 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003249 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 }
3251#endif
3252
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003255 if (path->fd != -1)
3256 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257 else
3258#endif
3259#ifdef HAVE_LCHOWN
3260 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003261 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003262 else
3263#endif
3264#ifdef HAVE_FCHOWNAT
3265 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003266 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003267 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3268 else
3269#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003270 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003271 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272
Larry Hastings2f936352014-08-05 14:04:04 +10003273 if (result)
3274 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275
Larry Hastings2f936352014-08-05 14:04:04 +10003276 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003277}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003278#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003279
Larry Hastings2f936352014-08-05 14:04:04 +10003280
Christian Heimes4e30a842007-11-30 22:12:06 +00003281#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003282/*[clinic input]
3283os.fchown
3284
3285 fd: int
3286 uid: uid_t
3287 gid: gid_t
3288
3289Change the owner and group id of the file specified by file descriptor.
3290
3291Equivalent to os.chown(fd, uid, gid).
3292
3293[clinic start generated code]*/
3294
Larry Hastings2f936352014-08-05 14:04:04 +10003295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003296os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3297/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003298{
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003300 int async_err = 0;
3301
3302 do {
3303 Py_BEGIN_ALLOW_THREADS
3304 res = fchown(fd, uid, gid);
3305 Py_END_ALLOW_THREADS
3306 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3307 if (res != 0)
3308 return (!async_err) ? posix_error() : NULL;
3309
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003311}
3312#endif /* HAVE_FCHOWN */
3313
Larry Hastings2f936352014-08-05 14:04:04 +10003314
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003315#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003316/*[clinic input]
3317os.lchown
3318
3319 path : path_t
3320 uid: uid_t
3321 gid: gid_t
3322
3323Change the owner and group id of path to the numeric uid and gid.
3324
3325This function will not follow symbolic links.
3326Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3327[clinic start generated code]*/
3328
Larry Hastings2f936352014-08-05 14:04:04 +10003329static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003330os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3331/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003332{
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003335 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003337 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003338 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003339 }
Larry Hastings2f936352014-08-05 14:04:04 +10003340 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003341}
3342#endif /* HAVE_LCHOWN */
3343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003344
Barry Warsaw53699e91996-12-10 23:23:01 +00003345static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003346posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003347{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003348 char *buf, *tmpbuf;
3349 char *cwd;
3350 const size_t chunk = 1024;
3351 size_t buflen = 0;
3352 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003353
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003354#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003355 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003356 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003357 wchar_t *wbuf2 = wbuf;
3358 PyObject *resobj;
3359 DWORD len;
3360 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003361 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 /* If the buffer is large enough, len does not include the
3363 terminating \0. If the buffer is too small, len includes
3364 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003365 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003366 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 if (wbuf2)
3368 len = GetCurrentDirectoryW(len, wbuf2);
3369 }
3370 Py_END_ALLOW_THREADS
3371 if (!wbuf2) {
3372 PyErr_NoMemory();
3373 return NULL;
3374 }
3375 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003376 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003377 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003378 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 }
3380 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003381 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003382 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003383 return resobj;
3384 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003385
3386 if (win32_warn_bytes_api())
3387 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003388#endif
3389
Victor Stinner4403d7d2015-04-25 00:16:10 +02003390 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003391 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003392 do {
3393 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003394#ifdef MS_WINDOWS
3395 if (buflen > INT_MAX) {
3396 PyErr_NoMemory();
3397 break;
3398 }
3399#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003400 tmpbuf = PyMem_RawRealloc(buf, buflen);
3401 if (tmpbuf == NULL)
3402 break;
3403
3404 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003405#ifdef MS_WINDOWS
3406 cwd = getcwd(buf, (int)buflen);
3407#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003408 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003409#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003410 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003412
3413 if (cwd == NULL) {
3414 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003416 }
3417
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003419 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3420 else
3421 obj = PyUnicode_DecodeFSDefault(buf);
3422 PyMem_RawFree(buf);
3423
3424 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003425}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003426
Larry Hastings2f936352014-08-05 14:04:04 +10003427
3428/*[clinic input]
3429os.getcwd
3430
3431Return a unicode string representing the current working directory.
3432[clinic start generated code]*/
3433
Larry Hastings2f936352014-08-05 14:04:04 +10003434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003435os_getcwd_impl(PyObject *module)
3436/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003437{
3438 return posix_getcwd(0);
3439}
3440
Larry Hastings2f936352014-08-05 14:04:04 +10003441
3442/*[clinic input]
3443os.getcwdb
3444
3445Return a bytes string representing the current working directory.
3446[clinic start generated code]*/
3447
Larry Hastings2f936352014-08-05 14:04:04 +10003448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003449os_getcwdb_impl(PyObject *module)
3450/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003451{
3452 return posix_getcwd(1);
3453}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003454
Larry Hastings2f936352014-08-05 14:04:04 +10003455
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3457#define HAVE_LINK 1
3458#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003459
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003461/*[clinic input]
3462
3463os.link
3464
3465 src : path_t
3466 dst : path_t
3467 *
3468 src_dir_fd : dir_fd = None
3469 dst_dir_fd : dir_fd = None
3470 follow_symlinks: bool = True
3471
3472Create a hard link to a file.
3473
3474If either src_dir_fd or dst_dir_fd is not None, it should be a file
3475 descriptor open to a directory, and the respective path string (src or dst)
3476 should be relative; the path will then be relative to that directory.
3477If follow_symlinks is False, and the last element of src is a symbolic
3478 link, link will create a link to the symbolic link itself instead of the
3479 file the link points to.
3480src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3481 platform. If they are unavailable, using them will raise a
3482 NotImplementedError.
3483[clinic start generated code]*/
3484
Larry Hastings2f936352014-08-05 14:04:04 +10003485static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003486os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003487 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003488/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003489{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490#ifdef MS_WINDOWS
3491 BOOL result;
3492#else
3493 int result;
3494#endif
3495
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496#ifndef HAVE_LINKAT
3497 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3498 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003499 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003500 }
3501#endif
3502
Larry Hastings2f936352014-08-05 14:04:04 +10003503 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003504 PyErr_SetString(PyExc_NotImplementedError,
3505 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003506 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003508
Brian Curtin1b9df392010-11-24 20:24:31 +00003509#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003511 if (src->wide)
3512 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003513 else
Larry Hastings2f936352014-08-05 14:04:04 +10003514 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003515 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003516
Larry Hastings2f936352014-08-05 14:04:04 +10003517 if (!result)
3518 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519#else
3520 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003521#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3523 (dst_dir_fd != DEFAULT_DIR_FD) ||
3524 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003525 result = linkat(src_dir_fd, src->narrow,
3526 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3528 else
3529#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003530 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003532
Larry Hastings2f936352014-08-05 14:04:04 +10003533 if (result)
3534 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535#endif
3536
Larry Hastings2f936352014-08-05 14:04:04 +10003537 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003538}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539#endif
3540
Brian Curtin1b9df392010-11-24 20:24:31 +00003541
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003542#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003543static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003544_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003545{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546 PyObject *v;
3547 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3548 BOOL result;
3549 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003550 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003552 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554
Gregory P. Smith40a21602013-03-20 20:52:50 -07003555 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 WIN32_FIND_DATAW wFileData;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003557 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003558
Gregory P. Smith40a21602013-03-20 20:52:50 -07003559 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003560 po_wchars = L".";
3561 len = 1;
3562 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003563 po_wchars = path->wide;
3564 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003565 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003567 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 if (!wnamebuf) {
3569 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003572 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003574 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003575 if (wch != SEP && wch != ALTSEP && wch != L':')
3576 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 wcscpy(wnamebuf + len, L"*.*");
3578 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003579 if ((list = PyList_New(0)) == NULL) {
3580 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003581 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003582 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003584 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 if (hFindFile == INVALID_HANDLE_VALUE) {
3586 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 if (error == ERROR_FILE_NOT_FOUND)
3588 goto exit;
3589 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003590 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003591 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003592 }
3593 do {
3594 /* Skip over . and .. */
3595 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3596 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597 v = PyUnicode_FromWideChar(wFileData.cFileName,
3598 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 Py_DECREF(list);
3601 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 break;
3603 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_DECREF(list);
3607 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003608 break;
3609 }
3610 Py_DECREF(v);
3611 }
3612 Py_BEGIN_ALLOW_THREADS
3613 result = FindNextFileW(hFindFile, &wFileData);
3614 Py_END_ALLOW_THREADS
3615 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3616 it got to the end of the directory. */
3617 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003619 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 }
3622 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003623
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003626 strcpy(namebuf, path->narrow);
3627 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 if (len > 0) {
3629 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003630 if (ch != '\\' && ch != '/' && ch != ':')
3631 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003632 strcpy(namebuf + len, "*.*");
3633 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003634
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003636 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003637
Antoine Pitroub73caab2010-08-09 23:39:31 +00003638 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003639 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003640 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 if (hFindFile == INVALID_HANDLE_VALUE) {
3642 int error = GetLastError();
3643 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 goto exit;
3645 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003646 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 }
3649 do {
3650 /* Skip over . and .. */
3651 if (strcmp(FileData.cFileName, ".") != 0 &&
3652 strcmp(FileData.cFileName, "..") != 0) {
3653 v = PyBytes_FromString(FileData.cFileName);
3654 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003655 Py_DECREF(list);
3656 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 break;
3658 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003661 Py_DECREF(list);
3662 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 break;
3664 }
3665 Py_DECREF(v);
3666 }
3667 Py_BEGIN_ALLOW_THREADS
3668 result = FindNextFile(hFindFile, &FileData);
3669 Py_END_ALLOW_THREADS
3670 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3671 it got to the end of the directory. */
3672 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003673 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003674 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003675 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 }
3677 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003678
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679exit:
3680 if (hFindFile != INVALID_HANDLE_VALUE) {
3681 if (FindClose(hFindFile) == FALSE) {
3682 if (list != NULL) {
3683 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003684 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003685 }
3686 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003687 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003688 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003689
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003691} /* end of _listdir_windows_no_opendir */
3692
3693#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3694
3695static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003696_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003697{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003698 PyObject *v;
3699 DIR *dirp = NULL;
3700 struct dirent *ep;
3701 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003702#ifdef HAVE_FDOPENDIR
3703 int fd = -1;
3704#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003705
Victor Stinner8c62be82010-05-06 00:08:46 +00003706 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003707#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003708 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003710 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003711 if (fd == -1)
3712 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713
Larry Hastingsfdaea062012-06-25 04:42:23 -07003714 return_str = 1;
3715
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716 Py_BEGIN_ALLOW_THREADS
3717 dirp = fdopendir(fd);
3718 Py_END_ALLOW_THREADS
3719 }
3720 else
3721#endif
3722 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003723 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003724 if (path->narrow) {
3725 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003726 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003727 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003728 }
3729 else {
3730 name = ".";
3731 return_str = 1;
3732 }
3733
Larry Hastings9cf065c2012-06-22 16:30:09 -07003734 Py_BEGIN_ALLOW_THREADS
3735 dirp = opendir(name);
3736 Py_END_ALLOW_THREADS
3737 }
3738
3739 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003740 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003741#ifdef HAVE_FDOPENDIR
3742 if (fd != -1) {
3743 Py_BEGIN_ALLOW_THREADS
3744 close(fd);
3745 Py_END_ALLOW_THREADS
3746 }
3747#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003748 goto exit;
3749 }
3750 if ((list = PyList_New(0)) == NULL) {
3751 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 }
3753 for (;;) {
3754 errno = 0;
3755 Py_BEGIN_ALLOW_THREADS
3756 ep = readdir(dirp);
3757 Py_END_ALLOW_THREADS
3758 if (ep == NULL) {
3759 if (errno == 0) {
3760 break;
3761 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003762 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003763 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003764 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003765 }
3766 }
3767 if (ep->d_name[0] == '.' &&
3768 (NAMLEN(ep) == 1 ||
3769 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3770 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003771 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003772 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3773 else
3774 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003776 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 break;
3778 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003779 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003781 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 break;
3783 }
3784 Py_DECREF(v);
3785 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003786
Larry Hastings9cf065c2012-06-22 16:30:09 -07003787exit:
3788 if (dirp != NULL) {
3789 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003790#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003791 if (fd > -1)
3792 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003793#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003794 closedir(dirp);
3795 Py_END_ALLOW_THREADS
3796 }
3797
Larry Hastings9cf065c2012-06-22 16:30:09 -07003798 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003799} /* end of _posix_listdir */
3800#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003801
Larry Hastings2f936352014-08-05 14:04:04 +10003802
3803/*[clinic input]
3804os.listdir
3805
3806 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3807
3808Return a list containing the names of the files in the directory.
3809
3810path can be specified as either str or bytes. If path is bytes,
3811 the filenames returned will also be bytes; in all other circumstances
3812 the filenames returned will be str.
3813If path is None, uses the path='.'.
3814On some platforms, path may also be specified as an open file descriptor;\
3815 the file descriptor must refer to a directory.
3816 If this functionality is unavailable, using it raises NotImplementedError.
3817
3818The list is in arbitrary order. It does not include the special
3819entries '.' and '..' even if they are present in the directory.
3820
3821
3822[clinic start generated code]*/
3823
Larry Hastings2f936352014-08-05 14:04:04 +10003824static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003825os_listdir_impl(PyObject *module, path_t *path)
3826/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003827{
3828#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3829 return _listdir_windows_no_opendir(path, NULL);
3830#else
3831 return _posix_listdir(path, NULL);
3832#endif
3833}
3834
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003835#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003836/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003837/*[clinic input]
3838os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003839
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003840 path: path_t
3841 /
3842
3843[clinic start generated code]*/
3844
3845static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003846os__getfullpathname_impl(PyObject *module, path_t *path)
3847/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003848{
3849 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003850 {
Victor Stinner75875072013-11-24 19:23:25 +01003851 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003852 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 DWORD result;
3854 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003855
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003856 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003857 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003858 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003859 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003860 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003861 if (!woutbufp)
3862 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003863 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003864 }
3865 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003866 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003867 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003868 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003869 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003870 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003871 return v;
3872 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003873 else {
3874 char outbuf[MAX_PATH];
3875 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003876
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003877 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3878 outbuf, &temp)) {
3879 win32_error_object("GetFullPathName", path->object);
3880 return NULL;
3881 }
3882 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 }
Larry Hastings2f936352014-08-05 14:04:04 +10003884}
Brian Curtind40e6f72010-07-08 21:39:08 +00003885
Brian Curtind25aef52011-06-13 15:16:04 -05003886
Larry Hastings2f936352014-08-05 14:04:04 +10003887/*[clinic input]
3888os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003889
Larry Hastings2f936352014-08-05 14:04:04 +10003890 path: unicode
3891 /
3892
3893A helper function for samepath on windows.
3894[clinic start generated code]*/
3895
Larry Hastings2f936352014-08-05 14:04:04 +10003896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003897os__getfinalpathname_impl(PyObject *module, PyObject *path)
3898/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003899{
3900 HANDLE hFile;
3901 int buf_size;
3902 wchar_t *target_path;
3903 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003904 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003905 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003906
Larry Hastings2f936352014-08-05 14:04:04 +10003907 path_wchar = PyUnicode_AsUnicode(path);
3908 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003909 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003910
Brian Curtind40e6f72010-07-08 21:39:08 +00003911 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003912 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003913 0, /* desired access */
3914 0, /* share mode */
3915 NULL, /* security attributes */
3916 OPEN_EXISTING,
3917 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3918 FILE_FLAG_BACKUP_SEMANTICS,
3919 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003920
Victor Stinnereb5657a2011-09-30 01:44:27 +02003921 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003922 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003923
3924 /* We have a good handle to the target, use it to determine the
3925 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003926 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003927
3928 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003929 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003930
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003931 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003932 if(!target_path)
3933 return PyErr_NoMemory();
3934
Steve Dower2ea51c92015-03-20 21:49:12 -07003935 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3936 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003937 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003938 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003939
3940 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003941 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003942
3943 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003944 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003945 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003946 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003947}
Brian Curtin62857742010-09-06 17:07:27 +00003948
Brian Curtin95d028f2011-06-09 09:10:38 -05003949PyDoc_STRVAR(posix__isdir__doc__,
3950"Return true if the pathname refers to an existing directory.");
3951
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003952/*[clinic input]
3953os._isdir
3954
3955 path: path_t
3956 /
3957
3958[clinic start generated code]*/
3959
Brian Curtin9c669cc2011-06-08 18:17:18 -05003960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003961os__isdir_impl(PyObject *module, path_t *path)
3962/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003963{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003964 DWORD attributes;
3965
Steve Dowerb22a6772016-07-17 20:49:38 -07003966 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003967 if (!path->narrow)
3968 attributes = GetFileAttributesW(path->wide);
3969 else
3970 attributes = GetFileAttributesA(path->narrow);
Steve Dowerb22a6772016-07-17 20:49:38 -07003971 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003972
Brian Curtin9c669cc2011-06-08 18:17:18 -05003973 if (attributes == INVALID_FILE_ATTRIBUTES)
3974 Py_RETURN_FALSE;
3975
Brian Curtin9c669cc2011-06-08 18:17:18 -05003976 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3977 Py_RETURN_TRUE;
3978 else
3979 Py_RETURN_FALSE;
3980}
Tim Golden6b528062013-08-01 12:44:00 +01003981
Tim Golden6b528062013-08-01 12:44:00 +01003982
Larry Hastings2f936352014-08-05 14:04:04 +10003983/*[clinic input]
3984os._getvolumepathname
3985
3986 path: unicode
3987
3988A helper function for ismount on Win32.
3989[clinic start generated code]*/
3990
Larry Hastings2f936352014-08-05 14:04:04 +10003991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003992os__getvolumepathname_impl(PyObject *module, PyObject *path)
3993/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003994{
3995 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003996 const wchar_t *path_wchar;
3997 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003998 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003999 BOOL ret;
4000
Larry Hastings2f936352014-08-05 14:04:04 +10004001 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
4002 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01004003 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004004 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004005
4006 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004007 buflen = Py_MAX(buflen, MAX_PATH);
4008
4009 if (buflen > DWORD_MAX) {
4010 PyErr_SetString(PyExc_OverflowError, "path too long");
4011 return NULL;
4012 }
4013
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004014 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004015 if (mountpath == NULL)
4016 return PyErr_NoMemory();
4017
4018 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004019 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004020 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004021 Py_END_ALLOW_THREADS
4022
4023 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10004024 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01004025 goto exit;
4026 }
4027 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4028
4029exit:
4030 PyMem_Free(mountpath);
4031 return result;
4032}
Tim Golden6b528062013-08-01 12:44:00 +01004033
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004034#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004035
Larry Hastings2f936352014-08-05 14:04:04 +10004036
4037/*[clinic input]
4038os.mkdir
4039
4040 path : path_t
4041
4042 mode: int = 0o777
4043
4044 *
4045
4046 dir_fd : dir_fd(requires='mkdirat') = None
4047
4048# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4049
4050Create a directory.
4051
4052If dir_fd is not None, it should be a file descriptor open to a directory,
4053 and path should be relative; path will then be relative to that directory.
4054dir_fd may not be implemented on your platform.
4055 If it is unavailable, using it will raise a NotImplementedError.
4056
4057The mode argument is ignored on Windows.
4058[clinic start generated code]*/
4059
Larry Hastings2f936352014-08-05 14:04:04 +10004060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004061os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4062/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004063{
4064 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004065
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004066#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004067 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004068 if (path->wide)
4069 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004070 else
Larry Hastings2f936352014-08-05 14:04:04 +10004071 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004073
Larry Hastings2f936352014-08-05 14:04:04 +10004074 if (!result)
4075 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004077 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004078#if HAVE_MKDIRAT
4079 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004080 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081 else
4082#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004083#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004084 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004085#else
Larry Hastings2f936352014-08-05 14:04:04 +10004086 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004087#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004088 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004089 if (result < 0)
4090 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004091#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004092 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004093}
4094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004095
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004096/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4097#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004098#include <sys/resource.h>
4099#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004100
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004101
4102#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004103/*[clinic input]
4104os.nice
4105
4106 increment: int
4107 /
4108
4109Add increment to the priority of process and return the new priority.
4110[clinic start generated code]*/
4111
Larry Hastings2f936352014-08-05 14:04:04 +10004112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004113os_nice_impl(PyObject *module, int increment)
4114/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004115{
4116 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004117
Victor Stinner8c62be82010-05-06 00:08:46 +00004118 /* There are two flavours of 'nice': one that returns the new
4119 priority (as required by almost all standards out there) and the
4120 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4121 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004122
Victor Stinner8c62be82010-05-06 00:08:46 +00004123 If we are of the nice family that returns the new priority, we
4124 need to clear errno before the call, and check if errno is filled
4125 before calling posix_error() on a returnvalue of -1, because the
4126 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004127
Victor Stinner8c62be82010-05-06 00:08:46 +00004128 errno = 0;
4129 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004130#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004131 if (value == 0)
4132 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004133#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004134 if (value == -1 && errno != 0)
4135 /* either nice() or getpriority() returned an error */
4136 return posix_error();
4137 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004138}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004139#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004140
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004141
4142#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004143/*[clinic input]
4144os.getpriority
4145
4146 which: int
4147 who: int
4148
4149Return program scheduling priority.
4150[clinic start generated code]*/
4151
Larry Hastings2f936352014-08-05 14:04:04 +10004152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004153os_getpriority_impl(PyObject *module, int which, int who)
4154/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004155{
4156 int retval;
4157
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004158 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004159 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004160 if (errno != 0)
4161 return posix_error();
4162 return PyLong_FromLong((long)retval);
4163}
4164#endif /* HAVE_GETPRIORITY */
4165
4166
4167#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004168/*[clinic input]
4169os.setpriority
4170
4171 which: int
4172 who: int
4173 priority: int
4174
4175Set program scheduling priority.
4176[clinic start generated code]*/
4177
Larry Hastings2f936352014-08-05 14:04:04 +10004178static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004179os_setpriority_impl(PyObject *module, int which, int who, int priority)
4180/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004181{
4182 int retval;
4183
4184 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004185 if (retval == -1)
4186 return posix_error();
4187 Py_RETURN_NONE;
4188}
4189#endif /* HAVE_SETPRIORITY */
4190
4191
Barry Warsaw53699e91996-12-10 23:23:01 +00004192static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004193internal_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 +00004194{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004195 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004196 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004197
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004198#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004200 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004201#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004202 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004203#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004204
Larry Hastings9cf065c2012-06-22 16:30:09 -07004205 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4206 (dst_dir_fd != DEFAULT_DIR_FD);
4207#ifndef HAVE_RENAMEAT
4208 if (dir_fd_specified) {
4209 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004210 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004211 }
4212#endif
4213
Larry Hastings2f936352014-08-05 14:04:04 +10004214 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004215 PyErr_Format(PyExc_ValueError,
4216 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004217 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004218 }
4219
4220#ifdef MS_WINDOWS
4221 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004222 if (src->wide)
4223 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004224 else
Larry Hastings2f936352014-08-05 14:04:04 +10004225 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004226 Py_END_ALLOW_THREADS
4227
Larry Hastings2f936352014-08-05 14:04:04 +10004228 if (!result)
4229 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004230
4231#else
4232 Py_BEGIN_ALLOW_THREADS
4233#ifdef HAVE_RENAMEAT
4234 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004235 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004236 else
4237#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004239 Py_END_ALLOW_THREADS
4240
Larry Hastings2f936352014-08-05 14:04:04 +10004241 if (result)
4242 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004243#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004244 Py_RETURN_NONE;
4245}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004246
Larry Hastings2f936352014-08-05 14:04:04 +10004247
4248/*[clinic input]
4249os.rename
4250
4251 src : path_t
4252 dst : path_t
4253 *
4254 src_dir_fd : dir_fd = None
4255 dst_dir_fd : dir_fd = None
4256
4257Rename a file or directory.
4258
4259If either src_dir_fd or dst_dir_fd is not None, it should be a file
4260 descriptor open to a directory, and the respective path string (src or dst)
4261 should be relative; the path will then be relative to that directory.
4262src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4263 If they are unavailable, using them will raise a NotImplementedError.
4264[clinic start generated code]*/
4265
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004266static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004267os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004268 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004269/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004270{
Larry Hastings2f936352014-08-05 14:04:04 +10004271 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004272}
4273
Larry Hastings2f936352014-08-05 14:04:04 +10004274
4275/*[clinic input]
4276os.replace = os.rename
4277
4278Rename a file or directory, overwriting the destination.
4279
4280If either src_dir_fd or dst_dir_fd is not None, it should be a file
4281 descriptor open to a directory, and the respective path string (src or dst)
4282 should be relative; the path will then be relative to that directory.
4283src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4284 If they are unavailable, using them will raise a NotImplementedError."
4285[clinic start generated code]*/
4286
Larry Hastings2f936352014-08-05 14:04:04 +10004287static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004288os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4289 int dst_dir_fd)
4290/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004291{
4292 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4293}
4294
4295
4296/*[clinic input]
4297os.rmdir
4298
4299 path: path_t
4300 *
4301 dir_fd: dir_fd(requires='unlinkat') = None
4302
4303Remove a directory.
4304
4305If dir_fd is not None, it should be a file descriptor open to a directory,
4306 and path should be relative; path will then be relative to that directory.
4307dir_fd may not be implemented on your platform.
4308 If it is unavailable, using it will raise a NotImplementedError.
4309[clinic start generated code]*/
4310
Larry Hastings2f936352014-08-05 14:04:04 +10004311static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004312os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4313/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004314{
4315 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004316
4317 Py_BEGIN_ALLOW_THREADS
4318#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004319 if (path->wide)
4320 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004321 else
Larry Hastings2f936352014-08-05 14:04:04 +10004322 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004323 result = !result; /* Windows, success=1, UNIX, success=0 */
4324#else
4325#ifdef HAVE_UNLINKAT
4326 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004327 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004328 else
4329#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004330 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004331#endif
4332 Py_END_ALLOW_THREADS
4333
Larry Hastings2f936352014-08-05 14:04:04 +10004334 if (result)
4335 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004336
Larry Hastings2f936352014-08-05 14:04:04 +10004337 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004338}
4339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004340
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004341#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004342#ifdef MS_WINDOWS
4343/*[clinic input]
4344os.system -> long
4345
4346 command: Py_UNICODE
4347
4348Execute the command in a subshell.
4349[clinic start generated code]*/
4350
Larry Hastings2f936352014-08-05 14:04:04 +10004351static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004352os_system_impl(PyObject *module, Py_UNICODE *command)
4353/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004354{
4355 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004356 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004357 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004358 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004359 return result;
4360}
4361#else /* MS_WINDOWS */
4362/*[clinic input]
4363os.system -> long
4364
4365 command: FSConverter
4366
4367Execute the command in a subshell.
4368[clinic start generated code]*/
4369
Larry Hastings2f936352014-08-05 14:04:04 +10004370static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004371os_system_impl(PyObject *module, PyObject *command)
4372/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004373{
4374 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004375 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004376 Py_BEGIN_ALLOW_THREADS
4377 result = system(bytes);
4378 Py_END_ALLOW_THREADS
4379 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004380}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004381#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004382#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004384
Larry Hastings2f936352014-08-05 14:04:04 +10004385/*[clinic input]
4386os.umask
4387
4388 mask: int
4389 /
4390
4391Set the current numeric umask and return the previous umask.
4392[clinic start generated code]*/
4393
Larry Hastings2f936352014-08-05 14:04:04 +10004394static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004395os_umask_impl(PyObject *module, int mask)
4396/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004397{
4398 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004399 if (i < 0)
4400 return posix_error();
4401 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004402}
4403
Brian Curtind40e6f72010-07-08 21:39:08 +00004404#ifdef MS_WINDOWS
4405
4406/* override the default DeleteFileW behavior so that directory
4407symlinks can be removed with this function, the same as with
4408Unix symlinks */
4409BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4410{
4411 WIN32_FILE_ATTRIBUTE_DATA info;
4412 WIN32_FIND_DATAW find_data;
4413 HANDLE find_data_handle;
4414 int is_directory = 0;
4415 int is_link = 0;
4416
4417 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4418 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004419
Brian Curtind40e6f72010-07-08 21:39:08 +00004420 /* Get WIN32_FIND_DATA structure for the path to determine if
4421 it is a symlink */
4422 if(is_directory &&
4423 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4424 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4425
4426 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004427 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4428 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4429 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4430 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004431 FindClose(find_data_handle);
4432 }
4433 }
4434 }
4435
4436 if (is_directory && is_link)
4437 return RemoveDirectoryW(lpFileName);
4438
4439 return DeleteFileW(lpFileName);
4440}
4441#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Larry Hastings2f936352014-08-05 14:04:04 +10004444/*[clinic input]
4445os.unlink
4446
4447 path: path_t
4448 *
4449 dir_fd: dir_fd(requires='unlinkat')=None
4450
4451Remove a file (same as remove()).
4452
4453If dir_fd is not None, it should be a file descriptor open to a directory,
4454 and path should be relative; path will then be relative to that directory.
4455dir_fd may not be implemented on your platform.
4456 If it is unavailable, using it will raise a NotImplementedError.
4457
4458[clinic start generated code]*/
4459
Larry Hastings2f936352014-08-05 14:04:04 +10004460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004461os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4462/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004463{
4464 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004465
4466 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004467 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004469 if (path->wide)
4470 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004471 else
Larry Hastings2f936352014-08-05 14:04:04 +10004472 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473 result = !result; /* Windows, success=1, UNIX, success=0 */
4474#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475#ifdef HAVE_UNLINKAT
4476 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004477 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004478 else
4479#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004480 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004481#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004482 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004483 Py_END_ALLOW_THREADS
4484
Larry Hastings2f936352014-08-05 14:04:04 +10004485 if (result)
4486 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004487
Larry Hastings2f936352014-08-05 14:04:04 +10004488 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004489}
4490
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004491
Larry Hastings2f936352014-08-05 14:04:04 +10004492/*[clinic input]
4493os.remove = os.unlink
4494
4495Remove a file (same as unlink()).
4496
4497If dir_fd is not None, it should be a file descriptor open to a directory,
4498 and path should be relative; path will then be relative to that directory.
4499dir_fd may not be implemented on your platform.
4500 If it is unavailable, using it will raise a NotImplementedError.
4501[clinic start generated code]*/
4502
Larry Hastings2f936352014-08-05 14:04:04 +10004503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004504os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4505/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004506{
4507 return os_unlink_impl(module, path, dir_fd);
4508}
4509
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004510
Larry Hastings605a62d2012-06-24 04:33:36 -07004511static PyStructSequence_Field uname_result_fields[] = {
4512 {"sysname", "operating system name"},
4513 {"nodename", "name of machine on network (implementation-defined)"},
4514 {"release", "operating system release"},
4515 {"version", "operating system version"},
4516 {"machine", "hardware identifier"},
4517 {NULL}
4518};
4519
4520PyDoc_STRVAR(uname_result__doc__,
4521"uname_result: Result from os.uname().\n\n\
4522This object may be accessed either as a tuple of\n\
4523 (sysname, nodename, release, version, machine),\n\
4524or via the attributes sysname, nodename, release, version, and machine.\n\
4525\n\
4526See os.uname for more information.");
4527
4528static PyStructSequence_Desc uname_result_desc = {
4529 "uname_result", /* name */
4530 uname_result__doc__, /* doc */
4531 uname_result_fields,
4532 5
4533};
4534
4535static PyTypeObject UnameResultType;
4536
4537
4538#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004539/*[clinic input]
4540os.uname
4541
4542Return an object identifying the current operating system.
4543
4544The object behaves like a named tuple with the following fields:
4545 (sysname, nodename, release, version, machine)
4546
4547[clinic start generated code]*/
4548
Larry Hastings2f936352014-08-05 14:04:04 +10004549static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004550os_uname_impl(PyObject *module)
4551/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004552{
Victor Stinner8c62be82010-05-06 00:08:46 +00004553 struct utsname u;
4554 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004555 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004556
Victor Stinner8c62be82010-05-06 00:08:46 +00004557 Py_BEGIN_ALLOW_THREADS
4558 res = uname(&u);
4559 Py_END_ALLOW_THREADS
4560 if (res < 0)
4561 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004562
4563 value = PyStructSequence_New(&UnameResultType);
4564 if (value == NULL)
4565 return NULL;
4566
4567#define SET(i, field) \
4568 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004569 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004570 if (!o) { \
4571 Py_DECREF(value); \
4572 return NULL; \
4573 } \
4574 PyStructSequence_SET_ITEM(value, i, o); \
4575 } \
4576
4577 SET(0, u.sysname);
4578 SET(1, u.nodename);
4579 SET(2, u.release);
4580 SET(3, u.version);
4581 SET(4, u.machine);
4582
4583#undef SET
4584
4585 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004586}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004587#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004588
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004589
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590
4591typedef struct {
4592 int now;
4593 time_t atime_s;
4594 long atime_ns;
4595 time_t mtime_s;
4596 long mtime_ns;
4597} utime_t;
4598
4599/*
Victor Stinner484df002014-10-09 13:52:31 +02004600 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601 * they also intentionally leak the declaration of a pointer named "time"
4602 */
4603#define UTIME_TO_TIMESPEC \
4604 struct timespec ts[2]; \
4605 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004606 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607 time = NULL; \
4608 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004609 ts[0].tv_sec = ut->atime_s; \
4610 ts[0].tv_nsec = ut->atime_ns; \
4611 ts[1].tv_sec = ut->mtime_s; \
4612 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613 time = ts; \
4614 } \
4615
4616#define UTIME_TO_TIMEVAL \
4617 struct timeval tv[2]; \
4618 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004619 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620 time = NULL; \
4621 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004622 tv[0].tv_sec = ut->atime_s; \
4623 tv[0].tv_usec = ut->atime_ns / 1000; \
4624 tv[1].tv_sec = ut->mtime_s; \
4625 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 time = tv; \
4627 } \
4628
4629#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004630 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004632 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633 time = NULL; \
4634 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004635 u.actime = ut->atime_s; \
4636 u.modtime = ut->mtime_s; \
4637 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004638 }
4639
4640#define UTIME_TO_TIME_T \
4641 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004642 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004643 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004644 time = NULL; \
4645 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004646 timet[0] = ut->atime_s; \
4647 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004648 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 } \
4650
4651
Victor Stinner528a9ab2015-09-03 21:30:26 +02004652#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004653
4654static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004655utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004656{
4657#ifdef HAVE_UTIMENSAT
4658 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4659 UTIME_TO_TIMESPEC;
4660 return utimensat(dir_fd, path, time, flags);
4661#elif defined(HAVE_FUTIMESAT)
4662 UTIME_TO_TIMEVAL;
4663 /*
4664 * follow_symlinks will never be false here;
4665 * we only allow !follow_symlinks and dir_fd together
4666 * if we have utimensat()
4667 */
4668 assert(follow_symlinks);
4669 return futimesat(dir_fd, path, time);
4670#endif
4671}
4672
Larry Hastings2f936352014-08-05 14:04:04 +10004673 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4674#else
4675 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004676#endif
4677
Victor Stinner528a9ab2015-09-03 21:30:26 +02004678#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004679
4680static int
Victor Stinner484df002014-10-09 13:52:31 +02004681utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682{
4683#ifdef HAVE_FUTIMENS
4684 UTIME_TO_TIMESPEC;
4685 return futimens(fd, time);
4686#else
4687 UTIME_TO_TIMEVAL;
4688 return futimes(fd, time);
4689#endif
4690}
4691
Larry Hastings2f936352014-08-05 14:04:04 +10004692 #define PATH_UTIME_HAVE_FD 1
4693#else
4694 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004695#endif
4696
Victor Stinner5ebae872015-09-22 01:29:33 +02004697#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4698# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4699#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004700
Victor Stinner4552ced2015-09-21 22:37:15 +02004701#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702
4703static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004704utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004705{
4706#ifdef HAVE_UTIMENSAT
4707 UTIME_TO_TIMESPEC;
4708 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4709#else
4710 UTIME_TO_TIMEVAL;
4711 return lutimes(path, time);
4712#endif
4713}
4714
4715#endif
4716
4717#ifndef MS_WINDOWS
4718
4719static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004720utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721{
4722#ifdef HAVE_UTIMENSAT
4723 UTIME_TO_TIMESPEC;
4724 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4725#elif defined(HAVE_UTIMES)
4726 UTIME_TO_TIMEVAL;
4727 return utimes(path, time);
4728#elif defined(HAVE_UTIME_H)
4729 UTIME_TO_UTIMBUF;
4730 return utime(path, time);
4731#else
4732 UTIME_TO_TIME_T;
4733 return utime(path, time);
4734#endif
4735}
4736
4737#endif
4738
Larry Hastings76ad59b2012-05-03 00:30:07 -07004739static int
4740split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4741{
4742 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004743 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004744 divmod = PyNumber_Divmod(py_long, billion);
4745 if (!divmod)
4746 goto exit;
4747 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4748 if ((*s == -1) && PyErr_Occurred())
4749 goto exit;
4750 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004751 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004752 goto exit;
4753
4754 result = 1;
4755exit:
4756 Py_XDECREF(divmod);
4757 return result;
4758}
4759
Larry Hastings2f936352014-08-05 14:04:04 +10004760
4761/*[clinic input]
4762os.utime
4763
4764 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4765 times: object = NULL
4766 *
4767 ns: object = NULL
4768 dir_fd: dir_fd(requires='futimensat') = None
4769 follow_symlinks: bool=True
4770
Martin Panter0ff89092015-09-09 01:56:53 +00004771# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004772
4773Set the access and modified time of path.
4774
4775path may always be specified as a string.
4776On some platforms, path may also be specified as an open file descriptor.
4777 If this functionality is unavailable, using it raises an exception.
4778
4779If times is not None, it must be a tuple (atime, mtime);
4780 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004781If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004782 atime_ns and mtime_ns should be expressed as integer nanoseconds
4783 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004784If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004785Specifying tuples for both times and ns is an error.
4786
4787If dir_fd is not None, it should be a file descriptor open to a directory,
4788 and path should be relative; path will then be relative to that directory.
4789If follow_symlinks is False, and the last element of the path is a symbolic
4790 link, utime will modify the symbolic link itself instead of the file the
4791 link points to.
4792It is an error to use dir_fd or follow_symlinks when specifying path
4793 as an open file descriptor.
4794dir_fd and follow_symlinks may not be available on your platform.
4795 If they are unavailable, using them will raise a NotImplementedError.
4796
4797[clinic start generated code]*/
4798
Larry Hastings2f936352014-08-05 14:04:04 +10004799static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004800os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4801 int dir_fd, int follow_symlinks)
4802/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004803{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804#ifdef MS_WINDOWS
4805 HANDLE hFile;
4806 FILETIME atime, mtime;
4807#else
4808 int result;
4809#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004810
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004812 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004813
Christian Heimesb3c87242013-08-01 00:08:16 +02004814 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004815
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816 if (times && (times != Py_None) && ns) {
4817 PyErr_SetString(PyExc_ValueError,
4818 "utime: you may specify either 'times'"
4819 " or 'ns' but not both");
4820 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004821 }
4822
4823 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004824 time_t a_sec, m_sec;
4825 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004826 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827 PyErr_SetString(PyExc_TypeError,
4828 "utime: 'times' must be either"
4829 " a tuple of two ints or None");
4830 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004831 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004832 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004833 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004834 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004835 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004836 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004837 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004838 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004839 utime.atime_s = a_sec;
4840 utime.atime_ns = a_nsec;
4841 utime.mtime_s = m_sec;
4842 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004843 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004845 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004846 PyErr_SetString(PyExc_TypeError,
4847 "utime: 'ns' must be a tuple of two ints");
4848 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004849 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004850 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004851 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004853 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854 &utime.mtime_s, &utime.mtime_ns)) {
4855 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004856 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004857 }
4858 else {
4859 /* times and ns are both None/unspecified. use "now". */
4860 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004861 }
4862
Victor Stinner4552ced2015-09-21 22:37:15 +02004863#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004864 if (follow_symlinks_specified("utime", follow_symlinks))
4865 goto exit;
4866#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004867
Larry Hastings2f936352014-08-05 14:04:04 +10004868 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4869 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4870 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004871 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004872
Larry Hastings9cf065c2012-06-22 16:30:09 -07004873#if !defined(HAVE_UTIMENSAT)
4874 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004875 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004876 "utime: cannot use dir_fd and follow_symlinks "
4877 "together on this platform");
4878 goto exit;
4879 }
4880#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004881
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004882#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004884 if (path->wide)
4885 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 NULL, OPEN_EXISTING,
4887 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004888 else
Larry Hastings2f936352014-08-05 14:04:04 +10004889 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 NULL, OPEN_EXISTING,
4891 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004892 Py_END_ALLOW_THREADS
4893 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004894 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004895 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004896 }
4897
Larry Hastings9cf065c2012-06-22 16:30:09 -07004898 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004899 GetSystemTimeAsFileTime(&mtime);
4900 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004903 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4904 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004905 }
4906 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4907 /* Avoid putting the file name into the error here,
4908 as that may confuse the user into believing that
4909 something is wrong with the file, when it also
4910 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004911 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004912 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004913 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004914#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004915 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004916
Victor Stinner4552ced2015-09-21 22:37:15 +02004917#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004918 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004919 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004920 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004921#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004922
Victor Stinner528a9ab2015-09-03 21:30:26 +02004923#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004924 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004925 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004926 else
4927#endif
4928
Victor Stinner528a9ab2015-09-03 21:30:26 +02004929#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004930 if (path->fd != -1)
4931 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004932 else
4933#endif
4934
Larry Hastings2f936352014-08-05 14:04:04 +10004935 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004936
4937 Py_END_ALLOW_THREADS
4938
4939 if (result < 0) {
4940 /* see previous comment about not putting filename in error here */
4941 return_value = posix_error();
4942 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004943 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004944
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004945#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946
4947 Py_INCREF(Py_None);
4948 return_value = Py_None;
4949
4950exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004951#ifdef MS_WINDOWS
4952 if (hFile != INVALID_HANDLE_VALUE)
4953 CloseHandle(hFile);
4954#endif
4955 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004956}
4957
Guido van Rossum3b066191991-06-04 19:40:25 +00004958/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004959
Larry Hastings2f936352014-08-05 14:04:04 +10004960
4961/*[clinic input]
4962os._exit
4963
4964 status: int
4965
4966Exit to the system with specified status, without normal exit processing.
4967[clinic start generated code]*/
4968
Larry Hastings2f936352014-08-05 14:04:04 +10004969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004970os__exit_impl(PyObject *module, int status)
4971/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004972{
4973 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004975}
4976
Martin v. Löwis114619e2002-10-07 06:44:21 +00004977#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4978static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004979free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004980{
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 Py_ssize_t i;
4982 for (i = 0; i < count; i++)
4983 PyMem_Free(array[i]);
4984 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004985}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004986
Antoine Pitrou69f71142009-05-24 21:25:49 +00004987static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004988int fsconvert_strdup(PyObject *o, char**out)
4989{
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 PyObject *bytes;
4991 Py_ssize_t size;
4992 if (!PyUnicode_FSConverter(o, &bytes))
4993 return 0;
4994 size = PyBytes_GET_SIZE(bytes);
4995 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004996 if (!*out) {
4997 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004998 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004999 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 memcpy(*out, PyBytes_AsString(bytes), size+1);
5001 Py_DECREF(bytes);
5002 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005003}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005004#endif
5005
Ross Lagerwall7807c352011-03-17 20:20:30 +02005006#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005007static char**
5008parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5009{
Victor Stinner8c62be82010-05-06 00:08:46 +00005010 char **envlist;
5011 Py_ssize_t i, pos, envc;
5012 PyObject *keys=NULL, *vals=NULL;
5013 PyObject *key, *val, *key2, *val2;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005014 char *p;
5015 const char *k, *v;
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005017
Victor Stinner8c62be82010-05-06 00:08:46 +00005018 i = PyMapping_Size(env);
5019 if (i < 0)
5020 return NULL;
5021 envlist = PyMem_NEW(char *, i + 1);
5022 if (envlist == NULL) {
5023 PyErr_NoMemory();
5024 return NULL;
5025 }
5026 envc = 0;
5027 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005028 if (!keys)
5029 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005031 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 goto error;
5033 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5034 PyErr_Format(PyExc_TypeError,
5035 "env.keys() or env.values() is not a list");
5036 goto error;
5037 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005038
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 for (pos = 0; pos < i; pos++) {
5040 key = PyList_GetItem(keys, pos);
5041 val = PyList_GetItem(vals, pos);
5042 if (!key || !val)
5043 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005044
Victor Stinner8c62be82010-05-06 00:08:46 +00005045 if (PyUnicode_FSConverter(key, &key2) == 0)
5046 goto error;
5047 if (PyUnicode_FSConverter(val, &val2) == 0) {
5048 Py_DECREF(key2);
5049 goto error;
5050 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005051
Victor Stinner8c62be82010-05-06 00:08:46 +00005052 k = PyBytes_AsString(key2);
5053 v = PyBytes_AsString(val2);
5054 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005055
Victor Stinner8c62be82010-05-06 00:08:46 +00005056 p = PyMem_NEW(char, len);
5057 if (p == NULL) {
5058 PyErr_NoMemory();
5059 Py_DECREF(key2);
5060 Py_DECREF(val2);
5061 goto error;
5062 }
5063 PyOS_snprintf(p, len, "%s=%s", k, v);
5064 envlist[envc++] = p;
5065 Py_DECREF(key2);
5066 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 }
5068 Py_DECREF(vals);
5069 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005070
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 envlist[envc] = 0;
5072 *envc_ptr = envc;
5073 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005074
5075error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005076 Py_XDECREF(keys);
5077 Py_XDECREF(vals);
5078 while (--envc >= 0)
5079 PyMem_DEL(envlist[envc]);
5080 PyMem_DEL(envlist);
5081 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005082}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084static char**
5085parse_arglist(PyObject* argv, Py_ssize_t *argc)
5086{
5087 int i;
5088 char **argvlist = PyMem_NEW(char *, *argc+1);
5089 if (argvlist == NULL) {
5090 PyErr_NoMemory();
5091 return NULL;
5092 }
5093 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005094 PyObject* item = PySequence_ITEM(argv, i);
5095 if (item == NULL)
5096 goto fail;
5097 if (!fsconvert_strdup(item, &argvlist[i])) {
5098 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005099 goto fail;
5100 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005101 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005102 }
5103 argvlist[*argc] = NULL;
5104 return argvlist;
5105fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005106 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005107 free_string_array(argvlist, *argc);
5108 return NULL;
5109}
5110#endif
5111
Larry Hastings2f936352014-08-05 14:04:04 +10005112
Ross Lagerwall7807c352011-03-17 20:20:30 +02005113#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005114/*[clinic input]
5115os.execv
5116
5117 path: FSConverter
5118 Path of executable file.
5119 argv: object
5120 Tuple or list of strings.
5121 /
5122
5123Execute an executable path with arguments, replacing current process.
5124[clinic start generated code]*/
5125
Larry Hastings2f936352014-08-05 14:04:04 +10005126static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005127os_execv_impl(PyObject *module, PyObject *path, PyObject *argv)
5128/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005129{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005130 const char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005131 char **argvlist;
5132 Py_ssize_t argc;
5133
5134 /* execv has two arguments: (path, argv), where
5135 argv is a list or tuple of strings. */
5136
Larry Hastings2f936352014-08-05 14:04:04 +10005137 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005138 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5139 PyErr_SetString(PyExc_TypeError,
5140 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141 return NULL;
5142 }
5143 argc = PySequence_Size(argv);
5144 if (argc < 1) {
5145 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005146 return NULL;
5147 }
5148
5149 argvlist = parse_arglist(argv, &argc);
5150 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005151 return NULL;
5152 }
5153
Larry Hastings2f936352014-08-05 14:04:04 +10005154 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005155
5156 /* If we get here it's definitely an error */
5157
5158 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005159 return posix_error();
5160}
5161
Larry Hastings2f936352014-08-05 14:04:04 +10005162
5163/*[clinic input]
5164os.execve
5165
5166 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5167 Path of executable file.
5168 argv: object
5169 Tuple or list of strings.
5170 env: object
5171 Dictionary of strings mapping to strings.
5172
5173Execute an executable path with arguments, replacing current process.
5174[clinic start generated code]*/
5175
Larry Hastings2f936352014-08-05 14:04:04 +10005176static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005177os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5178/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005179{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005180 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005182 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005183
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 /* execve has three arguments: (path, argv, env), where
5185 argv is a list or tuple of strings and env is a dictionary
5186 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005187
Ross Lagerwall7807c352011-03-17 20:20:30 +02005188 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005190 "execve: argv must be a tuple or list");
5191 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005193 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005194 if (!PyMapping_Check(env)) {
5195 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005196 "execve: environment must be a mapping object");
5197 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005199
Ross Lagerwall7807c352011-03-17 20:20:30 +02005200 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005202 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 envlist = parse_envlist(env, &envc);
5206 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005207 goto fail;
5208
Larry Hastings9cf065c2012-06-22 16:30:09 -07005209#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005210 if (path->fd > -1)
5211 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005212 else
5213#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005214 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005215
5216 /* If we get here it's definitely an error */
5217
Larry Hastings2f936352014-08-05 14:04:04 +10005218 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005219
5220 while (--envc >= 0)
5221 PyMem_DEL(envlist[envc]);
5222 PyMem_DEL(envlist);
5223 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005224 if (argvlist)
5225 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005226 return NULL;
5227}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005228#endif /* HAVE_EXECV */
5229
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005230
Guido van Rossuma1065681999-01-25 23:20:23 +00005231#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005232/*[clinic input]
5233os.spawnv
5234
5235 mode: int
5236 Mode of process creation.
5237 path: FSConverter
5238 Path of executable file.
5239 argv: object
5240 Tuple or list of strings.
5241 /
5242
5243Execute the program specified by path in a new process.
5244[clinic start generated code]*/
5245
Larry Hastings2f936352014-08-05 14:04:04 +10005246static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005247os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv)
5248/*[clinic end generated code: output=c427c0ce40f10638 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005249{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005250 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005252 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005254 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005256
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 /* spawnv has three arguments: (mode, path, argv), where
5258 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005259
Larry Hastings2f936352014-08-05 14:04:04 +10005260 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 if (PyList_Check(argv)) {
5262 argc = PyList_Size(argv);
5263 getitem = PyList_GetItem;
5264 }
5265 else if (PyTuple_Check(argv)) {
5266 argc = PyTuple_Size(argv);
5267 getitem = PyTuple_GetItem;
5268 }
5269 else {
5270 PyErr_SetString(PyExc_TypeError,
5271 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 return NULL;
5273 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005274
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 argvlist = PyMem_NEW(char *, argc+1);
5276 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 return PyErr_NoMemory();
5278 }
5279 for (i = 0; i < argc; i++) {
5280 if (!fsconvert_strdup((*getitem)(argv, i),
5281 &argvlist[i])) {
5282 free_string_array(argvlist, i);
5283 PyErr_SetString(
5284 PyExc_TypeError,
5285 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 return NULL;
5287 }
5288 }
5289 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 if (mode == _OLD_P_OVERLAY)
5292 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005295 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005297
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005299
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 if (spawnval == -1)
5301 return posix_error();
5302 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005303 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005304}
5305
5306
Larry Hastings2f936352014-08-05 14:04:04 +10005307/*[clinic input]
5308os.spawnve
5309
5310 mode: int
5311 Mode of process creation.
5312 path: FSConverter
5313 Path of executable file.
5314 argv: object
5315 Tuple or list of strings.
5316 env: object
5317 Dictionary of strings mapping to strings.
5318 /
5319
5320Execute the program specified by path in a new process.
5321[clinic start generated code]*/
5322
Larry Hastings2f936352014-08-05 14:04:04 +10005323static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005324os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5325 PyObject *env)
5326/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005327{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005328 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005329 char **argvlist;
5330 char **envlist;
5331 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005332 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005333 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5335 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005336
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 /* spawnve has four arguments: (mode, path, argv, env), where
5338 argv is a list or tuple of strings and env is a dictionary
5339 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005340
Larry Hastings2f936352014-08-05 14:04:04 +10005341 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005342 if (PyList_Check(argv)) {
5343 argc = PyList_Size(argv);
5344 getitem = PyList_GetItem;
5345 }
5346 else if (PyTuple_Check(argv)) {
5347 argc = PyTuple_Size(argv);
5348 getitem = PyTuple_GetItem;
5349 }
5350 else {
5351 PyErr_SetString(PyExc_TypeError,
5352 "spawnve() arg 2 must be a tuple or list");
5353 goto fail_0;
5354 }
5355 if (!PyMapping_Check(env)) {
5356 PyErr_SetString(PyExc_TypeError,
5357 "spawnve() arg 3 must be a mapping object");
5358 goto fail_0;
5359 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005360
Victor Stinner8c62be82010-05-06 00:08:46 +00005361 argvlist = PyMem_NEW(char *, argc+1);
5362 if (argvlist == NULL) {
5363 PyErr_NoMemory();
5364 goto fail_0;
5365 }
5366 for (i = 0; i < argc; i++) {
5367 if (!fsconvert_strdup((*getitem)(argv, i),
5368 &argvlist[i]))
5369 {
5370 lastarg = i;
5371 goto fail_1;
5372 }
5373 }
5374 lastarg = argc;
5375 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005376
Victor Stinner8c62be82010-05-06 00:08:46 +00005377 envlist = parse_envlist(env, &envc);
5378 if (envlist == NULL)
5379 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005380
Victor Stinner8c62be82010-05-06 00:08:46 +00005381 if (mode == _OLD_P_OVERLAY)
5382 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005383
Victor Stinner8c62be82010-05-06 00:08:46 +00005384 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005385 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005386 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005387
Victor Stinner8c62be82010-05-06 00:08:46 +00005388 if (spawnval == -1)
5389 (void) posix_error();
5390 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005391 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005392
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 while (--envc >= 0)
5394 PyMem_DEL(envlist[envc]);
5395 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005396 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005397 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005398 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005400}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005401
Guido van Rossuma1065681999-01-25 23:20:23 +00005402#endif /* HAVE_SPAWNV */
5403
5404
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005405#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005406/*[clinic input]
5407os.fork1
5408
5409Fork a child process with a single multiplexed (i.e., not bound) thread.
5410
5411Return 0 to child process and PID of child to parent process.
5412[clinic start generated code]*/
5413
Larry Hastings2f936352014-08-05 14:04:04 +10005414static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005415os_fork1_impl(PyObject *module)
5416/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005417{
Victor Stinner8c62be82010-05-06 00:08:46 +00005418 pid_t pid;
5419 int result = 0;
5420 _PyImport_AcquireLock();
5421 pid = fork1();
5422 if (pid == 0) {
5423 /* child: this clobbers and resets the import lock. */
5424 PyOS_AfterFork();
5425 } else {
5426 /* parent: release the import lock. */
5427 result = _PyImport_ReleaseLock();
5428 }
5429 if (pid == -1)
5430 return posix_error();
5431 if (result < 0) {
5432 /* Don't clobber the OSError if the fork failed. */
5433 PyErr_SetString(PyExc_RuntimeError,
5434 "not holding the import lock");
5435 return NULL;
5436 }
5437 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005438}
Larry Hastings2f936352014-08-05 14:04:04 +10005439#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005440
5441
Guido van Rossumad0ee831995-03-01 10:34:45 +00005442#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005443/*[clinic input]
5444os.fork
5445
5446Fork a child process.
5447
5448Return 0 to child process and PID of child to parent process.
5449[clinic start generated code]*/
5450
Larry Hastings2f936352014-08-05 14:04:04 +10005451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005452os_fork_impl(PyObject *module)
5453/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005454{
Victor Stinner8c62be82010-05-06 00:08:46 +00005455 pid_t pid;
5456 int result = 0;
5457 _PyImport_AcquireLock();
5458 pid = fork();
5459 if (pid == 0) {
5460 /* child: this clobbers and resets the import lock. */
5461 PyOS_AfterFork();
5462 } else {
5463 /* parent: release the import lock. */
5464 result = _PyImport_ReleaseLock();
5465 }
5466 if (pid == -1)
5467 return posix_error();
5468 if (result < 0) {
5469 /* Don't clobber the OSError if the fork failed. */
5470 PyErr_SetString(PyExc_RuntimeError,
5471 "not holding the import lock");
5472 return NULL;
5473 }
5474 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005475}
Larry Hastings2f936352014-08-05 14:04:04 +10005476#endif /* HAVE_FORK */
5477
Guido van Rossum85e3b011991-06-03 12:42:10 +00005478
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005479#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005480#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005481/*[clinic input]
5482os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005483
Larry Hastings2f936352014-08-05 14:04:04 +10005484 policy: int
5485
5486Get the maximum scheduling priority for policy.
5487[clinic start generated code]*/
5488
Larry Hastings2f936352014-08-05 14:04:04 +10005489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005490os_sched_get_priority_max_impl(PyObject *module, int policy)
5491/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005492{
5493 int max;
5494
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005495 max = sched_get_priority_max(policy);
5496 if (max < 0)
5497 return posix_error();
5498 return PyLong_FromLong(max);
5499}
5500
Larry Hastings2f936352014-08-05 14:04:04 +10005501
5502/*[clinic input]
5503os.sched_get_priority_min
5504
5505 policy: int
5506
5507Get the minimum scheduling priority for policy.
5508[clinic start generated code]*/
5509
Larry Hastings2f936352014-08-05 14:04:04 +10005510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005511os_sched_get_priority_min_impl(PyObject *module, int policy)
5512/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005513{
5514 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005515 if (min < 0)
5516 return posix_error();
5517 return PyLong_FromLong(min);
5518}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005519#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5520
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005521
Larry Hastings2f936352014-08-05 14:04:04 +10005522#ifdef HAVE_SCHED_SETSCHEDULER
5523/*[clinic input]
5524os.sched_getscheduler
5525 pid: pid_t
5526 /
5527
5528Get the scheduling policy for the process identifiedy by pid.
5529
5530Passing 0 for pid returns the scheduling policy for the calling process.
5531[clinic start generated code]*/
5532
Larry Hastings2f936352014-08-05 14:04:04 +10005533static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005534os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5535/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005536{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005537 int policy;
5538
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005539 policy = sched_getscheduler(pid);
5540 if (policy < 0)
5541 return posix_error();
5542 return PyLong_FromLong(policy);
5543}
Larry Hastings2f936352014-08-05 14:04:04 +10005544#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005545
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005546
5547#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005548/*[clinic input]
5549class os.sched_param "PyObject *" "&SchedParamType"
5550
5551@classmethod
5552os.sched_param.__new__
5553
5554 sched_priority: object
5555 A scheduling parameter.
5556
5557Current has only one field: sched_priority");
5558[clinic start generated code]*/
5559
Larry Hastings2f936352014-08-05 14:04:04 +10005560static PyObject *
5561os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005562/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005563{
5564 PyObject *res;
5565
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005566 res = PyStructSequence_New(type);
5567 if (!res)
5568 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005569 Py_INCREF(sched_priority);
5570 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571 return res;
5572}
5573
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005574
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005575PyDoc_VAR(os_sched_param__doc__);
5576
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005577static PyStructSequence_Field sched_param_fields[] = {
5578 {"sched_priority", "the scheduling priority"},
5579 {0}
5580};
5581
5582static PyStructSequence_Desc sched_param_desc = {
5583 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005584 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005585 sched_param_fields,
5586 1
5587};
5588
5589static int
5590convert_sched_param(PyObject *param, struct sched_param *res)
5591{
5592 long priority;
5593
5594 if (Py_TYPE(param) != &SchedParamType) {
5595 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5596 return 0;
5597 }
5598 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5599 if (priority == -1 && PyErr_Occurred())
5600 return 0;
5601 if (priority > INT_MAX || priority < INT_MIN) {
5602 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5603 return 0;
5604 }
5605 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5606 return 1;
5607}
Larry Hastings2f936352014-08-05 14:04:04 +10005608#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005609
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005610
5611#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005612/*[clinic input]
5613os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005614
Larry Hastings2f936352014-08-05 14:04:04 +10005615 pid: pid_t
5616 policy: int
5617 param: sched_param
5618 /
5619
5620Set the scheduling policy for the process identified by pid.
5621
5622If pid is 0, the calling process is changed.
5623param is an instance of sched_param.
5624[clinic start generated code]*/
5625
Larry Hastings2f936352014-08-05 14:04:04 +10005626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005627os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005628 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005629/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005630{
Jesus Cea9c822272011-09-10 01:40:52 +02005631 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005632 ** sched_setscheduler() returns 0 in Linux, but the previous
5633 ** scheduling policy under Solaris/Illumos, and others.
5634 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005635 */
Larry Hastings2f936352014-08-05 14:04:04 +10005636 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637 return posix_error();
5638 Py_RETURN_NONE;
5639}
Larry Hastings2f936352014-08-05 14:04:04 +10005640#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005641
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005642
5643#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005644/*[clinic input]
5645os.sched_getparam
5646 pid: pid_t
5647 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005648
Larry Hastings2f936352014-08-05 14:04:04 +10005649Returns scheduling parameters for the process identified by pid.
5650
5651If pid is 0, returns parameters for the calling process.
5652Return value is an instance of sched_param.
5653[clinic start generated code]*/
5654
Larry Hastings2f936352014-08-05 14:04:04 +10005655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005656os_sched_getparam_impl(PyObject *module, pid_t pid)
5657/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005658{
5659 struct sched_param param;
5660 PyObject *result;
5661 PyObject *priority;
5662
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005663 if (sched_getparam(pid, &param))
5664 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005665 result = PyStructSequence_New(&SchedParamType);
5666 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005667 return NULL;
5668 priority = PyLong_FromLong(param.sched_priority);
5669 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005670 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005671 return NULL;
5672 }
Larry Hastings2f936352014-08-05 14:04:04 +10005673 PyStructSequence_SET_ITEM(result, 0, priority);
5674 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005675}
5676
Larry Hastings2f936352014-08-05 14:04:04 +10005677
5678/*[clinic input]
5679os.sched_setparam
5680 pid: pid_t
5681 param: sched_param
5682 /
5683
5684Set scheduling parameters for the process identified by pid.
5685
5686If pid is 0, sets parameters for the calling process.
5687param should be an instance of sched_param.
5688[clinic start generated code]*/
5689
Larry Hastings2f936352014-08-05 14:04:04 +10005690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005691os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005692 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005693/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005694{
5695 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005696 return posix_error();
5697 Py_RETURN_NONE;
5698}
Larry Hastings2f936352014-08-05 14:04:04 +10005699#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005700
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005701
5702#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005703/*[clinic input]
5704os.sched_rr_get_interval -> double
5705 pid: pid_t
5706 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005707
Larry Hastings2f936352014-08-05 14:04:04 +10005708Return the round-robin quantum for the process identified by pid, in seconds.
5709
5710Value returned is a float.
5711[clinic start generated code]*/
5712
Larry Hastings2f936352014-08-05 14:04:04 +10005713static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005714os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5715/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005716{
5717 struct timespec interval;
5718 if (sched_rr_get_interval(pid, &interval)) {
5719 posix_error();
5720 return -1.0;
5721 }
5722 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5723}
5724#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005725
Larry Hastings2f936352014-08-05 14:04:04 +10005726
5727/*[clinic input]
5728os.sched_yield
5729
5730Voluntarily relinquish the CPU.
5731[clinic start generated code]*/
5732
Larry Hastings2f936352014-08-05 14:04:04 +10005733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005734os_sched_yield_impl(PyObject *module)
5735/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005736{
5737 if (sched_yield())
5738 return posix_error();
5739 Py_RETURN_NONE;
5740}
5741
Benjamin Peterson2740af82011-08-02 17:41:34 -05005742#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005743/* The minimum number of CPUs allocated in a cpu_set_t */
5744static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005745
Larry Hastings2f936352014-08-05 14:04:04 +10005746/*[clinic input]
5747os.sched_setaffinity
5748 pid: pid_t
5749 mask : object
5750 /
5751
5752Set the CPU affinity of the process identified by pid to mask.
5753
5754mask should be an iterable of integers identifying CPUs.
5755[clinic start generated code]*/
5756
Larry Hastings2f936352014-08-05 14:04:04 +10005757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005758os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5759/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005760{
Antoine Pitrou84869872012-08-04 16:16:35 +02005761 int ncpus;
5762 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005763 cpu_set_t *cpu_set = NULL;
5764 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005765
Larry Hastings2f936352014-08-05 14:04:04 +10005766 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005767 if (iterator == NULL)
5768 return NULL;
5769
5770 ncpus = NCPUS_START;
5771 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005772 cpu_set = CPU_ALLOC(ncpus);
5773 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005774 PyErr_NoMemory();
5775 goto error;
5776 }
Larry Hastings2f936352014-08-05 14:04:04 +10005777 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005778
5779 while ((item = PyIter_Next(iterator))) {
5780 long cpu;
5781 if (!PyLong_Check(item)) {
5782 PyErr_Format(PyExc_TypeError,
5783 "expected an iterator of ints, "
5784 "but iterator yielded %R",
5785 Py_TYPE(item));
5786 Py_DECREF(item);
5787 goto error;
5788 }
5789 cpu = PyLong_AsLong(item);
5790 Py_DECREF(item);
5791 if (cpu < 0) {
5792 if (!PyErr_Occurred())
5793 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5794 goto error;
5795 }
5796 if (cpu > INT_MAX - 1) {
5797 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5798 goto error;
5799 }
5800 if (cpu >= ncpus) {
5801 /* Grow CPU mask to fit the CPU number */
5802 int newncpus = ncpus;
5803 cpu_set_t *newmask;
5804 size_t newsetsize;
5805 while (newncpus <= cpu) {
5806 if (newncpus > INT_MAX / 2)
5807 newncpus = cpu + 1;
5808 else
5809 newncpus = newncpus * 2;
5810 }
5811 newmask = CPU_ALLOC(newncpus);
5812 if (newmask == NULL) {
5813 PyErr_NoMemory();
5814 goto error;
5815 }
5816 newsetsize = CPU_ALLOC_SIZE(newncpus);
5817 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005818 memcpy(newmask, cpu_set, setsize);
5819 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005820 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005821 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005822 ncpus = newncpus;
5823 }
Larry Hastings2f936352014-08-05 14:04:04 +10005824 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005825 }
5826 Py_CLEAR(iterator);
5827
Larry Hastings2f936352014-08-05 14:04:04 +10005828 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005829 posix_error();
5830 goto error;
5831 }
Larry Hastings2f936352014-08-05 14:04:04 +10005832 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005833 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005834
5835error:
Larry Hastings2f936352014-08-05 14:04:04 +10005836 if (cpu_set)
5837 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005838 Py_XDECREF(iterator);
5839 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005840}
5841
Larry Hastings2f936352014-08-05 14:04:04 +10005842
5843/*[clinic input]
5844os.sched_getaffinity
5845 pid: pid_t
5846 /
5847
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005848Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005849
5850The affinity is returned as a set of CPU identifiers.
5851[clinic start generated code]*/
5852
Larry Hastings2f936352014-08-05 14:04:04 +10005853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005854os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005855/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005856{
Antoine Pitrou84869872012-08-04 16:16:35 +02005857 int cpu, ncpus, count;
5858 size_t setsize;
5859 cpu_set_t *mask = NULL;
5860 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005861
Antoine Pitrou84869872012-08-04 16:16:35 +02005862 ncpus = NCPUS_START;
5863 while (1) {
5864 setsize = CPU_ALLOC_SIZE(ncpus);
5865 mask = CPU_ALLOC(ncpus);
5866 if (mask == NULL)
5867 return PyErr_NoMemory();
5868 if (sched_getaffinity(pid, setsize, mask) == 0)
5869 break;
5870 CPU_FREE(mask);
5871 if (errno != EINVAL)
5872 return posix_error();
5873 if (ncpus > INT_MAX / 2) {
5874 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5875 "a large enough CPU set");
5876 return NULL;
5877 }
5878 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005879 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005880
5881 res = PySet_New(NULL);
5882 if (res == NULL)
5883 goto error;
5884 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5885 if (CPU_ISSET_S(cpu, setsize, mask)) {
5886 PyObject *cpu_num = PyLong_FromLong(cpu);
5887 --count;
5888 if (cpu_num == NULL)
5889 goto error;
5890 if (PySet_Add(res, cpu_num)) {
5891 Py_DECREF(cpu_num);
5892 goto error;
5893 }
5894 Py_DECREF(cpu_num);
5895 }
5896 }
5897 CPU_FREE(mask);
5898 return res;
5899
5900error:
5901 if (mask)
5902 CPU_FREE(mask);
5903 Py_XDECREF(res);
5904 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005905}
5906
Benjamin Peterson2740af82011-08-02 17:41:34 -05005907#endif /* HAVE_SCHED_SETAFFINITY */
5908
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005909#endif /* HAVE_SCHED_H */
5910
Larry Hastings2f936352014-08-05 14:04:04 +10005911
Neal Norwitzb59798b2003-03-21 01:43:31 +00005912/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005913/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5914#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005915#define DEV_PTY_FILE "/dev/ptc"
5916#define HAVE_DEV_PTMX
5917#else
5918#define DEV_PTY_FILE "/dev/ptmx"
5919#endif
5920
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005921#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005922#ifdef HAVE_PTY_H
5923#include <pty.h>
5924#else
5925#ifdef HAVE_LIBUTIL_H
5926#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005927#else
5928#ifdef HAVE_UTIL_H
5929#include <util.h>
5930#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005931#endif /* HAVE_LIBUTIL_H */
5932#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005933#ifdef HAVE_STROPTS_H
5934#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005935#endif
5936#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005937
Larry Hastings2f936352014-08-05 14:04:04 +10005938
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005939#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005940/*[clinic input]
5941os.openpty
5942
5943Open a pseudo-terminal.
5944
5945Return a tuple of (master_fd, slave_fd) containing open file descriptors
5946for both the master and slave ends.
5947[clinic start generated code]*/
5948
Larry Hastings2f936352014-08-05 14:04:04 +10005949static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005950os_openpty_impl(PyObject *module)
5951/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005952{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005954#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005956#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005957#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005959#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005961#endif
5962#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005963
Thomas Wouters70c21a12000-07-14 14:28:33 +00005964#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005966 goto posix_error;
5967
5968 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5969 goto error;
5970 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5971 goto error;
5972
Neal Norwitzb59798b2003-03-21 01:43:31 +00005973#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5975 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005976 goto posix_error;
5977 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5978 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005979
Victor Stinnerdaf45552013-08-28 00:53:59 +02005980 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005982 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005983
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005984#else
Victor Stinner000de532013-11-25 23:19:58 +01005985 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005987 goto posix_error;
5988
Victor Stinner8c62be82010-05-06 00:08:46 +00005989 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005990
Victor Stinner8c62be82010-05-06 00:08:46 +00005991 /* change permission of slave */
5992 if (grantpt(master_fd) < 0) {
5993 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005994 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005996
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 /* unlock slave */
5998 if (unlockpt(master_fd) < 0) {
5999 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006000 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006002
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006004
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 slave_name = ptsname(master_fd); /* get name of slave */
6006 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006007 goto posix_error;
6008
6009 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006010 if (slave_fd == -1)
6011 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006012
6013 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6014 goto posix_error;
6015
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006016#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6018 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006019#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006021#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006022#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006023#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006024
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006026
Victor Stinnerdaf45552013-08-28 00:53:59 +02006027posix_error:
6028 posix_error();
6029error:
6030 if (master_fd != -1)
6031 close(master_fd);
6032 if (slave_fd != -1)
6033 close(slave_fd);
6034 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006035}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006036#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006037
Larry Hastings2f936352014-08-05 14:04:04 +10006038
Fred Drake8cef4cf2000-06-28 16:40:38 +00006039#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006040/*[clinic input]
6041os.forkpty
6042
6043Fork a new process with a new pseudo-terminal as controlling tty.
6044
6045Returns a tuple of (pid, master_fd).
6046Like fork(), return pid of 0 to the child process,
6047and pid of child to the parent process.
6048To both, return fd of newly opened pseudo-terminal.
6049[clinic start generated code]*/
6050
Larry Hastings2f936352014-08-05 14:04:04 +10006051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006052os_forkpty_impl(PyObject *module)
6053/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006054{
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 int master_fd = -1, result = 0;
6056 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006057
Victor Stinner8c62be82010-05-06 00:08:46 +00006058 _PyImport_AcquireLock();
6059 pid = forkpty(&master_fd, NULL, NULL, NULL);
6060 if (pid == 0) {
6061 /* child: this clobbers and resets the import lock. */
6062 PyOS_AfterFork();
6063 } else {
6064 /* parent: release the import lock. */
6065 result = _PyImport_ReleaseLock();
6066 }
6067 if (pid == -1)
6068 return posix_error();
6069 if (result < 0) {
6070 /* Don't clobber the OSError if the fork failed. */
6071 PyErr_SetString(PyExc_RuntimeError,
6072 "not holding the import lock");
6073 return NULL;
6074 }
6075 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006076}
Larry Hastings2f936352014-08-05 14:04:04 +10006077#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006078
Ross Lagerwall7807c352011-03-17 20:20:30 +02006079
Guido van Rossumad0ee831995-03-01 10:34:45 +00006080#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006081/*[clinic input]
6082os.getegid
6083
6084Return the current process's effective group id.
6085[clinic start generated code]*/
6086
Larry Hastings2f936352014-08-05 14:04:04 +10006087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006088os_getegid_impl(PyObject *module)
6089/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006090{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006091 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006092}
Larry Hastings2f936352014-08-05 14:04:04 +10006093#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006095
Guido van Rossumad0ee831995-03-01 10:34:45 +00006096#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006097/*[clinic input]
6098os.geteuid
6099
6100Return the current process's effective user id.
6101[clinic start generated code]*/
6102
Larry Hastings2f936352014-08-05 14:04:04 +10006103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006104os_geteuid_impl(PyObject *module)
6105/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006106{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006107 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006108}
Larry Hastings2f936352014-08-05 14:04:04 +10006109#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006111
Guido van Rossumad0ee831995-03-01 10:34:45 +00006112#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006113/*[clinic input]
6114os.getgid
6115
6116Return the current process's group id.
6117[clinic start generated code]*/
6118
Larry Hastings2f936352014-08-05 14:04:04 +10006119static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006120os_getgid_impl(PyObject *module)
6121/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006122{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006123 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006124}
Larry Hastings2f936352014-08-05 14:04:04 +10006125#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006127
Larry Hastings2f936352014-08-05 14:04:04 +10006128/*[clinic input]
6129os.getpid
6130
6131Return the current process id.
6132[clinic start generated code]*/
6133
Larry Hastings2f936352014-08-05 14:04:04 +10006134static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006135os_getpid_impl(PyObject *module)
6136/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006137{
Victor Stinner8c62be82010-05-06 00:08:46 +00006138 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006139}
6140
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006141#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006142
6143/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006144PyDoc_STRVAR(posix_getgrouplist__doc__,
6145"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6146Returns a list of groups to which a user belongs.\n\n\
6147 user: username to lookup\n\
6148 group: base group id of the user");
6149
6150static PyObject *
6151posix_getgrouplist(PyObject *self, PyObject *args)
6152{
6153#ifdef NGROUPS_MAX
6154#define MAX_GROUPS NGROUPS_MAX
6155#else
6156 /* defined to be 16 on Solaris7, so this should be a small number */
6157#define MAX_GROUPS 64
6158#endif
6159
6160 const char *user;
6161 int i, ngroups;
6162 PyObject *list;
6163#ifdef __APPLE__
6164 int *groups, basegid;
6165#else
6166 gid_t *groups, basegid;
6167#endif
6168 ngroups = MAX_GROUPS;
6169
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006170#ifdef __APPLE__
6171 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006172 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006173#else
6174 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6175 _Py_Gid_Converter, &basegid))
6176 return NULL;
6177#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006178
6179#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006180 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006181#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006182 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006183#endif
6184 if (groups == NULL)
6185 return PyErr_NoMemory();
6186
6187 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6188 PyMem_Del(groups);
6189 return posix_error();
6190 }
6191
6192 list = PyList_New(ngroups);
6193 if (list == NULL) {
6194 PyMem_Del(groups);
6195 return NULL;
6196 }
6197
6198 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006199#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006200 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006201#else
6202 PyObject *o = _PyLong_FromGid(groups[i]);
6203#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006204 if (o == NULL) {
6205 Py_DECREF(list);
6206 PyMem_Del(groups);
6207 return NULL;
6208 }
6209 PyList_SET_ITEM(list, i, o);
6210 }
6211
6212 PyMem_Del(groups);
6213
6214 return list;
6215}
Larry Hastings2f936352014-08-05 14:04:04 +10006216#endif /* HAVE_GETGROUPLIST */
6217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006218
Fred Drakec9680921999-12-13 16:37:25 +00006219#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006220/*[clinic input]
6221os.getgroups
6222
6223Return list of supplemental group IDs for the process.
6224[clinic start generated code]*/
6225
Larry Hastings2f936352014-08-05 14:04:04 +10006226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006227os_getgroups_impl(PyObject *module)
6228/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006229{
6230 PyObject *result = NULL;
6231
Fred Drakec9680921999-12-13 16:37:25 +00006232#ifdef NGROUPS_MAX
6233#define MAX_GROUPS NGROUPS_MAX
6234#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006236#define MAX_GROUPS 64
6237#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006239
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006240 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006241 * This is a helper variable to store the intermediate result when
6242 * that happens.
6243 *
6244 * To keep the code readable the OSX behaviour is unconditional,
6245 * according to the POSIX spec this should be safe on all unix-y
6246 * systems.
6247 */
6248 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006249 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006250
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006251#ifdef __APPLE__
6252 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6253 * there are more groups than can fit in grouplist. Therefore, on OS X
6254 * always first call getgroups with length 0 to get the actual number
6255 * of groups.
6256 */
6257 n = getgroups(0, NULL);
6258 if (n < 0) {
6259 return posix_error();
6260 } else if (n <= MAX_GROUPS) {
6261 /* groups will fit in existing array */
6262 alt_grouplist = grouplist;
6263 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006264 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006265 if (alt_grouplist == NULL) {
6266 errno = EINVAL;
6267 return posix_error();
6268 }
6269 }
6270
6271 n = getgroups(n, alt_grouplist);
6272 if (n == -1) {
6273 if (alt_grouplist != grouplist) {
6274 PyMem_Free(alt_grouplist);
6275 }
6276 return posix_error();
6277 }
6278#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006280 if (n < 0) {
6281 if (errno == EINVAL) {
6282 n = getgroups(0, NULL);
6283 if (n == -1) {
6284 return posix_error();
6285 }
6286 if (n == 0) {
6287 /* Avoid malloc(0) */
6288 alt_grouplist = grouplist;
6289 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006290 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006291 if (alt_grouplist == NULL) {
6292 errno = EINVAL;
6293 return posix_error();
6294 }
6295 n = getgroups(n, alt_grouplist);
6296 if (n == -1) {
6297 PyMem_Free(alt_grouplist);
6298 return posix_error();
6299 }
6300 }
6301 } else {
6302 return posix_error();
6303 }
6304 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006305#endif
6306
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006307 result = PyList_New(n);
6308 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 int i;
6310 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006311 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006312 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006313 Py_DECREF(result);
6314 result = NULL;
6315 break;
Fred Drakec9680921999-12-13 16:37:25 +00006316 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006317 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006318 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006319 }
6320
6321 if (alt_grouplist != grouplist) {
6322 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006324
Fred Drakec9680921999-12-13 16:37:25 +00006325 return result;
6326}
Larry Hastings2f936352014-08-05 14:04:04 +10006327#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006328
Antoine Pitroub7572f02009-12-02 20:46:48 +00006329#ifdef HAVE_INITGROUPS
6330PyDoc_STRVAR(posix_initgroups__doc__,
6331"initgroups(username, gid) -> None\n\n\
6332Call the system initgroups() to initialize the group access list with all of\n\
6333the groups of which the specified username is a member, plus the specified\n\
6334group id.");
6335
Larry Hastings2f936352014-08-05 14:04:04 +10006336/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006337static PyObject *
6338posix_initgroups(PyObject *self, PyObject *args)
6339{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006340 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006341 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006342 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006343#ifdef __APPLE__
6344 int gid;
6345#else
6346 gid_t gid;
6347#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006348
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006349#ifdef __APPLE__
6350 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6351 PyUnicode_FSConverter, &oname,
6352 &gid))
6353#else
6354 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6355 PyUnicode_FSConverter, &oname,
6356 _Py_Gid_Converter, &gid))
6357#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006359 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006360
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006361 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006362 Py_DECREF(oname);
6363 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006365
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 Py_INCREF(Py_None);
6367 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006368}
Larry Hastings2f936352014-08-05 14:04:04 +10006369#endif /* HAVE_INITGROUPS */
6370
Antoine Pitroub7572f02009-12-02 20:46:48 +00006371
Martin v. Löwis606edc12002-06-13 21:09:11 +00006372#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006373/*[clinic input]
6374os.getpgid
6375
6376 pid: pid_t
6377
6378Call the system call getpgid(), and return the result.
6379[clinic start generated code]*/
6380
Larry Hastings2f936352014-08-05 14:04:04 +10006381static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006382os_getpgid_impl(PyObject *module, pid_t pid)
6383/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006384{
6385 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 if (pgid < 0)
6387 return posix_error();
6388 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006389}
6390#endif /* HAVE_GETPGID */
6391
6392
Guido van Rossumb6775db1994-08-01 11:34:53 +00006393#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006394/*[clinic input]
6395os.getpgrp
6396
6397Return the current process group id.
6398[clinic start generated code]*/
6399
Larry Hastings2f936352014-08-05 14:04:04 +10006400static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006401os_getpgrp_impl(PyObject *module)
6402/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006403{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006406#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006408#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006409}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006410#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006412
Guido van Rossumb6775db1994-08-01 11:34:53 +00006413#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006414/*[clinic input]
6415os.setpgrp
6416
6417Make the current process the leader of its process group.
6418[clinic start generated code]*/
6419
Larry Hastings2f936352014-08-05 14:04:04 +10006420static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006421os_setpgrp_impl(PyObject *module)
6422/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006423{
Guido van Rossum64933891994-10-20 21:56:42 +00006424#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006426#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006428#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 return posix_error();
6430 Py_INCREF(Py_None);
6431 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006432}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006433#endif /* HAVE_SETPGRP */
6434
Guido van Rossumad0ee831995-03-01 10:34:45 +00006435#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006436
6437#ifdef MS_WINDOWS
6438#include <tlhelp32.h>
6439
6440static PyObject*
6441win32_getppid()
6442{
6443 HANDLE snapshot;
6444 pid_t mypid;
6445 PyObject* result = NULL;
6446 BOOL have_record;
6447 PROCESSENTRY32 pe;
6448
6449 mypid = getpid(); /* This function never fails */
6450
6451 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6452 if (snapshot == INVALID_HANDLE_VALUE)
6453 return PyErr_SetFromWindowsErr(GetLastError());
6454
6455 pe.dwSize = sizeof(pe);
6456 have_record = Process32First(snapshot, &pe);
6457 while (have_record) {
6458 if (mypid == (pid_t)pe.th32ProcessID) {
6459 /* We could cache the ulong value in a static variable. */
6460 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6461 break;
6462 }
6463
6464 have_record = Process32Next(snapshot, &pe);
6465 }
6466
6467 /* If our loop exits and our pid was not found (result will be NULL)
6468 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6469 * error anyway, so let's raise it. */
6470 if (!result)
6471 result = PyErr_SetFromWindowsErr(GetLastError());
6472
6473 CloseHandle(snapshot);
6474
6475 return result;
6476}
6477#endif /*MS_WINDOWS*/
6478
Larry Hastings2f936352014-08-05 14:04:04 +10006479
6480/*[clinic input]
6481os.getppid
6482
6483Return the parent's process id.
6484
6485If the parent process has already exited, Windows machines will still
6486return its id; others systems will return the id of the 'init' process (1).
6487[clinic start generated code]*/
6488
Larry Hastings2f936352014-08-05 14:04:04 +10006489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006490os_getppid_impl(PyObject *module)
6491/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006492{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006493#ifdef MS_WINDOWS
6494 return win32_getppid();
6495#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006497#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006498}
6499#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006501
Fred Drake12c6e2d1999-12-14 21:25:03 +00006502#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006503/*[clinic input]
6504os.getlogin
6505
6506Return the actual login name.
6507[clinic start generated code]*/
6508
Larry Hastings2f936352014-08-05 14:04:04 +10006509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006510os_getlogin_impl(PyObject *module)
6511/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006512{
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006514#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006515 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006516 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006517
6518 if (GetUserNameW(user_name, &num_chars)) {
6519 /* num_chars is the number of unicode chars plus null terminator */
6520 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006521 }
6522 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006523 result = PyErr_SetFromWindowsErr(GetLastError());
6524#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006525 char *name;
6526 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006527
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 errno = 0;
6529 name = getlogin();
6530 if (name == NULL) {
6531 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006532 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006533 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006534 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 }
6536 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006537 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006539#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006540 return result;
6541}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006542#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006543
Larry Hastings2f936352014-08-05 14:04:04 +10006544
Guido van Rossumad0ee831995-03-01 10:34:45 +00006545#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006546/*[clinic input]
6547os.getuid
6548
6549Return the current process's user id.
6550[clinic start generated code]*/
6551
Larry Hastings2f936352014-08-05 14:04:04 +10006552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006553os_getuid_impl(PyObject *module)
6554/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006555{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006556 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006557}
Larry Hastings2f936352014-08-05 14:04:04 +10006558#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006560
Brian Curtineb24d742010-04-12 17:16:38 +00006561#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006562#define HAVE_KILL
6563#endif /* MS_WINDOWS */
6564
6565#ifdef HAVE_KILL
6566/*[clinic input]
6567os.kill
6568
6569 pid: pid_t
6570 signal: Py_ssize_t
6571 /
6572
6573Kill a process with a signal.
6574[clinic start generated code]*/
6575
Larry Hastings2f936352014-08-05 14:04:04 +10006576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006577os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6578/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006579#ifndef MS_WINDOWS
6580{
6581 if (kill(pid, (int)signal) == -1)
6582 return posix_error();
6583 Py_RETURN_NONE;
6584}
6585#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006586{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006587 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006588 DWORD sig = (DWORD)signal;
6589 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006591
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 /* Console processes which share a common console can be sent CTRL+C or
6593 CTRL+BREAK events, provided they handle said events. */
6594 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006595 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 err = GetLastError();
6597 PyErr_SetFromWindowsErr(err);
6598 }
6599 else
6600 Py_RETURN_NONE;
6601 }
Brian Curtineb24d742010-04-12 17:16:38 +00006602
Victor Stinner8c62be82010-05-06 00:08:46 +00006603 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6604 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006605 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006606 if (handle == NULL) {
6607 err = GetLastError();
6608 return PyErr_SetFromWindowsErr(err);
6609 }
Brian Curtineb24d742010-04-12 17:16:38 +00006610
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 if (TerminateProcess(handle, sig) == 0) {
6612 err = GetLastError();
6613 result = PyErr_SetFromWindowsErr(err);
6614 } else {
6615 Py_INCREF(Py_None);
6616 result = Py_None;
6617 }
Brian Curtineb24d742010-04-12 17:16:38 +00006618
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 CloseHandle(handle);
6620 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006621}
Larry Hastings2f936352014-08-05 14:04:04 +10006622#endif /* !MS_WINDOWS */
6623#endif /* HAVE_KILL */
6624
6625
6626#ifdef HAVE_KILLPG
6627/*[clinic input]
6628os.killpg
6629
6630 pgid: pid_t
6631 signal: int
6632 /
6633
6634Kill a process group with a signal.
6635[clinic start generated code]*/
6636
Larry Hastings2f936352014-08-05 14:04:04 +10006637static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006638os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6639/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006640{
6641 /* XXX some man pages make the `pgid` parameter an int, others
6642 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6643 take the same type. Moreover, pid_t is always at least as wide as
6644 int (else compilation of this module fails), which is safe. */
6645 if (killpg(pgid, signal) == -1)
6646 return posix_error();
6647 Py_RETURN_NONE;
6648}
6649#endif /* HAVE_KILLPG */
6650
Brian Curtineb24d742010-04-12 17:16:38 +00006651
Guido van Rossumc0125471996-06-28 18:55:32 +00006652#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006653#ifdef HAVE_SYS_LOCK_H
6654#include <sys/lock.h>
6655#endif
6656
Larry Hastings2f936352014-08-05 14:04:04 +10006657/*[clinic input]
6658os.plock
6659 op: int
6660 /
6661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006662Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006663[clinic start generated code]*/
6664
Larry Hastings2f936352014-08-05 14:04:04 +10006665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006666os_plock_impl(PyObject *module, int op)
6667/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006668{
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 if (plock(op) == -1)
6670 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006671 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006672}
Larry Hastings2f936352014-08-05 14:04:04 +10006673#endif /* HAVE_PLOCK */
6674
Guido van Rossumc0125471996-06-28 18:55:32 +00006675
Guido van Rossumb6775db1994-08-01 11:34:53 +00006676#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006677/*[clinic input]
6678os.setuid
6679
6680 uid: uid_t
6681 /
6682
6683Set the current process's user id.
6684[clinic start generated code]*/
6685
Larry Hastings2f936352014-08-05 14:04:04 +10006686static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006687os_setuid_impl(PyObject *module, uid_t uid)
6688/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006689{
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 if (setuid(uid) < 0)
6691 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006692 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006693}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006694#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006696
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006697#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006698/*[clinic input]
6699os.seteuid
6700
6701 euid: uid_t
6702 /
6703
6704Set the current process's effective user id.
6705[clinic start generated code]*/
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006708os_seteuid_impl(PyObject *module, uid_t euid)
6709/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006710{
6711 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006713 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006714}
6715#endif /* HAVE_SETEUID */
6716
Larry Hastings2f936352014-08-05 14:04:04 +10006717
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006718#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006719/*[clinic input]
6720os.setegid
6721
6722 egid: gid_t
6723 /
6724
6725Set the current process's effective group id.
6726[clinic start generated code]*/
6727
Larry Hastings2f936352014-08-05 14:04:04 +10006728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006729os_setegid_impl(PyObject *module, gid_t egid)
6730/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006731{
6732 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006734 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006735}
6736#endif /* HAVE_SETEGID */
6737
Larry Hastings2f936352014-08-05 14:04:04 +10006738
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006739#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006740/*[clinic input]
6741os.setreuid
6742
6743 ruid: uid_t
6744 euid: uid_t
6745 /
6746
6747Set the current process's real and effective user ids.
6748[clinic start generated code]*/
6749
Larry Hastings2f936352014-08-05 14:04:04 +10006750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006751os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6752/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006753{
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 if (setreuid(ruid, euid) < 0) {
6755 return posix_error();
6756 } else {
6757 Py_INCREF(Py_None);
6758 return Py_None;
6759 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006760}
6761#endif /* HAVE_SETREUID */
6762
Larry Hastings2f936352014-08-05 14:04:04 +10006763
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006764#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006765/*[clinic input]
6766os.setregid
6767
6768 rgid: gid_t
6769 egid: gid_t
6770 /
6771
6772Set the current process's real and effective group ids.
6773[clinic start generated code]*/
6774
Larry Hastings2f936352014-08-05 14:04:04 +10006775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006776os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6777/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006778{
6779 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006781 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006782}
6783#endif /* HAVE_SETREGID */
6784
Larry Hastings2f936352014-08-05 14:04:04 +10006785
Guido van Rossumb6775db1994-08-01 11:34:53 +00006786#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006787/*[clinic input]
6788os.setgid
6789 gid: gid_t
6790 /
6791
6792Set the current process's group id.
6793[clinic start generated code]*/
6794
Larry Hastings2f936352014-08-05 14:04:04 +10006795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006796os_setgid_impl(PyObject *module, gid_t gid)
6797/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006798{
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 if (setgid(gid) < 0)
6800 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006801 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006802}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006803#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006804
Larry Hastings2f936352014-08-05 14:04:04 +10006805
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006806#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006807/*[clinic input]
6808os.setgroups
6809
6810 groups: object
6811 /
6812
6813Set the groups of the current process to list.
6814[clinic start generated code]*/
6815
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006816static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006817os_setgroups(PyObject *module, PyObject *groups)
6818/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006819{
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 int i, len;
6821 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006822
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 if (!PySequence_Check(groups)) {
6824 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6825 return NULL;
6826 }
6827 len = PySequence_Size(groups);
6828 if (len > MAX_GROUPS) {
6829 PyErr_SetString(PyExc_ValueError, "too many groups");
6830 return NULL;
6831 }
6832 for(i = 0; i < len; i++) {
6833 PyObject *elem;
6834 elem = PySequence_GetItem(groups, i);
6835 if (!elem)
6836 return NULL;
6837 if (!PyLong_Check(elem)) {
6838 PyErr_SetString(PyExc_TypeError,
6839 "groups must be integers");
6840 Py_DECREF(elem);
6841 return NULL;
6842 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006843 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 Py_DECREF(elem);
6845 return NULL;
6846 }
6847 }
6848 Py_DECREF(elem);
6849 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006850
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 if (setgroups(len, grouplist) < 0)
6852 return posix_error();
6853 Py_INCREF(Py_None);
6854 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006855}
6856#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006857
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006858#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6859static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006860wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006861{
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 PyObject *result;
6863 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006864 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 if (pid == -1)
6867 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 if (struct_rusage == NULL) {
6870 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6871 if (m == NULL)
6872 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006873 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 Py_DECREF(m);
6875 if (struct_rusage == NULL)
6876 return NULL;
6877 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006878
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6880 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6881 if (!result)
6882 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006883
6884#ifndef doubletime
6885#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6886#endif
6887
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006889 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006891 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6894 SET_INT(result, 2, ru->ru_maxrss);
6895 SET_INT(result, 3, ru->ru_ixrss);
6896 SET_INT(result, 4, ru->ru_idrss);
6897 SET_INT(result, 5, ru->ru_isrss);
6898 SET_INT(result, 6, ru->ru_minflt);
6899 SET_INT(result, 7, ru->ru_majflt);
6900 SET_INT(result, 8, ru->ru_nswap);
6901 SET_INT(result, 9, ru->ru_inblock);
6902 SET_INT(result, 10, ru->ru_oublock);
6903 SET_INT(result, 11, ru->ru_msgsnd);
6904 SET_INT(result, 12, ru->ru_msgrcv);
6905 SET_INT(result, 13, ru->ru_nsignals);
6906 SET_INT(result, 14, ru->ru_nvcsw);
6907 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006908#undef SET_INT
6909
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 if (PyErr_Occurred()) {
6911 Py_DECREF(result);
6912 return NULL;
6913 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006914
Victor Stinner8c62be82010-05-06 00:08:46 +00006915 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006916}
6917#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6918
Larry Hastings2f936352014-08-05 14:04:04 +10006919
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006921/*[clinic input]
6922os.wait3
6923
6924 options: int
6925Wait for completion of a child process.
6926
6927Returns a tuple of information about the child process:
6928 (pid, status, rusage)
6929[clinic start generated code]*/
6930
Larry Hastings2f936352014-08-05 14:04:04 +10006931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006932os_wait3_impl(PyObject *module, int options)
6933/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934{
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006937 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 WAIT_TYPE status;
6939 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006941 do {
6942 Py_BEGIN_ALLOW_THREADS
6943 pid = wait3(&status, options, &ru);
6944 Py_END_ALLOW_THREADS
6945 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6946 if (pid < 0)
6947 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948
Victor Stinner4195b5c2012-02-08 23:03:19 +01006949 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950}
6951#endif /* HAVE_WAIT3 */
6952
Larry Hastings2f936352014-08-05 14:04:04 +10006953
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006954#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006955/*[clinic input]
6956
6957os.wait4
6958
6959 pid: pid_t
6960 options: int
6961
6962Wait for completion of a specific child process.
6963
6964Returns a tuple of information about the child process:
6965 (pid, status, rusage)
6966[clinic start generated code]*/
6967
Larry Hastings2f936352014-08-05 14:04:04 +10006968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006969os_wait4_impl(PyObject *module, pid_t pid, int options)
6970/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006971{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006972 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006974 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 WAIT_TYPE status;
6976 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006977
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006978 do {
6979 Py_BEGIN_ALLOW_THREADS
6980 res = wait4(pid, &status, options, &ru);
6981 Py_END_ALLOW_THREADS
6982 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6983 if (res < 0)
6984 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006985
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006986 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006987}
6988#endif /* HAVE_WAIT4 */
6989
Larry Hastings2f936352014-08-05 14:04:04 +10006990
Ross Lagerwall7807c352011-03-17 20:20:30 +02006991#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006992/*[clinic input]
6993os.waitid
6994
6995 idtype: idtype_t
6996 Must be one of be P_PID, P_PGID or P_ALL.
6997 id: id_t
6998 The id to wait on.
6999 options: int
7000 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7001 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7002 /
7003
7004Returns the result of waiting for a process or processes.
7005
7006Returns either waitid_result or None if WNOHANG is specified and there are
7007no children in a waitable state.
7008[clinic start generated code]*/
7009
Larry Hastings2f936352014-08-05 14:04:04 +10007010static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007011os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7012/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007013{
7014 PyObject *result;
7015 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007016 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007017 siginfo_t si;
7018 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007019
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007020 do {
7021 Py_BEGIN_ALLOW_THREADS
7022 res = waitid(idtype, id, &si, options);
7023 Py_END_ALLOW_THREADS
7024 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7025 if (res < 0)
7026 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007027
7028 if (si.si_pid == 0)
7029 Py_RETURN_NONE;
7030
7031 result = PyStructSequence_New(&WaitidResultType);
7032 if (!result)
7033 return NULL;
7034
7035 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007036 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007037 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7038 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7039 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7040 if (PyErr_Occurred()) {
7041 Py_DECREF(result);
7042 return NULL;
7043 }
7044
7045 return result;
7046}
Larry Hastings2f936352014-08-05 14:04:04 +10007047#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007048
Larry Hastings2f936352014-08-05 14:04:04 +10007049
7050#if defined(HAVE_WAITPID)
7051/*[clinic input]
7052os.waitpid
7053 pid: pid_t
7054 options: int
7055 /
7056
7057Wait for completion of a given child process.
7058
7059Returns a tuple of information regarding the child process:
7060 (pid, status)
7061
7062The options argument is ignored on Windows.
7063[clinic start generated code]*/
7064
Larry Hastings2f936352014-08-05 14:04:04 +10007065static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007066os_waitpid_impl(PyObject *module, pid_t pid, int options)
7067/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007068{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007069 pid_t res;
7070 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 WAIT_TYPE status;
7072 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007073
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007074 do {
7075 Py_BEGIN_ALLOW_THREADS
7076 res = waitpid(pid, &status, options);
7077 Py_END_ALLOW_THREADS
7078 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7079 if (res < 0)
7080 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007081
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007082 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007083}
Tim Petersab034fa2002-02-01 11:27:43 +00007084#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007085/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007086/*[clinic input]
7087os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07007088 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10007089 options: int
7090 /
7091
7092Wait for completion of a given process.
7093
7094Returns a tuple of information regarding the process:
7095 (pid, status << 8)
7096
7097The options argument is ignored on Windows.
7098[clinic start generated code]*/
7099
Larry Hastings2f936352014-08-05 14:04:04 +10007100static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07007101os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07007102/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007103{
7104 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07007105 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007106 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007107
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007108 do {
7109 Py_BEGIN_ALLOW_THREADS
7110 res = _cwait(&status, pid, options);
7111 Py_END_ALLOW_THREADS
7112 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007113 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007114 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007115
Victor Stinner8c62be82010-05-06 00:08:46 +00007116 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007117 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007118}
Larry Hastings2f936352014-08-05 14:04:04 +10007119#endif
7120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007121
Guido van Rossumad0ee831995-03-01 10:34:45 +00007122#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007123/*[clinic input]
7124os.wait
7125
7126Wait for completion of a child process.
7127
7128Returns a tuple of information about the child process:
7129 (pid, status)
7130[clinic start generated code]*/
7131
Larry Hastings2f936352014-08-05 14:04:04 +10007132static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007133os_wait_impl(PyObject *module)
7134/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007135{
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007137 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 WAIT_TYPE status;
7139 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007140
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007141 do {
7142 Py_BEGIN_ALLOW_THREADS
7143 pid = wait(&status);
7144 Py_END_ALLOW_THREADS
7145 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7146 if (pid < 0)
7147 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007148
Victor Stinner8c62be82010-05-06 00:08:46 +00007149 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007150}
Larry Hastings2f936352014-08-05 14:04:04 +10007151#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007153
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7155PyDoc_STRVAR(readlink__doc__,
7156"readlink(path, *, dir_fd=None) -> path\n\n\
7157Return a string representing the path to which the symbolic link points.\n\
7158\n\
7159If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7160 and path should be relative; path will then be relative to that directory.\n\
7161dir_fd may not be implemented on your platform.\n\
7162 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007163#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007164
Guido van Rossumb6775db1994-08-01 11:34:53 +00007165#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007166
Larry Hastings2f936352014-08-05 14:04:04 +10007167/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007168static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007169posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007170{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007171 path_t path;
7172 int dir_fd = DEFAULT_DIR_FD;
7173 char buffer[MAXPATHLEN];
7174 ssize_t length;
7175 PyObject *return_value = NULL;
7176 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007177
Larry Hastings9cf065c2012-06-22 16:30:09 -07007178 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007179 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007180 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7181 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007182 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007184
Victor Stinner8c62be82010-05-06 00:08:46 +00007185 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007186#ifdef HAVE_READLINKAT
7187 if (dir_fd != DEFAULT_DIR_FD)
7188 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007189 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190#endif
7191 length = readlink(path.narrow, buffer, sizeof(buffer));
7192 Py_END_ALLOW_THREADS
7193
7194 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007195 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007196 goto exit;
7197 }
7198
7199 if (PyUnicode_Check(path.object))
7200 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7201 else
7202 return_value = PyBytes_FromStringAndSize(buffer, length);
7203exit:
7204 path_cleanup(&path);
7205 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007206}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007207
Guido van Rossumb6775db1994-08-01 11:34:53 +00007208#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007209
Larry Hastings2f936352014-08-05 14:04:04 +10007210#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7211
7212static PyObject *
7213win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7214{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007215 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007216 DWORD n_bytes_returned;
7217 DWORD io_result;
7218 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007219 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007220 HANDLE reparse_point_handle;
7221
Martin Panter70214ad2016-08-04 02:38:59 +00007222 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7223 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007224 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007225
7226 static char *keywords[] = {"path", "dir_fd", NULL};
7227
7228 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7229 &po,
7230 dir_fd_unavailable, &dir_fd
7231 ))
7232 return NULL;
7233
7234 path = PyUnicode_AsUnicode(po);
7235 if (path == NULL)
7236 return NULL;
7237
7238 /* First get a handle to the reparse point */
7239 Py_BEGIN_ALLOW_THREADS
7240 reparse_point_handle = CreateFileW(
7241 path,
7242 0,
7243 0,
7244 0,
7245 OPEN_EXISTING,
7246 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7247 0);
7248 Py_END_ALLOW_THREADS
7249
7250 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7251 return win32_error_object("readlink", po);
7252
7253 Py_BEGIN_ALLOW_THREADS
7254 /* New call DeviceIoControl to read the reparse point */
7255 io_result = DeviceIoControl(
7256 reparse_point_handle,
7257 FSCTL_GET_REPARSE_POINT,
7258 0, 0, /* in buffer */
7259 target_buffer, sizeof(target_buffer),
7260 &n_bytes_returned,
7261 0 /* we're not using OVERLAPPED_IO */
7262 );
7263 CloseHandle(reparse_point_handle);
7264 Py_END_ALLOW_THREADS
7265
7266 if (io_result==0)
7267 return win32_error_object("readlink", po);
7268
7269 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7270 {
7271 PyErr_SetString(PyExc_ValueError,
7272 "not a symbolic link");
7273 return NULL;
7274 }
7275 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7276 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7277
7278 result = PyUnicode_FromWideChar(print_name,
7279 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7280 return result;
7281}
7282
7283#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7284
7285
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007286
Larry Hastings9cf065c2012-06-22 16:30:09 -07007287#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007288
7289#if defined(MS_WINDOWS)
7290
7291/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007292static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
7293static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPCSTR, LPCSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007294
Larry Hastings9cf065c2012-06-22 16:30:09 -07007295static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007296check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007297{
7298 HINSTANCE hKernel32;
7299 /* only recheck */
7300 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7301 return 1;
7302 hKernel32 = GetModuleHandleW(L"KERNEL32");
7303 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7304 "CreateSymbolicLinkW");
7305 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7306 "CreateSymbolicLinkA");
7307 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7308}
7309
Victor Stinner31b3b922013-06-05 01:49:17 +02007310/* Remove the last portion of the path */
7311static void
7312_dirnameW(WCHAR *path)
7313{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314 WCHAR *ptr;
7315
7316 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007317 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007318 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007319 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320 }
7321 *ptr = 0;
7322}
7323
Victor Stinner31b3b922013-06-05 01:49:17 +02007324/* Remove the last portion of the path */
7325static void
7326_dirnameA(char *path)
7327{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007328 char *ptr;
7329
7330 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007331 for(ptr = path + strlen(path); ptr != path; ptr--) {
7332 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007334 }
7335 *ptr = 0;
7336}
7337
Victor Stinner31b3b922013-06-05 01:49:17 +02007338/* Is this path absolute? */
7339static int
7340_is_absW(const WCHAR *path)
7341{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007342 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7343
7344}
7345
Victor Stinner31b3b922013-06-05 01:49:17 +02007346/* Is this path absolute? */
7347static int
7348_is_absA(const char *path)
7349{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007350 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7351
7352}
7353
Victor Stinner31b3b922013-06-05 01:49:17 +02007354/* join root and rest with a backslash */
7355static void
7356_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7357{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007358 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007359
Victor Stinner31b3b922013-06-05 01:49:17 +02007360 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007361 wcscpy(dest_path, rest);
7362 return;
7363 }
7364
7365 root_len = wcslen(root);
7366
7367 wcscpy(dest_path, root);
7368 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007369 dest_path[root_len] = L'\\';
7370 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007371 }
7372 wcscpy(dest_path+root_len, rest);
7373}
7374
Victor Stinner31b3b922013-06-05 01:49:17 +02007375/* join root and rest with a backslash */
7376static void
7377_joinA(char *dest_path, const char *root, const char *rest)
7378{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007379 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007380
Victor Stinner31b3b922013-06-05 01:49:17 +02007381 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007382 strcpy(dest_path, rest);
7383 return;
7384 }
7385
7386 root_len = strlen(root);
7387
7388 strcpy(dest_path, root);
7389 if(root_len) {
7390 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007391 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007392 }
7393 strcpy(dest_path+root_len, rest);
7394}
7395
Victor Stinner31b3b922013-06-05 01:49:17 +02007396/* Return True if the path at src relative to dest is a directory */
7397static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007398_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007399{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007400 WIN32_FILE_ATTRIBUTE_DATA src_info;
7401 WCHAR dest_parent[MAX_PATH];
7402 WCHAR src_resolved[MAX_PATH] = L"";
7403
7404 /* dest_parent = os.path.dirname(dest) */
7405 wcscpy(dest_parent, dest);
7406 _dirnameW(dest_parent);
7407 /* src_resolved = os.path.join(dest_parent, src) */
7408 _joinW(src_resolved, dest_parent, src);
7409 return (
7410 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7411 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7412 );
7413}
7414
Victor Stinner31b3b922013-06-05 01:49:17 +02007415/* Return True if the path at src relative to dest is a directory */
7416static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007417_check_dirA(LPCSTR src, LPCSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007418{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007419 WIN32_FILE_ATTRIBUTE_DATA src_info;
7420 char dest_parent[MAX_PATH];
7421 char src_resolved[MAX_PATH] = "";
7422
7423 /* dest_parent = os.path.dirname(dest) */
7424 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007425 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007426 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007427 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007428 return (
7429 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7430 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7431 );
7432}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007434
Larry Hastings2f936352014-08-05 14:04:04 +10007435
7436/*[clinic input]
7437os.symlink
7438 src: path_t
7439 dst: path_t
7440 target_is_directory: bool = False
7441 *
7442 dir_fd: dir_fd(requires='symlinkat')=None
7443
7444# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7445
7446Create a symbolic link pointing to src named dst.
7447
7448target_is_directory is required on Windows if the target is to be
7449 interpreted as a directory. (On Windows, symlink requires
7450 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7451 target_is_directory is ignored on non-Windows platforms.
7452
7453If dir_fd is not None, it should be a file descriptor open to a directory,
7454 and path should be relative; path will then be relative to that directory.
7455dir_fd may not be implemented on your platform.
7456 If it is unavailable, using it will raise a NotImplementedError.
7457
7458[clinic start generated code]*/
7459
Larry Hastings2f936352014-08-05 14:04:04 +10007460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007461os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007462 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007463/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007464{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007465#ifdef MS_WINDOWS
7466 DWORD result;
7467#else
7468 int result;
7469#endif
7470
Larry Hastings9cf065c2012-06-22 16:30:09 -07007471#ifdef MS_WINDOWS
7472 if (!check_CreateSymbolicLink()) {
7473 PyErr_SetString(PyExc_NotImplementedError,
7474 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007475 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007476 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007477 if (!win32_can_symlink) {
7478 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007479 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007480 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007481#endif
7482
Larry Hastings2f936352014-08-05 14:04:04 +10007483 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007484 PyErr_SetString(PyExc_ValueError,
7485 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007486 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007487 }
7488
7489#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007490
Larry Hastings9cf065c2012-06-22 16:30:09 -07007491 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007492 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007493 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007494 target_is_directory |= _check_dirW(src->wide, dst->wide);
7495 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007496 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007497 }
7498 else {
7499 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007500 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7501 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007502 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007503 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007504 Py_END_ALLOW_THREADS
7505
Larry Hastings2f936352014-08-05 14:04:04 +10007506 if (!result)
7507 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007508
7509#else
7510
7511 Py_BEGIN_ALLOW_THREADS
7512#if HAVE_SYMLINKAT
7513 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007514 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007515 else
7516#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007517 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007518 Py_END_ALLOW_THREADS
7519
Larry Hastings2f936352014-08-05 14:04:04 +10007520 if (result)
7521 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007522#endif
7523
Larry Hastings2f936352014-08-05 14:04:04 +10007524 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007525}
7526#endif /* HAVE_SYMLINK */
7527
Larry Hastings9cf065c2012-06-22 16:30:09 -07007528
Brian Curtind40e6f72010-07-08 21:39:08 +00007529
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007530
Larry Hastings605a62d2012-06-24 04:33:36 -07007531static PyStructSequence_Field times_result_fields[] = {
7532 {"user", "user time"},
7533 {"system", "system time"},
7534 {"children_user", "user time of children"},
7535 {"children_system", "system time of children"},
7536 {"elapsed", "elapsed time since an arbitrary point in the past"},
7537 {NULL}
7538};
7539
7540PyDoc_STRVAR(times_result__doc__,
7541"times_result: Result from os.times().\n\n\
7542This object may be accessed either as a tuple of\n\
7543 (user, system, children_user, children_system, elapsed),\n\
7544or via the attributes user, system, children_user, children_system,\n\
7545and elapsed.\n\
7546\n\
7547See os.times for more information.");
7548
7549static PyStructSequence_Desc times_result_desc = {
7550 "times_result", /* name */
7551 times_result__doc__, /* doc */
7552 times_result_fields,
7553 5
7554};
7555
7556static PyTypeObject TimesResultType;
7557
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007558#ifdef MS_WINDOWS
7559#define HAVE_TIMES /* mandatory, for the method table */
7560#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007561
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007562#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007563
7564static PyObject *
7565build_times_result(double user, double system,
7566 double children_user, double children_system,
7567 double elapsed)
7568{
7569 PyObject *value = PyStructSequence_New(&TimesResultType);
7570 if (value == NULL)
7571 return NULL;
7572
7573#define SET(i, field) \
7574 { \
7575 PyObject *o = PyFloat_FromDouble(field); \
7576 if (!o) { \
7577 Py_DECREF(value); \
7578 return NULL; \
7579 } \
7580 PyStructSequence_SET_ITEM(value, i, o); \
7581 } \
7582
7583 SET(0, user);
7584 SET(1, system);
7585 SET(2, children_user);
7586 SET(3, children_system);
7587 SET(4, elapsed);
7588
7589#undef SET
7590
7591 return value;
7592}
7593
Larry Hastings605a62d2012-06-24 04:33:36 -07007594
Larry Hastings2f936352014-08-05 14:04:04 +10007595#ifndef MS_WINDOWS
7596#define NEED_TICKS_PER_SECOND
7597static long ticks_per_second = -1;
7598#endif /* MS_WINDOWS */
7599
7600/*[clinic input]
7601os.times
7602
7603Return a collection containing process timing information.
7604
7605The object returned behaves like a named tuple with these fields:
7606 (utime, stime, cutime, cstime, elapsed_time)
7607All fields are floating point numbers.
7608[clinic start generated code]*/
7609
Larry Hastings2f936352014-08-05 14:04:04 +10007610static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007611os_times_impl(PyObject *module)
7612/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007613#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007614{
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 FILETIME create, exit, kernel, user;
7616 HANDLE hProc;
7617 hProc = GetCurrentProcess();
7618 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7619 /* The fields of a FILETIME structure are the hi and lo part
7620 of a 64-bit value expressed in 100 nanosecond units.
7621 1e7 is one second in such units; 1e-7 the inverse.
7622 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7623 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007624 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 (double)(user.dwHighDateTime*429.4967296 +
7626 user.dwLowDateTime*1e-7),
7627 (double)(kernel.dwHighDateTime*429.4967296 +
7628 kernel.dwLowDateTime*1e-7),
7629 (double)0,
7630 (double)0,
7631 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007632}
Larry Hastings2f936352014-08-05 14:04:04 +10007633#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007634{
Larry Hastings2f936352014-08-05 14:04:04 +10007635
7636
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007637 struct tms t;
7638 clock_t c;
7639 errno = 0;
7640 c = times(&t);
7641 if (c == (clock_t) -1)
7642 return posix_error();
7643 return build_times_result(
7644 (double)t.tms_utime / ticks_per_second,
7645 (double)t.tms_stime / ticks_per_second,
7646 (double)t.tms_cutime / ticks_per_second,
7647 (double)t.tms_cstime / ticks_per_second,
7648 (double)c / ticks_per_second);
7649}
Larry Hastings2f936352014-08-05 14:04:04 +10007650#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007651#endif /* HAVE_TIMES */
7652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007653
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007654#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007655/*[clinic input]
7656os.getsid
7657
7658 pid: pid_t
7659 /
7660
7661Call the system call getsid(pid) and return the result.
7662[clinic start generated code]*/
7663
Larry Hastings2f936352014-08-05 14:04:04 +10007664static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007665os_getsid_impl(PyObject *module, pid_t pid)
7666/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007667{
Victor Stinner8c62be82010-05-06 00:08:46 +00007668 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 sid = getsid(pid);
7670 if (sid < 0)
7671 return posix_error();
7672 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007673}
7674#endif /* HAVE_GETSID */
7675
7676
Guido van Rossumb6775db1994-08-01 11:34:53 +00007677#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007678/*[clinic input]
7679os.setsid
7680
7681Call the system call setsid().
7682[clinic start generated code]*/
7683
Larry Hastings2f936352014-08-05 14:04:04 +10007684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007685os_setsid_impl(PyObject *module)
7686/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007687{
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 if (setsid() < 0)
7689 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007690 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007691}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007692#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007693
Larry Hastings2f936352014-08-05 14:04:04 +10007694
Guido van Rossumb6775db1994-08-01 11:34:53 +00007695#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007696/*[clinic input]
7697os.setpgid
7698
7699 pid: pid_t
7700 pgrp: pid_t
7701 /
7702
7703Call the system call setpgid(pid, pgrp).
7704[clinic start generated code]*/
7705
Larry Hastings2f936352014-08-05 14:04:04 +10007706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007707os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7708/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007709{
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 if (setpgid(pid, pgrp) < 0)
7711 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007712 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007713}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007714#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007716
Guido van Rossumb6775db1994-08-01 11:34:53 +00007717#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007718/*[clinic input]
7719os.tcgetpgrp
7720
7721 fd: int
7722 /
7723
7724Return the process group associated with the terminal specified by fd.
7725[clinic start generated code]*/
7726
Larry Hastings2f936352014-08-05 14:04:04 +10007727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007728os_tcgetpgrp_impl(PyObject *module, int fd)
7729/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007730{
7731 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 if (pgid < 0)
7733 return posix_error();
7734 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007735}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007736#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007738
Guido van Rossumb6775db1994-08-01 11:34:53 +00007739#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007740/*[clinic input]
7741os.tcsetpgrp
7742
7743 fd: int
7744 pgid: pid_t
7745 /
7746
7747Set the process group associated with the terminal specified by fd.
7748[clinic start generated code]*/
7749
Larry Hastings2f936352014-08-05 14:04:04 +10007750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007751os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7752/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007753{
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 if (tcsetpgrp(fd, pgid) < 0)
7755 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007756 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007757}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007758#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007759
Guido van Rossum687dd131993-05-17 08:34:16 +00007760/* Functions acting on file descriptors */
7761
Victor Stinnerdaf45552013-08-28 00:53:59 +02007762#ifdef O_CLOEXEC
7763extern int _Py_open_cloexec_works;
7764#endif
7765
Larry Hastings2f936352014-08-05 14:04:04 +10007766
7767/*[clinic input]
7768os.open -> int
7769 path: path_t
7770 flags: int
7771 mode: int = 0o777
7772 *
7773 dir_fd: dir_fd(requires='openat') = None
7774
7775# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7776
7777Open a file for low level IO. Returns a file descriptor (integer).
7778
7779If dir_fd is not None, it should be a file descriptor open to a directory,
7780 and path should be relative; path will then be relative to that directory.
7781dir_fd may not be implemented on your platform.
7782 If it is unavailable, using it will raise a NotImplementedError.
7783[clinic start generated code]*/
7784
Larry Hastings2f936352014-08-05 14:04:04 +10007785static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007786os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7787/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007788{
7789 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007790 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007791
Victor Stinnerdaf45552013-08-28 00:53:59 +02007792#ifdef O_CLOEXEC
7793 int *atomic_flag_works = &_Py_open_cloexec_works;
7794#elif !defined(MS_WINDOWS)
7795 int *atomic_flag_works = NULL;
7796#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007797
Victor Stinnerdaf45552013-08-28 00:53:59 +02007798#ifdef MS_WINDOWS
7799 flags |= O_NOINHERIT;
7800#elif defined(O_CLOEXEC)
7801 flags |= O_CLOEXEC;
7802#endif
7803
Steve Dower8fc89802015-04-12 00:26:27 -04007804 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007805 do {
7806 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007807#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007808 if (path->wide)
7809 fd = _wopen(path->wide, flags, mode);
7810 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007811#endif
7812#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007813 if (dir_fd != DEFAULT_DIR_FD)
7814 fd = openat(dir_fd, path->narrow, flags, mode);
7815 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007816#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007817 fd = open(path->narrow, flags, mode);
7818 Py_END_ALLOW_THREADS
7819 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007820 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007821
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007822 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007823 if (!async_err)
7824 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007825 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007826 }
7827
Victor Stinnerdaf45552013-08-28 00:53:59 +02007828#ifndef MS_WINDOWS
7829 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7830 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007831 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007832 }
7833#endif
7834
Larry Hastings2f936352014-08-05 14:04:04 +10007835 return fd;
7836}
7837
7838
7839/*[clinic input]
7840os.close
7841
7842 fd: int
7843
7844Close a file descriptor.
7845[clinic start generated code]*/
7846
Barry Warsaw53699e91996-12-10 23:23:01 +00007847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007848os_close_impl(PyObject *module, int fd)
7849/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007850{
Larry Hastings2f936352014-08-05 14:04:04 +10007851 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 if (!_PyVerify_fd(fd))
7853 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007854 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7855 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7856 * for more details.
7857 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007859 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007861 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 Py_END_ALLOW_THREADS
7863 if (res < 0)
7864 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007865 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007866}
7867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007868
Larry Hastings2f936352014-08-05 14:04:04 +10007869/*[clinic input]
7870os.closerange
7871
7872 fd_low: int
7873 fd_high: int
7874 /
7875
7876Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7877[clinic start generated code]*/
7878
Larry Hastings2f936352014-08-05 14:04:04 +10007879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007880os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7881/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007882{
7883 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007885 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007886 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 if (_PyVerify_fd(i))
7888 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007889 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 Py_END_ALLOW_THREADS
7891 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007892}
7893
7894
Larry Hastings2f936352014-08-05 14:04:04 +10007895/*[clinic input]
7896os.dup -> int
7897
7898 fd: int
7899 /
7900
7901Return a duplicate of a file descriptor.
7902[clinic start generated code]*/
7903
Larry Hastings2f936352014-08-05 14:04:04 +10007904static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007905os_dup_impl(PyObject *module, int fd)
7906/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007907{
7908 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007909}
7910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007911
Larry Hastings2f936352014-08-05 14:04:04 +10007912/*[clinic input]
7913os.dup2
7914 fd: int
7915 fd2: int
7916 inheritable: bool=True
7917
7918Duplicate file descriptor.
7919[clinic start generated code]*/
7920
Larry Hastings2f936352014-08-05 14:04:04 +10007921static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007922os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7923/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007924{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007925 int res;
7926#if defined(HAVE_DUP3) && \
7927 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7928 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7929 int dup3_works = -1;
7930#endif
7931
Victor Stinner8c62be82010-05-06 00:08:46 +00007932 if (!_PyVerify_fd_dup2(fd, fd2))
7933 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007935 /* dup2() can fail with EINTR if the target FD is already open, because it
7936 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7937 * upon close(), and therefore below.
7938 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007939#ifdef MS_WINDOWS
7940 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007941 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007943 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007944 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 if (res < 0)
7946 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007947
7948 /* Character files like console cannot be make non-inheritable */
7949 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7950 close(fd2);
7951 return NULL;
7952 }
7953
7954#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7955 Py_BEGIN_ALLOW_THREADS
7956 if (!inheritable)
7957 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7958 else
7959 res = dup2(fd, fd2);
7960 Py_END_ALLOW_THREADS
7961 if (res < 0)
7962 return posix_error();
7963
7964#else
7965
7966#ifdef HAVE_DUP3
7967 if (!inheritable && dup3_works != 0) {
7968 Py_BEGIN_ALLOW_THREADS
7969 res = dup3(fd, fd2, O_CLOEXEC);
7970 Py_END_ALLOW_THREADS
7971 if (res < 0) {
7972 if (dup3_works == -1)
7973 dup3_works = (errno != ENOSYS);
7974 if (dup3_works)
7975 return posix_error();
7976 }
7977 }
7978
7979 if (inheritable || dup3_works == 0)
7980 {
7981#endif
7982 Py_BEGIN_ALLOW_THREADS
7983 res = dup2(fd, fd2);
7984 Py_END_ALLOW_THREADS
7985 if (res < 0)
7986 return posix_error();
7987
7988 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7989 close(fd2);
7990 return NULL;
7991 }
7992#ifdef HAVE_DUP3
7993 }
7994#endif
7995
7996#endif
7997
Larry Hastings2f936352014-08-05 14:04:04 +10007998 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007999}
8000
Larry Hastings2f936352014-08-05 14:04:04 +10008001
Ross Lagerwall7807c352011-03-17 20:20:30 +02008002#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008003/*[clinic input]
8004os.lockf
8005
8006 fd: int
8007 An open file descriptor.
8008 command: int
8009 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8010 length: Py_off_t
8011 The number of bytes to lock, starting at the current position.
8012 /
8013
8014Apply, test or remove a POSIX lock on an open file descriptor.
8015
8016[clinic start generated code]*/
8017
Larry Hastings2f936352014-08-05 14:04:04 +10008018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008019os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8020/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008021{
8022 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008023
8024 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008025 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008026 Py_END_ALLOW_THREADS
8027
8028 if (res < 0)
8029 return posix_error();
8030
8031 Py_RETURN_NONE;
8032}
Larry Hastings2f936352014-08-05 14:04:04 +10008033#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008034
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008035
Larry Hastings2f936352014-08-05 14:04:04 +10008036/*[clinic input]
8037os.lseek -> Py_off_t
8038
8039 fd: int
8040 position: Py_off_t
8041 how: int
8042 /
8043
8044Set the position of a file descriptor. Return the new position.
8045
8046Return the new cursor position in number of bytes
8047relative to the beginning of the file.
8048[clinic start generated code]*/
8049
Larry Hastings2f936352014-08-05 14:04:04 +10008050static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008051os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8052/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008053{
8054 Py_off_t result;
8055
8056 if (!_PyVerify_fd(fd)) {
8057 posix_error();
8058 return -1;
8059 }
Guido van Rossum687dd131993-05-17 08:34:16 +00008060#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8062 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008063 case 0: how = SEEK_SET; break;
8064 case 1: how = SEEK_CUR; break;
8065 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008066 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008067#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008068
Victor Stinner8c62be82010-05-06 00:08:46 +00008069 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10008070 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008071
Larry Hastings2f936352014-08-05 14:04:04 +10008072 if (!_PyVerify_fd(fd)) {
8073 posix_error();
8074 return -1;
8075 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008076 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008077 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008078#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008079 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008080#else
Larry Hastings2f936352014-08-05 14:04:04 +10008081 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008082#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008083 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008085 if (result < 0)
8086 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008087
Larry Hastings2f936352014-08-05 14:04:04 +10008088 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008089}
8090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008091
Larry Hastings2f936352014-08-05 14:04:04 +10008092/*[clinic input]
8093os.read
8094 fd: int
8095 length: Py_ssize_t
8096 /
8097
8098Read from a file descriptor. Returns a bytes object.
8099[clinic start generated code]*/
8100
Larry Hastings2f936352014-08-05 14:04:04 +10008101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008102os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8103/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008104{
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 Py_ssize_t n;
8106 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008107
8108 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 errno = EINVAL;
8110 return posix_error();
8111 }
Larry Hastings2f936352014-08-05 14:04:04 +10008112
8113#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008114 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008115 if (length > INT_MAX)
8116 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008117#endif
8118
8119 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008120 if (buffer == NULL)
8121 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008122
Victor Stinner66aab0c2015-03-19 22:53:20 +01008123 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8124 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008126 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 }
Larry Hastings2f936352014-08-05 14:04:04 +10008128
8129 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008131
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008133}
8134
Ross Lagerwall7807c352011-03-17 20:20:30 +02008135#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8136 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008137static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008138iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8139{
8140 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008141 Py_ssize_t blen, total = 0;
8142
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008143 *iov = PyMem_New(struct iovec, cnt);
8144 if (*iov == NULL) {
8145 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008146 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008147 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008148
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008149 *buf = PyMem_New(Py_buffer, cnt);
8150 if (*buf == NULL) {
8151 PyMem_Del(*iov);
8152 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008153 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008154 }
8155
8156 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008157 PyObject *item = PySequence_GetItem(seq, i);
8158 if (item == NULL)
8159 goto fail;
8160 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8161 Py_DECREF(item);
8162 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008163 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008164 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008165 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008166 blen = (*buf)[i].len;
8167 (*iov)[i].iov_len = blen;
8168 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008169 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008170 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008171
8172fail:
8173 PyMem_Del(*iov);
8174 for (j = 0; j < i; j++) {
8175 PyBuffer_Release(&(*buf)[j]);
8176 }
8177 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008178 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008179}
8180
8181static void
8182iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8183{
8184 int i;
8185 PyMem_Del(iov);
8186 for (i = 0; i < cnt; i++) {
8187 PyBuffer_Release(&buf[i]);
8188 }
8189 PyMem_Del(buf);
8190}
8191#endif
8192
Larry Hastings2f936352014-08-05 14:04:04 +10008193
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008195/*[clinic input]
8196os.readv -> Py_ssize_t
8197
8198 fd: int
8199 buffers: object
8200 /
8201
8202Read from a file descriptor fd into an iterable of buffers.
8203
8204The buffers should be mutable buffers accepting bytes.
8205readv will transfer data into each buffer until it is full
8206and then move on to the next buffer in the sequence to hold
8207the rest of the data.
8208
8209readv returns the total number of bytes read,
8210which may be less than the total capacity of all the buffers.
8211[clinic start generated code]*/
8212
Larry Hastings2f936352014-08-05 14:04:04 +10008213static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008214os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8215/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008216{
8217 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008218 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008219 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008220 struct iovec *iov;
8221 Py_buffer *buf;
8222
Larry Hastings2f936352014-08-05 14:04:04 +10008223 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008224 PyErr_SetString(PyExc_TypeError,
8225 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008226 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008227 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008228
Larry Hastings2f936352014-08-05 14:04:04 +10008229 cnt = PySequence_Size(buffers);
8230
8231 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8232 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008233
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008234 do {
8235 Py_BEGIN_ALLOW_THREADS
8236 n = readv(fd, iov, cnt);
8237 Py_END_ALLOW_THREADS
8238 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008239
8240 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008241 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008242 if (!async_err)
8243 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008244 return -1;
8245 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008246
Larry Hastings2f936352014-08-05 14:04:04 +10008247 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008248}
Larry Hastings2f936352014-08-05 14:04:04 +10008249#endif /* HAVE_READV */
8250
Ross Lagerwall7807c352011-03-17 20:20:30 +02008251
8252#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008253/*[clinic input]
8254# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8255os.pread
8256
8257 fd: int
8258 length: int
8259 offset: Py_off_t
8260 /
8261
8262Read a number of bytes from a file descriptor starting at a particular offset.
8263
8264Read length bytes from file descriptor fd, starting at offset bytes from
8265the beginning of the file. The file offset remains unchanged.
8266[clinic start generated code]*/
8267
Larry Hastings2f936352014-08-05 14:04:04 +10008268static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008269os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8270/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008271{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008272 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008273 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008274 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008275
Larry Hastings2f936352014-08-05 14:04:04 +10008276 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008277 errno = EINVAL;
8278 return posix_error();
8279 }
Larry Hastings2f936352014-08-05 14:04:04 +10008280 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008281 if (buffer == NULL)
8282 return NULL;
8283 if (!_PyVerify_fd(fd)) {
8284 Py_DECREF(buffer);
8285 return posix_error();
8286 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008287
8288 do {
8289 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008290 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008291 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008292 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008293 Py_END_ALLOW_THREADS
8294 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8295
Ross Lagerwall7807c352011-03-17 20:20:30 +02008296 if (n < 0) {
8297 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008298 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008299 }
Larry Hastings2f936352014-08-05 14:04:04 +10008300 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008301 _PyBytes_Resize(&buffer, n);
8302 return buffer;
8303}
Larry Hastings2f936352014-08-05 14:04:04 +10008304#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008305
Larry Hastings2f936352014-08-05 14:04:04 +10008306
8307/*[clinic input]
8308os.write -> Py_ssize_t
8309
8310 fd: int
8311 data: Py_buffer
8312 /
8313
8314Write a bytes object to a file descriptor.
8315[clinic start generated code]*/
8316
Larry Hastings2f936352014-08-05 14:04:04 +10008317static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008318os_write_impl(PyObject *module, int fd, Py_buffer *data)
8319/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008320{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008321 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008322}
8323
8324#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008326"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008327sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008328 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008329Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008330
Larry Hastings2f936352014-08-05 14:04:04 +10008331/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008332static PyObject *
8333posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8334{
8335 int in, out;
8336 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008337 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008338 off_t offset;
8339
8340#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8341#ifndef __APPLE__
8342 Py_ssize_t len;
8343#endif
8344 PyObject *headers = NULL, *trailers = NULL;
8345 Py_buffer *hbuf, *tbuf;
8346 off_t sbytes;
8347 struct sf_hdtr sf;
8348 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008349 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008350 static char *keywords[] = {"out", "in",
8351 "offset", "count",
8352 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008353
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008354 sf.headers = NULL;
8355 sf.trailers = NULL;
8356
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008357#ifdef __APPLE__
8358 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008359 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008360#else
8361 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008362 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008363#endif
8364 &headers, &trailers, &flags))
8365 return NULL;
8366 if (headers != NULL) {
8367 if (!PySequence_Check(headers)) {
8368 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008369 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008370 return NULL;
8371 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008372 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008373 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008374 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008375 (i = iov_setup(&(sf.headers), &hbuf,
8376 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008377 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008378#ifdef __APPLE__
8379 sbytes += i;
8380#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008381 }
8382 }
8383 if (trailers != NULL) {
8384 if (!PySequence_Check(trailers)) {
8385 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008386 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008387 return NULL;
8388 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008389 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008390 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008391 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008392 (i = iov_setup(&(sf.trailers), &tbuf,
8393 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008394 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008395#ifdef __APPLE__
8396 sbytes += i;
8397#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008398 }
8399 }
8400
Steve Dower8fc89802015-04-12 00:26:27 -04008401 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008402 do {
8403 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008404#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008405 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008406#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008407 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008408#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008409 Py_END_ALLOW_THREADS
8410 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008411 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008412
8413 if (sf.headers != NULL)
8414 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8415 if (sf.trailers != NULL)
8416 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8417
8418 if (ret < 0) {
8419 if ((errno == EAGAIN) || (errno == EBUSY)) {
8420 if (sbytes != 0) {
8421 // some data has been sent
8422 goto done;
8423 }
8424 else {
8425 // no data has been sent; upper application is supposed
8426 // to retry on EAGAIN or EBUSY
8427 return posix_error();
8428 }
8429 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008430 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008431 }
8432 goto done;
8433
8434done:
8435 #if !defined(HAVE_LARGEFILE_SUPPORT)
8436 return Py_BuildValue("l", sbytes);
8437 #else
8438 return Py_BuildValue("L", sbytes);
8439 #endif
8440
8441#else
8442 Py_ssize_t count;
8443 PyObject *offobj;
8444 static char *keywords[] = {"out", "in",
8445 "offset", "count", NULL};
8446 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8447 keywords, &out, &in, &offobj, &count))
8448 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008449#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008450 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008451 do {
8452 Py_BEGIN_ALLOW_THREADS
8453 ret = sendfile(out, in, NULL, count);
8454 Py_END_ALLOW_THREADS
8455 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008456 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008457 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008458 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008459 }
8460#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008461 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008462 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008463
8464 do {
8465 Py_BEGIN_ALLOW_THREADS
8466 ret = sendfile(out, in, &offset, count);
8467 Py_END_ALLOW_THREADS
8468 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008469 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008470 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008471 return Py_BuildValue("n", ret);
8472#endif
8473}
Larry Hastings2f936352014-08-05 14:04:04 +10008474#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008475
Larry Hastings2f936352014-08-05 14:04:04 +10008476
8477/*[clinic input]
8478os.fstat
8479
8480 fd : int
8481
8482Perform a stat system call on the given file descriptor.
8483
8484Like stat(), but for an open file descriptor.
8485Equivalent to os.stat(fd).
8486[clinic start generated code]*/
8487
Larry Hastings2f936352014-08-05 14:04:04 +10008488static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008489os_fstat_impl(PyObject *module, int fd)
8490/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008491{
Victor Stinner8c62be82010-05-06 00:08:46 +00008492 STRUCT_STAT st;
8493 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008494 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008495
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008496 do {
8497 Py_BEGIN_ALLOW_THREADS
8498 res = FSTAT(fd, &st);
8499 Py_END_ALLOW_THREADS
8500 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008501 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008502#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008503 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008504#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008505 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008506#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008507 }
Tim Peters5aa91602002-01-30 05:46:57 +00008508
Victor Stinner4195b5c2012-02-08 23:03:19 +01008509 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008510}
8511
Larry Hastings2f936352014-08-05 14:04:04 +10008512
8513/*[clinic input]
8514os.isatty -> bool
8515 fd: int
8516 /
8517
8518Return True if the fd is connected to a terminal.
8519
8520Return True if the file descriptor is an open file descriptor
8521connected to the slave end of a terminal.
8522[clinic start generated code]*/
8523
Larry Hastings2f936352014-08-05 14:04:04 +10008524static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008525os_isatty_impl(PyObject *module, int fd)
8526/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008527{
Steve Dower8fc89802015-04-12 00:26:27 -04008528 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008529 if (!_PyVerify_fd(fd))
8530 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008531 _Py_BEGIN_SUPPRESS_IPH
8532 return_value = isatty(fd);
8533 _Py_END_SUPPRESS_IPH
8534 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008535}
8536
8537
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008538#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008539/*[clinic input]
8540os.pipe
8541
8542Create a pipe.
8543
8544Returns a tuple of two file descriptors:
8545 (read_fd, write_fd)
8546[clinic start generated code]*/
8547
Larry Hastings2f936352014-08-05 14:04:04 +10008548static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008549os_pipe_impl(PyObject *module)
8550/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008551{
Victor Stinner8c62be82010-05-06 00:08:46 +00008552 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008553#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008554 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008555 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008556 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008557#else
8558 int res;
8559#endif
8560
8561#ifdef MS_WINDOWS
8562 attr.nLength = sizeof(attr);
8563 attr.lpSecurityDescriptor = NULL;
8564 attr.bInheritHandle = FALSE;
8565
8566 Py_BEGIN_ALLOW_THREADS
8567 ok = CreatePipe(&read, &write, &attr, 0);
8568 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008569 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8570 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008571 if (fds[0] == -1 || fds[1] == -1) {
8572 CloseHandle(read);
8573 CloseHandle(write);
8574 ok = 0;
8575 }
8576 }
8577 Py_END_ALLOW_THREADS
8578
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008580 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008581#else
8582
8583#ifdef HAVE_PIPE2
8584 Py_BEGIN_ALLOW_THREADS
8585 res = pipe2(fds, O_CLOEXEC);
8586 Py_END_ALLOW_THREADS
8587
8588 if (res != 0 && errno == ENOSYS)
8589 {
8590#endif
8591 Py_BEGIN_ALLOW_THREADS
8592 res = pipe(fds);
8593 Py_END_ALLOW_THREADS
8594
8595 if (res == 0) {
8596 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8597 close(fds[0]);
8598 close(fds[1]);
8599 return NULL;
8600 }
8601 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8602 close(fds[0]);
8603 close(fds[1]);
8604 return NULL;
8605 }
8606 }
8607#ifdef HAVE_PIPE2
8608 }
8609#endif
8610
8611 if (res != 0)
8612 return PyErr_SetFromErrno(PyExc_OSError);
8613#endif /* !MS_WINDOWS */
8614 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008615}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008616#endif /* HAVE_PIPE */
8617
Larry Hastings2f936352014-08-05 14:04:04 +10008618
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008619#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008620/*[clinic input]
8621os.pipe2
8622
8623 flags: int
8624 /
8625
8626Create a pipe with flags set atomically.
8627
8628Returns a tuple of two file descriptors:
8629 (read_fd, write_fd)
8630
8631flags can be constructed by ORing together one or more of these values:
8632O_NONBLOCK, O_CLOEXEC.
8633[clinic start generated code]*/
8634
Larry Hastings2f936352014-08-05 14:04:04 +10008635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008636os_pipe2_impl(PyObject *module, int flags)
8637/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008638{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008639 int fds[2];
8640 int res;
8641
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008642 res = pipe2(fds, flags);
8643 if (res != 0)
8644 return posix_error();
8645 return Py_BuildValue("(ii)", fds[0], fds[1]);
8646}
8647#endif /* HAVE_PIPE2 */
8648
Larry Hastings2f936352014-08-05 14:04:04 +10008649
Ross Lagerwall7807c352011-03-17 20:20:30 +02008650#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008651/*[clinic input]
8652os.writev -> Py_ssize_t
8653 fd: int
8654 buffers: object
8655 /
8656
8657Iterate over buffers, and write the contents of each to a file descriptor.
8658
8659Returns the total number of bytes written.
8660buffers must be a sequence of bytes-like objects.
8661[clinic start generated code]*/
8662
Larry Hastings2f936352014-08-05 14:04:04 +10008663static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008664os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8665/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008666{
8667 int cnt;
8668 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008669 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008670 struct iovec *iov;
8671 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008672
8673 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008674 PyErr_SetString(PyExc_TypeError,
8675 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008676 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008677 }
Larry Hastings2f936352014-08-05 14:04:04 +10008678 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008679
Larry Hastings2f936352014-08-05 14:04:04 +10008680 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8681 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008682 }
8683
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684 do {
8685 Py_BEGIN_ALLOW_THREADS
8686 result = writev(fd, iov, cnt);
8687 Py_END_ALLOW_THREADS
8688 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008689
8690 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008691 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008692 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008693
Georg Brandl306336b2012-06-24 12:55:33 +02008694 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008695}
Larry Hastings2f936352014-08-05 14:04:04 +10008696#endif /* HAVE_WRITEV */
8697
8698
8699#ifdef HAVE_PWRITE
8700/*[clinic input]
8701os.pwrite -> Py_ssize_t
8702
8703 fd: int
8704 buffer: Py_buffer
8705 offset: Py_off_t
8706 /
8707
8708Write bytes to a file descriptor starting at a particular offset.
8709
8710Write buffer to fd, starting at offset bytes from the beginning of
8711the file. Returns the number of bytes writte. Does not change the
8712current file offset.
8713[clinic start generated code]*/
8714
Larry Hastings2f936352014-08-05 14:04:04 +10008715static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008716os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8717/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008718{
8719 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008720 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008721
8722 if (!_PyVerify_fd(fd)) {
8723 posix_error();
8724 return -1;
8725 }
8726
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008727 do {
8728 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008729 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008730 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008731 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008732 Py_END_ALLOW_THREADS
8733 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008734
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008735 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008736 posix_error();
8737 return size;
8738}
8739#endif /* HAVE_PWRITE */
8740
8741
8742#ifdef HAVE_MKFIFO
8743/*[clinic input]
8744os.mkfifo
8745
8746 path: path_t
8747 mode: int=0o666
8748 *
8749 dir_fd: dir_fd(requires='mkfifoat')=None
8750
8751Create a "fifo" (a POSIX named pipe).
8752
8753If dir_fd is not None, it should be a file descriptor open to a directory,
8754 and path should be relative; path will then be relative to that directory.
8755dir_fd may not be implemented on your platform.
8756 If it is unavailable, using it will raise a NotImplementedError.
8757[clinic start generated code]*/
8758
Larry Hastings2f936352014-08-05 14:04:04 +10008759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008760os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8761/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008762{
8763 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008764 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008765
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008766 do {
8767 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008768#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008769 if (dir_fd != DEFAULT_DIR_FD)
8770 result = mkfifoat(dir_fd, path->narrow, mode);
8771 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008772#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008773 result = mkfifo(path->narrow, mode);
8774 Py_END_ALLOW_THREADS
8775 } while (result != 0 && errno == EINTR &&
8776 !(async_err = PyErr_CheckSignals()));
8777 if (result != 0)
8778 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008779
8780 Py_RETURN_NONE;
8781}
8782#endif /* HAVE_MKFIFO */
8783
8784
8785#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8786/*[clinic input]
8787os.mknod
8788
8789 path: path_t
8790 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008791 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008792 *
8793 dir_fd: dir_fd(requires='mknodat')=None
8794
8795Create a node in the file system.
8796
8797Create a node in the file system (file, device special file or named pipe)
8798at path. mode specifies both the permissions to use and the
8799type of node to be created, being combined (bitwise OR) with one of
8800S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8801device defines the newly created device special file (probably using
8802os.makedev()). Otherwise device is ignored.
8803
8804If dir_fd is not None, it should be a file descriptor open to a directory,
8805 and path should be relative; path will then be relative to that directory.
8806dir_fd may not be implemented on your platform.
8807 If it is unavailable, using it will raise a NotImplementedError.
8808[clinic start generated code]*/
8809
Larry Hastings2f936352014-08-05 14:04:04 +10008810static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008811os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008812 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008813/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008814{
8815 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008816 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008817
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008818 do {
8819 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008820#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008821 if (dir_fd != DEFAULT_DIR_FD)
8822 result = mknodat(dir_fd, path->narrow, mode, device);
8823 else
Larry Hastings2f936352014-08-05 14:04:04 +10008824#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008825 result = mknod(path->narrow, mode, device);
8826 Py_END_ALLOW_THREADS
8827 } while (result != 0 && errno == EINTR &&
8828 !(async_err = PyErr_CheckSignals()));
8829 if (result != 0)
8830 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008831
8832 Py_RETURN_NONE;
8833}
8834#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8835
8836
8837#ifdef HAVE_DEVICE_MACROS
8838/*[clinic input]
8839os.major -> unsigned_int
8840
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008841 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008842 /
8843
8844Extracts a device major number from a raw device number.
8845[clinic start generated code]*/
8846
Larry Hastings2f936352014-08-05 14:04:04 +10008847static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008848os_major_impl(PyObject *module, dev_t device)
8849/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008850{
8851 return major(device);
8852}
8853
8854
8855/*[clinic input]
8856os.minor -> unsigned_int
8857
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008858 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008859 /
8860
8861Extracts a device minor number from a raw device number.
8862[clinic start generated code]*/
8863
Larry Hastings2f936352014-08-05 14:04:04 +10008864static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008865os_minor_impl(PyObject *module, dev_t device)
8866/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008867{
8868 return minor(device);
8869}
8870
8871
8872/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008873os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008874
8875 major: int
8876 minor: int
8877 /
8878
8879Composes a raw device number from the major and minor device numbers.
8880[clinic start generated code]*/
8881
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008882static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008883os_makedev_impl(PyObject *module, int major, int minor)
8884/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008885{
8886 return makedev(major, minor);
8887}
8888#endif /* HAVE_DEVICE_MACROS */
8889
8890
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008891#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008892/*[clinic input]
8893os.ftruncate
8894
8895 fd: int
8896 length: Py_off_t
8897 /
8898
8899Truncate a file, specified by file descriptor, to a specific length.
8900[clinic start generated code]*/
8901
Larry Hastings2f936352014-08-05 14:04:04 +10008902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008903os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8904/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008905{
8906 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008907 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008908
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008909 if (!_PyVerify_fd(fd))
8910 return posix_error();
8911
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008912 do {
8913 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008914 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008915#ifdef MS_WINDOWS
8916 result = _chsize_s(fd, length);
8917#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008918 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008919#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008920 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008921 Py_END_ALLOW_THREADS
8922 } while (result != 0 && errno == EINTR &&
8923 !(async_err = PyErr_CheckSignals()));
8924 if (result != 0)
8925 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008926 Py_RETURN_NONE;
8927}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008928#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008929
8930
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008931#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008932/*[clinic input]
8933os.truncate
8934 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8935 length: Py_off_t
8936
8937Truncate a file, specified by path, to a specific length.
8938
8939On some platforms, path may also be specified as an open file descriptor.
8940 If this functionality is unavailable, using it raises an exception.
8941[clinic start generated code]*/
8942
Larry Hastings2f936352014-08-05 14:04:04 +10008943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008944os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8945/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008946{
8947 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008948#ifdef MS_WINDOWS
8949 int fd;
8950#endif
8951
8952 if (path->fd != -1)
8953 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008954
8955 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008956 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008957#ifdef MS_WINDOWS
8958 if (path->wide)
8959 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008960 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008961 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008962 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008963 result = -1;
8964 else {
8965 result = _chsize_s(fd, length);
8966 close(fd);
8967 if (result < 0)
8968 errno = result;
8969 }
8970#else
8971 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008972#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008973 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008974 Py_END_ALLOW_THREADS
8975 if (result < 0)
8976 return path_error(path);
8977
8978 Py_RETURN_NONE;
8979}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008980#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008981
Ross Lagerwall7807c352011-03-17 20:20:30 +02008982
Victor Stinnerd6b17692014-09-30 12:20:05 +02008983/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8984 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8985 defined, which is the case in Python on AIX. AIX bug report:
8986 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8987#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8988# define POSIX_FADVISE_AIX_BUG
8989#endif
8990
Victor Stinnerec39e262014-09-30 12:35:58 +02008991
Victor Stinnerd6b17692014-09-30 12:20:05 +02008992#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008993/*[clinic input]
8994os.posix_fallocate
8995
8996 fd: int
8997 offset: Py_off_t
8998 length: Py_off_t
8999 /
9000
9001Ensure a file has allocated at least a particular number of bytes on disk.
9002
9003Ensure that the file specified by fd encompasses a range of bytes
9004starting at offset bytes from the beginning and continuing for length bytes.
9005[clinic start generated code]*/
9006
Larry Hastings2f936352014-08-05 14:04:04 +10009007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009008os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009009 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009010/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009011{
9012 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009013 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009014
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009015 do {
9016 Py_BEGIN_ALLOW_THREADS
9017 result = posix_fallocate(fd, offset, length);
9018 Py_END_ALLOW_THREADS
9019 } while (result != 0 && errno == EINTR &&
9020 !(async_err = PyErr_CheckSignals()));
9021 if (result != 0)
9022 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009023 Py_RETURN_NONE;
9024}
Victor Stinnerec39e262014-09-30 12:35:58 +02009025#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009026
Ross Lagerwall7807c352011-03-17 20:20:30 +02009027
Victor Stinnerd6b17692014-09-30 12:20:05 +02009028#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009029/*[clinic input]
9030os.posix_fadvise
9031
9032 fd: int
9033 offset: Py_off_t
9034 length: Py_off_t
9035 advice: int
9036 /
9037
9038Announce an intention to access data in a specific pattern.
9039
9040Announce an intention to access data in a specific pattern, thus allowing
9041the kernel to make optimizations.
9042The advice applies to the region of the file specified by fd starting at
9043offset and continuing for length bytes.
9044advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9045POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9046POSIX_FADV_DONTNEED.
9047[clinic start generated code]*/
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009050os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009051 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009052/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009053{
9054 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009055 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009056
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009057 do {
9058 Py_BEGIN_ALLOW_THREADS
9059 result = posix_fadvise(fd, offset, length, advice);
9060 Py_END_ALLOW_THREADS
9061 } while (result != 0 && errno == EINTR &&
9062 !(async_err = PyErr_CheckSignals()));
9063 if (result != 0)
9064 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009065 Py_RETURN_NONE;
9066}
Victor Stinnerec39e262014-09-30 12:35:58 +02009067#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009068
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009069#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009070
Fred Drake762e2061999-08-26 17:23:54 +00009071/* Save putenv() parameters as values here, so we can collect them when they
9072 * get re-set with another call for the same key. */
9073static PyObject *posix_putenv_garbage;
9074
Larry Hastings2f936352014-08-05 14:04:04 +10009075static void
9076posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009077{
Larry Hastings2f936352014-08-05 14:04:04 +10009078 /* Install the first arg and newstr in posix_putenv_garbage;
9079 * this will cause previous value to be collected. This has to
9080 * happen after the real putenv() call because the old value
9081 * was still accessible until then. */
9082 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9083 /* really not much we can do; just leak */
9084 PyErr_Clear();
9085 else
9086 Py_DECREF(value);
9087}
9088
9089
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009090#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009091/*[clinic input]
9092os.putenv
9093
9094 name: unicode
9095 value: unicode
9096 /
9097
9098Change or add an environment variable.
9099[clinic start generated code]*/
9100
Larry Hastings2f936352014-08-05 14:04:04 +10009101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009102os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9103/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009104{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009105 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10009106
9107 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9108 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009109 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009110 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009111 }
Larry Hastings2f936352014-08-05 14:04:04 +10009112 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009113 PyErr_Format(PyExc_ValueError,
9114 "the environment variable is longer than %u characters",
9115 _MAX_ENV);
9116 goto error;
9117 }
9118
Larry Hastings2f936352014-08-05 14:04:04 +10009119 env = PyUnicode_AsUnicode(unicode);
9120 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009121 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009122 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009124 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009126
Larry Hastings2f936352014-08-05 14:04:04 +10009127 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009128 Py_RETURN_NONE;
9129
9130error:
Larry Hastings2f936352014-08-05 14:04:04 +10009131 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009132 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009133}
Larry Hastings2f936352014-08-05 14:04:04 +10009134#else /* MS_WINDOWS */
9135/*[clinic input]
9136os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009137
Larry Hastings2f936352014-08-05 14:04:04 +10009138 name: FSConverter
9139 value: FSConverter
9140 /
9141
9142Change or add an environment variable.
9143[clinic start generated code]*/
9144
Larry Hastings2f936352014-08-05 14:04:04 +10009145static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009146os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9147/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009148{
9149 PyObject *bytes = NULL;
9150 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009151 const char *name_string = PyBytes_AsString(name);
9152 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009153
9154 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9155 if (bytes == NULL) {
9156 PyErr_NoMemory();
9157 return NULL;
9158 }
9159
9160 env = PyBytes_AS_STRING(bytes);
9161 if (putenv(env)) {
9162 Py_DECREF(bytes);
9163 return posix_error();
9164 }
9165
9166 posix_putenv_garbage_setitem(name, bytes);
9167 Py_RETURN_NONE;
9168}
9169#endif /* MS_WINDOWS */
9170#endif /* HAVE_PUTENV */
9171
9172
9173#ifdef HAVE_UNSETENV
9174/*[clinic input]
9175os.unsetenv
9176 name: FSConverter
9177 /
9178
9179Delete an environment variable.
9180[clinic start generated code]*/
9181
Larry Hastings2f936352014-08-05 14:04:04 +10009182static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009183os_unsetenv_impl(PyObject *module, PyObject *name)
9184/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009185{
Victor Stinner984890f2011-11-24 13:53:38 +01009186#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009187 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009188#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009189
Victor Stinner984890f2011-11-24 13:53:38 +01009190#ifdef HAVE_BROKEN_UNSETENV
9191 unsetenv(PyBytes_AS_STRING(name));
9192#else
Victor Stinner65170952011-11-22 22:16:17 +01009193 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009194 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009195 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009196#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009197
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 /* Remove the key from posix_putenv_garbage;
9199 * this will cause it to be collected. This has to
9200 * happen after the real unsetenv() call because the
9201 * old value was still accessible until then.
9202 */
Victor Stinner65170952011-11-22 22:16:17 +01009203 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 /* really not much we can do; just leak */
9205 PyErr_Clear();
9206 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009207 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009208}
Larry Hastings2f936352014-08-05 14:04:04 +10009209#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009210
Larry Hastings2f936352014-08-05 14:04:04 +10009211
9212/*[clinic input]
9213os.strerror
9214
9215 code: int
9216 /
9217
9218Translate an error code to a message string.
9219[clinic start generated code]*/
9220
Larry Hastings2f936352014-08-05 14:04:04 +10009221static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009222os_strerror_impl(PyObject *module, int code)
9223/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009224{
9225 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 if (message == NULL) {
9227 PyErr_SetString(PyExc_ValueError,
9228 "strerror() argument out of range");
9229 return NULL;
9230 }
Victor Stinner1b579672011-12-17 05:47:23 +01009231 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009232}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009233
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009234
Guido van Rossumc9641791998-08-04 15:26:23 +00009235#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009236#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009237/*[clinic input]
9238os.WCOREDUMP -> bool
9239
9240 status: int
9241 /
9242
9243Return True if the process returning status was dumped to a core file.
9244[clinic start generated code]*/
9245
Larry Hastings2f936352014-08-05 14:04:04 +10009246static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009247os_WCOREDUMP_impl(PyObject *module, int status)
9248/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009249{
9250 WAIT_TYPE wait_status;
9251 WAIT_STATUS_INT(wait_status) = status;
9252 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009253}
9254#endif /* WCOREDUMP */
9255
Larry Hastings2f936352014-08-05 14:04:04 +10009256
Fred Drake106c1a02002-04-23 15:58:02 +00009257#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009258/*[clinic input]
9259os.WIFCONTINUED -> bool
9260
9261 status: int
9262
9263Return True if a particular process was continued from a job control stop.
9264
9265Return True if the process returning status was continued from a
9266job control stop.
9267[clinic start generated code]*/
9268
Larry Hastings2f936352014-08-05 14:04:04 +10009269static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009270os_WIFCONTINUED_impl(PyObject *module, int status)
9271/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009272{
9273 WAIT_TYPE wait_status;
9274 WAIT_STATUS_INT(wait_status) = status;
9275 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009276}
9277#endif /* WIFCONTINUED */
9278
Larry Hastings2f936352014-08-05 14:04:04 +10009279
Guido van Rossumc9641791998-08-04 15:26:23 +00009280#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009281/*[clinic input]
9282os.WIFSTOPPED -> bool
9283
9284 status: int
9285
9286Return True if the process returning status was stopped.
9287[clinic start generated code]*/
9288
Larry Hastings2f936352014-08-05 14:04:04 +10009289static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009290os_WIFSTOPPED_impl(PyObject *module, int status)
9291/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009292{
9293 WAIT_TYPE wait_status;
9294 WAIT_STATUS_INT(wait_status) = status;
9295 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009296}
9297#endif /* WIFSTOPPED */
9298
Larry Hastings2f936352014-08-05 14:04:04 +10009299
Guido van Rossumc9641791998-08-04 15:26:23 +00009300#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009301/*[clinic input]
9302os.WIFSIGNALED -> bool
9303
9304 status: int
9305
9306Return True if the process returning status was terminated by a signal.
9307[clinic start generated code]*/
9308
Larry Hastings2f936352014-08-05 14:04:04 +10009309static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009310os_WIFSIGNALED_impl(PyObject *module, int status)
9311/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009312{
9313 WAIT_TYPE wait_status;
9314 WAIT_STATUS_INT(wait_status) = status;
9315 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009316}
9317#endif /* WIFSIGNALED */
9318
Larry Hastings2f936352014-08-05 14:04:04 +10009319
Guido van Rossumc9641791998-08-04 15:26:23 +00009320#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009321/*[clinic input]
9322os.WIFEXITED -> bool
9323
9324 status: int
9325
9326Return True if the process returning status exited via the exit() system call.
9327[clinic start generated code]*/
9328
Larry Hastings2f936352014-08-05 14:04:04 +10009329static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009330os_WIFEXITED_impl(PyObject *module, int status)
9331/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009332{
9333 WAIT_TYPE wait_status;
9334 WAIT_STATUS_INT(wait_status) = status;
9335 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009336}
9337#endif /* WIFEXITED */
9338
Larry Hastings2f936352014-08-05 14:04:04 +10009339
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009340#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009341/*[clinic input]
9342os.WEXITSTATUS -> int
9343
9344 status: int
9345
9346Return the process return code from status.
9347[clinic start generated code]*/
9348
Larry Hastings2f936352014-08-05 14:04:04 +10009349static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009350os_WEXITSTATUS_impl(PyObject *module, int status)
9351/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009352{
9353 WAIT_TYPE wait_status;
9354 WAIT_STATUS_INT(wait_status) = status;
9355 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009356}
9357#endif /* WEXITSTATUS */
9358
Larry Hastings2f936352014-08-05 14:04:04 +10009359
Guido van Rossumc9641791998-08-04 15:26:23 +00009360#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009361/*[clinic input]
9362os.WTERMSIG -> int
9363
9364 status: int
9365
9366Return the signal that terminated the process that provided the status value.
9367[clinic start generated code]*/
9368
Larry Hastings2f936352014-08-05 14:04:04 +10009369static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009370os_WTERMSIG_impl(PyObject *module, int status)
9371/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009372{
9373 WAIT_TYPE wait_status;
9374 WAIT_STATUS_INT(wait_status) = status;
9375 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009376}
9377#endif /* WTERMSIG */
9378
Larry Hastings2f936352014-08-05 14:04:04 +10009379
Guido van Rossumc9641791998-08-04 15:26:23 +00009380#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009381/*[clinic input]
9382os.WSTOPSIG -> int
9383
9384 status: int
9385
9386Return the signal that stopped the process that provided the status value.
9387[clinic start generated code]*/
9388
Larry Hastings2f936352014-08-05 14:04:04 +10009389static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009390os_WSTOPSIG_impl(PyObject *module, int status)
9391/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009392{
9393 WAIT_TYPE wait_status;
9394 WAIT_STATUS_INT(wait_status) = status;
9395 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009396}
9397#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009398#endif /* HAVE_SYS_WAIT_H */
9399
9400
Thomas Wouters477c8d52006-05-27 19:21:47 +00009401#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009402#ifdef _SCO_DS
9403/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9404 needed definitions in sys/statvfs.h */
9405#define _SVID3
9406#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009407#include <sys/statvfs.h>
9408
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009409static PyObject*
9410_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9412 if (v == NULL)
9413 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009414
9415#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9417 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9418 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9419 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9420 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9421 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9422 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9423 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9424 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9425 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009426#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9428 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9429 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009430 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009431 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009432 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009434 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009436 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009437 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009438 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009440 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9442 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009443#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009444 if (PyErr_Occurred()) {
9445 Py_DECREF(v);
9446 return NULL;
9447 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009448
Victor Stinner8c62be82010-05-06 00:08:46 +00009449 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009450}
9451
Larry Hastings2f936352014-08-05 14:04:04 +10009452
9453/*[clinic input]
9454os.fstatvfs
9455 fd: int
9456 /
9457
9458Perform an fstatvfs system call on the given fd.
9459
9460Equivalent to statvfs(fd).
9461[clinic start generated code]*/
9462
Larry Hastings2f936352014-08-05 14:04:04 +10009463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009464os_fstatvfs_impl(PyObject *module, int fd)
9465/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009466{
9467 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009468 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009470
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009471 do {
9472 Py_BEGIN_ALLOW_THREADS
9473 result = fstatvfs(fd, &st);
9474 Py_END_ALLOW_THREADS
9475 } while (result != 0 && errno == EINTR &&
9476 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009477 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009478 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009479
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009481}
Larry Hastings2f936352014-08-05 14:04:04 +10009482#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009483
9484
Thomas Wouters477c8d52006-05-27 19:21:47 +00009485#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009486#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009487/*[clinic input]
9488os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009489
Larry Hastings2f936352014-08-05 14:04:04 +10009490 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9491
9492Perform a statvfs system call on the given path.
9493
9494path may always be specified as a string.
9495On some platforms, path may also be specified as an open file descriptor.
9496 If this functionality is unavailable, using it raises an exception.
9497[clinic start generated code]*/
9498
Larry Hastings2f936352014-08-05 14:04:04 +10009499static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009500os_statvfs_impl(PyObject *module, path_t *path)
9501/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009502{
9503 int result;
9504 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009505
9506 Py_BEGIN_ALLOW_THREADS
9507#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009508 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009509#ifdef __APPLE__
9510 /* handle weak-linking on Mac OS X 10.3 */
9511 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009512 fd_specified("statvfs", path->fd);
9513 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009514 }
9515#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009516 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009517 }
9518 else
9519#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009520 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009521 Py_END_ALLOW_THREADS
9522
9523 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009524 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009525 }
9526
Larry Hastings2f936352014-08-05 14:04:04 +10009527 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009528}
Larry Hastings2f936352014-08-05 14:04:04 +10009529#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9530
Guido van Rossum94f6f721999-01-06 18:42:14 +00009531
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009532#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009533/*[clinic input]
9534os._getdiskusage
9535
9536 path: Py_UNICODE
9537
9538Return disk usage statistics about the given path as a (total, free) tuple.
9539[clinic start generated code]*/
9540
Larry Hastings2f936352014-08-05 14:04:04 +10009541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009542os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9543/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009544{
9545 BOOL retval;
9546 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009547
9548 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009549 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009550 Py_END_ALLOW_THREADS
9551 if (retval == 0)
9552 return PyErr_SetFromWindowsErr(0);
9553
9554 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9555}
Larry Hastings2f936352014-08-05 14:04:04 +10009556#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009557
9558
Fred Drakec9680921999-12-13 16:37:25 +00009559/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9560 * It maps strings representing configuration variable names to
9561 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009562 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009563 * rarely-used constants. There are three separate tables that use
9564 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009565 *
9566 * This code is always included, even if none of the interfaces that
9567 * need it are included. The #if hackery needed to avoid it would be
9568 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009569 */
9570struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009571 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009572 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009573};
9574
Fred Drake12c6e2d1999-12-14 21:25:03 +00009575static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009576conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009577 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009578{
Christian Heimes217cfd12007-12-02 14:31:20 +00009579 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009580 int value = _PyLong_AsInt(arg);
9581 if (value == -1 && PyErr_Occurred())
9582 return 0;
9583 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009584 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009585 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009586 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009587 /* look up the value in the table using a binary search */
9588 size_t lo = 0;
9589 size_t mid;
9590 size_t hi = tablesize;
9591 int cmp;
9592 const char *confname;
9593 if (!PyUnicode_Check(arg)) {
9594 PyErr_SetString(PyExc_TypeError,
9595 "configuration names must be strings or integers");
9596 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009598 confname = _PyUnicode_AsString(arg);
9599 if (confname == NULL)
9600 return 0;
9601 while (lo < hi) {
9602 mid = (lo + hi) / 2;
9603 cmp = strcmp(confname, table[mid].name);
9604 if (cmp < 0)
9605 hi = mid;
9606 else if (cmp > 0)
9607 lo = mid + 1;
9608 else {
9609 *valuep = table[mid].value;
9610 return 1;
9611 }
9612 }
9613 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9614 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009616}
9617
9618
9619#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9620static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009621#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009623#endif
9624#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009626#endif
Fred Drakec9680921999-12-13 16:37:25 +00009627#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
9648#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
9657#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
9669#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009671#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009672#ifdef _PC_ACL_ENABLED
9673 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9674#endif
9675#ifdef _PC_MIN_HOLE_SIZE
9676 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9677#endif
9678#ifdef _PC_ALLOC_SIZE_MIN
9679 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9680#endif
9681#ifdef _PC_REC_INCR_XFER_SIZE
9682 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9683#endif
9684#ifdef _PC_REC_MAX_XFER_SIZE
9685 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9686#endif
9687#ifdef _PC_REC_MIN_XFER_SIZE
9688 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9689#endif
9690#ifdef _PC_REC_XFER_ALIGN
9691 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9692#endif
9693#ifdef _PC_SYMLINK_MAX
9694 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9695#endif
9696#ifdef _PC_XATTR_ENABLED
9697 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9698#endif
9699#ifdef _PC_XATTR_EXISTS
9700 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9701#endif
9702#ifdef _PC_TIMESTAMP_RESOLUTION
9703 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9704#endif
Fred Drakec9680921999-12-13 16:37:25 +00009705};
9706
Fred Drakec9680921999-12-13 16:37:25 +00009707static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009708conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009709{
9710 return conv_confname(arg, valuep, posix_constants_pathconf,
9711 sizeof(posix_constants_pathconf)
9712 / sizeof(struct constdef));
9713}
9714#endif
9715
Larry Hastings2f936352014-08-05 14:04:04 +10009716
Fred Drakec9680921999-12-13 16:37:25 +00009717#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009718/*[clinic input]
9719os.fpathconf -> long
9720
9721 fd: int
9722 name: path_confname
9723 /
9724
9725Return the configuration limit name for the file descriptor fd.
9726
9727If there is no limit, return -1.
9728[clinic start generated code]*/
9729
Larry Hastings2f936352014-08-05 14:04:04 +10009730static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009731os_fpathconf_impl(PyObject *module, int fd, int name)
9732/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009733{
9734 long limit;
9735
9736 errno = 0;
9737 limit = fpathconf(fd, name);
9738 if (limit == -1 && errno != 0)
9739 posix_error();
9740
9741 return limit;
9742}
9743#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009744
9745
9746#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009747/*[clinic input]
9748os.pathconf -> long
9749 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9750 name: path_confname
9751
9752Return the configuration limit name for the file or directory path.
9753
9754If there is no limit, return -1.
9755On some platforms, path may also be specified as an open file descriptor.
9756 If this functionality is unavailable, using it raises an exception.
9757[clinic start generated code]*/
9758
Larry Hastings2f936352014-08-05 14:04:04 +10009759static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009760os_pathconf_impl(PyObject *module, path_t *path, int name)
9761/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009762{
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009764
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009766#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009767 if (path->fd != -1)
9768 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009769 else
9770#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009771 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 if (limit == -1 && errno != 0) {
9773 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009774 /* could be a path or name problem */
9775 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009776 else
Larry Hastings2f936352014-08-05 14:04:04 +10009777 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 }
Larry Hastings2f936352014-08-05 14:04:04 +10009779
9780 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009781}
Larry Hastings2f936352014-08-05 14:04:04 +10009782#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009783
9784#ifdef HAVE_CONFSTR
9785static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009786#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009788#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009789#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009791#endif
9792#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009794#endif
Fred Draked86ed291999-12-15 15:34:33 +00009795#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009797#endif
9798#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009800#endif
9801#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009803#endif
9804#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009806#endif
Fred Drakec9680921999-12-13 16:37:25 +00009807#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
Fred Draked86ed291999-12-15 15:34:33 +00009831#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009833#endif
Fred Drakec9680921999-12-13 16:37:25 +00009834#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
Fred Draked86ed291999-12-15 15:34:33 +00009837#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009839#endif
9840#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009842#endif
9843#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009845#endif
9846#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009848#endif
Fred Drakec9680921999-12-13 16:37:25 +00009849#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
Fred Draked86ed291999-12-15 15:34:33 +00009897#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009899#endif
9900#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009902#endif
9903#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009905#endif
9906#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009908#endif
9909#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009911#endif
9912#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009914#endif
9915#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009917#endif
9918#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009920#endif
9921#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009923#endif
9924#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009926#endif
9927#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009929#endif
9930#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009932#endif
9933#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009935#endif
Fred Drakec9680921999-12-13 16:37:25 +00009936};
9937
9938static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009939conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009940{
9941 return conv_confname(arg, valuep, posix_constants_confstr,
9942 sizeof(posix_constants_confstr)
9943 / sizeof(struct constdef));
9944}
9945
Larry Hastings2f936352014-08-05 14:04:04 +10009946
9947/*[clinic input]
9948os.confstr
9949
9950 name: confstr_confname
9951 /
9952
9953Return a string-valued system configuration variable.
9954[clinic start generated code]*/
9955
Larry Hastings2f936352014-08-05 14:04:04 +10009956static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009957os_confstr_impl(PyObject *module, int name)
9958/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009959{
9960 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009961 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009962 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009963
Victor Stinnercb043522010-09-10 23:49:04 +00009964 errno = 0;
9965 len = confstr(name, buffer, sizeof(buffer));
9966 if (len == 0) {
9967 if (errno) {
9968 posix_error();
9969 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009970 }
9971 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009972 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009973 }
9974 }
Victor Stinnercb043522010-09-10 23:49:04 +00009975
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009976 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009977 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009978 char *buf = PyMem_Malloc(len);
9979 if (buf == NULL)
9980 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009981 len2 = confstr(name, buf, len);
9982 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009983 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009984 PyMem_Free(buf);
9985 }
9986 else
9987 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009988 return result;
9989}
Larry Hastings2f936352014-08-05 14:04:04 +10009990#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009991
9992
9993#ifdef HAVE_SYSCONF
9994static struct constdef posix_constants_sysconf[] = {
9995#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
Fred Draked86ed291999-12-15 15:34:33 +000010025#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010027#endif
10028#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010030#endif
Fred Drakec9680921999-12-13 16:37:25 +000010031#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
Fred Drakec9680921999-12-13 16:37:25 +000010034#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
Fred Draked86ed291999-12-15 15:34:33 +000010049#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010051#endif
Fred Drakec9680921999-12-13 16:37:25 +000010052#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
Fred Draked86ed291999-12-15 15:34:33 +000010067#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010069#endif
Fred Drakec9680921999-12-13 16:37:25 +000010070#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
Fred Draked86ed291999-12-15 15:34:33 +000010139#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010141#endif
Fred Drakec9680921999-12-13 16:37:25 +000010142#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
Fred Draked86ed291999-12-15 15:34:33 +000010151#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010153#endif
Fred Drakec9680921999-12-13 16:37:25 +000010154#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
Fred Draked86ed291999-12-15 15:34:33 +000010157#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010159#endif
10160#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010162#endif
Fred Drakec9680921999-12-13 16:37:25 +000010163#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
Fred Draked86ed291999-12-15 15:34:33 +000010175#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010177#endif
Fred Drakec9680921999-12-13 16:37:25 +000010178#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
Fred Draked86ed291999-12-15 15:34:33 +000010199#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010201#endif
Fred Drakec9680921999-12-13 16:37:25 +000010202#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
Fred Draked86ed291999-12-15 15:34:33 +000010208#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010210#endif
Fred Drakec9680921999-12-13 16:37:25 +000010211#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
Fred Draked86ed291999-12-15 15:34:33 +000010238#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010240#endif
10241#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010243#endif
Fred Drakec9680921999-12-13 16:37:25 +000010244#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
Fred Draked86ed291999-12-15 15:34:33 +000010349#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010351#endif
Fred Drakec9680921999-12-13 16:37:25 +000010352#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010417#endif
10418#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010420#endif
10421#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010423#endif
10424#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010426#endif
10427#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010429#endif
10430#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010432#endif
10433#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010435#endif
10436#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010438#endif
10439#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010441#endif
10442#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010444#endif
10445#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010447#endif
10448#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010450#endif
10451#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010453#endif
10454#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010456#endif
10457#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010459#endif
10460#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010462#endif
10463#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010465#endif
10466#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010468#endif
10469#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010471#endif
10472#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010474#endif
10475#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010477#endif
10478#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010479 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010480#endif
10481#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010483#endif
10484#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010486#endif
10487};
10488
10489static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010490conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010491{
10492 return conv_confname(arg, valuep, posix_constants_sysconf,
10493 sizeof(posix_constants_sysconf)
10494 / sizeof(struct constdef));
10495}
10496
Larry Hastings2f936352014-08-05 14:04:04 +100010497
10498/*[clinic input]
10499os.sysconf -> long
10500 name: sysconf_confname
10501 /
10502
10503Return an integer-valued system configuration variable.
10504[clinic start generated code]*/
10505
Larry Hastings2f936352014-08-05 14:04:04 +100010506static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010507os_sysconf_impl(PyObject *module, int name)
10508/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010509{
10510 long value;
10511
10512 errno = 0;
10513 value = sysconf(name);
10514 if (value == -1 && errno != 0)
10515 posix_error();
10516 return value;
10517}
10518#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010519
10520
Fred Drakebec628d1999-12-15 18:31:10 +000010521/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010522 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010523 * the exported dictionaries that are used to publish information about the
10524 * names available on the host platform.
10525 *
10526 * Sorting the table at runtime ensures that the table is properly ordered
10527 * when used, even for platforms we're not able to test on. It also makes
10528 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010529 */
Fred Drakebec628d1999-12-15 18:31:10 +000010530
10531static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010532cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010533{
10534 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010536 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010538
10539 return strcmp(c1->name, c2->name);
10540}
10541
10542static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010543setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010544 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010545{
Fred Drakebec628d1999-12-15 18:31:10 +000010546 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010547 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010548
10549 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10550 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010551 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010553
Barry Warsaw3155db32000-04-13 15:20:40 +000010554 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 PyObject *o = PyLong_FromLong(table[i].value);
10556 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10557 Py_XDECREF(o);
10558 Py_DECREF(d);
10559 return -1;
10560 }
10561 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010562 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010563 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010564}
10565
Fred Drakebec628d1999-12-15 18:31:10 +000010566/* Return -1 on failure, 0 on success. */
10567static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010568setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010569{
10570#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010571 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010572 sizeof(posix_constants_pathconf)
10573 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010574 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010575 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010576#endif
10577#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010578 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010579 sizeof(posix_constants_confstr)
10580 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010581 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010582 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010583#endif
10584#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010585 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010586 sizeof(posix_constants_sysconf)
10587 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010588 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010589 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010590#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010591 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010592}
Fred Draked86ed291999-12-15 15:34:33 +000010593
10594
Larry Hastings2f936352014-08-05 14:04:04 +100010595/*[clinic input]
10596os.abort
10597
10598Abort the interpreter immediately.
10599
10600This function 'dumps core' or otherwise fails in the hardest way possible
10601on the hosting operating system. This function never returns.
10602[clinic start generated code]*/
10603
Larry Hastings2f936352014-08-05 14:04:04 +100010604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010605os_abort_impl(PyObject *module)
10606/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010607{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010608 abort();
10609 /*NOTREACHED*/
10610 Py_FatalError("abort() called from Python code didn't abort!");
10611 return NULL;
10612}
Fred Drakebec628d1999-12-15 18:31:10 +000010613
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010614#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010615/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010616PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010617"startfile(filepath [, operation])\n\
10618\n\
10619Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010620\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010621When \"operation\" is not specified or \"open\", this acts like\n\
10622double-clicking the file in Explorer, or giving the file name as an\n\
10623argument to the DOS \"start\" command: the file is opened with whatever\n\
10624application (if any) its extension is associated.\n\
10625When another \"operation\" is given, it specifies what should be done with\n\
10626the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010627\n\
10628startfile returns as soon as the associated application is launched.\n\
10629There is no option to wait for the application to close, and no way\n\
10630to retrieve the application's exit status.\n\
10631\n\
10632The filepath is relative to the current directory. If you want to use\n\
10633an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010634the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010635
Steve Dower7d0e0c92015-01-24 08:18:24 -080010636/* Grab ShellExecute dynamically from shell32 */
10637static int has_ShellExecute = -1;
10638static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10639 LPCSTR, INT);
10640static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10641 LPCWSTR, INT);
10642static int
10643check_ShellExecute()
10644{
10645 HINSTANCE hShell32;
10646
10647 /* only recheck */
10648 if (-1 == has_ShellExecute) {
10649 Py_BEGIN_ALLOW_THREADS
10650 hShell32 = LoadLibraryW(L"SHELL32");
10651 Py_END_ALLOW_THREADS
10652 if (hShell32) {
10653 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10654 "ShellExecuteA");
10655 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10656 "ShellExecuteW");
10657 has_ShellExecute = Py_ShellExecuteA &&
10658 Py_ShellExecuteW;
10659 } else {
10660 has_ShellExecute = 0;
10661 }
10662 }
10663 return has_ShellExecute;
10664}
10665
10666
Tim Petersf58a7aa2000-09-22 10:05:54 +000010667static PyObject *
10668win32_startfile(PyObject *self, PyObject *args)
10669{
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 PyObject *ofilepath;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010671 const char *filepath;
10672 const char *operation = NULL;
10673 const wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010674 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010675
Victor Stinnereb5657a2011-09-30 01:44:27 +020010676 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010677
10678 if(!check_ShellExecute()) {
10679 /* If the OS doesn't have ShellExecute, return a
10680 NotImplementedError. */
10681 return PyErr_Format(PyExc_NotImplementedError,
10682 "startfile not available on this platform");
10683 }
10684
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 if (!PyArg_ParseTuple(args, "U|s:startfile",
10686 &unipath, &operation)) {
10687 PyErr_Clear();
10688 goto normal;
10689 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010690
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010692 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010694 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 PyErr_Clear();
10696 operation = NULL;
10697 goto normal;
10698 }
10699 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010700
Victor Stinnereb5657a2011-09-30 01:44:27 +020010701 wpath = PyUnicode_AsUnicode(unipath);
10702 if (wpath == NULL)
10703 goto normal;
10704 if (uoperation) {
10705 woperation = PyUnicode_AsUnicode(uoperation);
10706 if (woperation == NULL)
10707 goto normal;
10708 }
10709 else
10710 woperation = NULL;
10711
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010713 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10714 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 Py_END_ALLOW_THREADS
10716
Victor Stinnereb5657a2011-09-30 01:44:27 +020010717 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010719 win32_error_object("startfile", unipath);
10720 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 }
10722 Py_INCREF(Py_None);
10723 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010724
10725normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10727 PyUnicode_FSConverter, &ofilepath,
10728 &operation))
10729 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010730 if (win32_warn_bytes_api()) {
10731 Py_DECREF(ofilepath);
10732 return NULL;
10733 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 filepath = PyBytes_AsString(ofilepath);
10735 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010736 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10737 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 Py_END_ALLOW_THREADS
10739 if (rc <= (HINSTANCE)32) {
10740 PyObject *errval = win32_error("startfile", filepath);
10741 Py_DECREF(ofilepath);
10742 return errval;
10743 }
10744 Py_DECREF(ofilepath);
10745 Py_INCREF(Py_None);
10746 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010747}
Larry Hastings2f936352014-08-05 14:04:04 +100010748#endif /* MS_WINDOWS */
10749
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010750
Martin v. Löwis438b5342002-12-27 10:16:42 +000010751#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010752/*[clinic input]
10753os.getloadavg
10754
10755Return average recent system load information.
10756
10757Return the number of processes in the system run queue averaged over
10758the last 1, 5, and 15 minutes as a tuple of three floats.
10759Raises OSError if the load average was unobtainable.
10760[clinic start generated code]*/
10761
Larry Hastings2f936352014-08-05 14:04:04 +100010762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010763os_getloadavg_impl(PyObject *module)
10764/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010765{
10766 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010767 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010768 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10769 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010770 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010771 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010772}
Larry Hastings2f936352014-08-05 14:04:04 +100010773#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010774
Larry Hastings2f936352014-08-05 14:04:04 +100010775
10776/*[clinic input]
10777os.device_encoding
10778 fd: int
10779
10780Return a string describing the encoding of a terminal's file descriptor.
10781
10782The file descriptor must be attached to a terminal.
10783If the device is not a terminal, return None.
10784[clinic start generated code]*/
10785
Larry Hastings2f936352014-08-05 14:04:04 +100010786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010787os_device_encoding_impl(PyObject *module, int fd)
10788/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010789{
Brett Cannonefb00c02012-02-29 18:31:31 -050010790 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010791}
10792
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010793
Larry Hastings2f936352014-08-05 14:04:04 +100010794#ifdef HAVE_SETRESUID
10795/*[clinic input]
10796os.setresuid
10797
10798 ruid: uid_t
10799 euid: uid_t
10800 suid: uid_t
10801 /
10802
10803Set the current process's real, effective, and saved user ids.
10804[clinic start generated code]*/
10805
Larry Hastings2f936352014-08-05 14:04:04 +100010806static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010807os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10808/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010809{
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 if (setresuid(ruid, euid, suid) < 0)
10811 return posix_error();
10812 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010813}
Larry Hastings2f936352014-08-05 14:04:04 +100010814#endif /* HAVE_SETRESUID */
10815
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010816
10817#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010818/*[clinic input]
10819os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010820
Larry Hastings2f936352014-08-05 14:04:04 +100010821 rgid: gid_t
10822 egid: gid_t
10823 sgid: gid_t
10824 /
10825
10826Set the current process's real, effective, and saved group ids.
10827[clinic start generated code]*/
10828
Larry Hastings2f936352014-08-05 14:04:04 +100010829static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010830os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10831/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010832{
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 if (setresgid(rgid, egid, sgid) < 0)
10834 return posix_error();
10835 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010836}
Larry Hastings2f936352014-08-05 14:04:04 +100010837#endif /* HAVE_SETRESGID */
10838
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010839
10840#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010841/*[clinic input]
10842os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010843
Larry Hastings2f936352014-08-05 14:04:04 +100010844Return a tuple of the current process's real, effective, and saved user ids.
10845[clinic start generated code]*/
10846
Larry Hastings2f936352014-08-05 14:04:04 +100010847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010848os_getresuid_impl(PyObject *module)
10849/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010850{
Victor Stinner8c62be82010-05-06 00:08:46 +000010851 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 if (getresuid(&ruid, &euid, &suid) < 0)
10853 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010854 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10855 _PyLong_FromUid(euid),
10856 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010857}
Larry Hastings2f936352014-08-05 14:04:04 +100010858#endif /* HAVE_GETRESUID */
10859
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010860
10861#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010862/*[clinic input]
10863os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010864
Larry Hastings2f936352014-08-05 14:04:04 +100010865Return a tuple of the current process's real, effective, and saved group ids.
10866[clinic start generated code]*/
10867
Larry Hastings2f936352014-08-05 14:04:04 +100010868static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010869os_getresgid_impl(PyObject *module)
10870/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010871{
10872 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 if (getresgid(&rgid, &egid, &sgid) < 0)
10874 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010875 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10876 _PyLong_FromGid(egid),
10877 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010878}
Larry Hastings2f936352014-08-05 14:04:04 +100010879#endif /* HAVE_GETRESGID */
10880
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010881
Benjamin Peterson9428d532011-09-14 11:45:52 -040010882#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010883/*[clinic input]
10884os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010885
Larry Hastings2f936352014-08-05 14:04:04 +100010886 path: path_t(allow_fd=True)
10887 attribute: path_t
10888 *
10889 follow_symlinks: bool = True
10890
10891Return the value of extended attribute attribute on path.
10892
10893path may be either a string or an open file descriptor.
10894If follow_symlinks is False, and the last element of the path is a symbolic
10895 link, getxattr will examine the symbolic link itself instead of the file
10896 the link points to.
10897
10898[clinic start generated code]*/
10899
Larry Hastings2f936352014-08-05 14:04:04 +100010900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010901os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010902 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010903/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010904{
10905 Py_ssize_t i;
10906 PyObject *buffer = NULL;
10907
10908 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10909 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910
Larry Hastings9cf065c2012-06-22 16:30:09 -070010911 for (i = 0; ; i++) {
10912 void *ptr;
10913 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010914 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010915 Py_ssize_t buffer_size = buffer_sizes[i];
10916 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010917 path_error(path);
10918 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010919 }
10920 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10921 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010922 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010923 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010924
Larry Hastings9cf065c2012-06-22 16:30:09 -070010925 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010926 if (path->fd >= 0)
10927 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010928 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010929 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010930 else
Larry Hastings2f936352014-08-05 14:04:04 +100010931 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010932 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010933
Larry Hastings9cf065c2012-06-22 16:30:09 -070010934 if (result < 0) {
10935 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010936 if (errno == ERANGE)
10937 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010938 path_error(path);
10939 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010940 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010941
Larry Hastings9cf065c2012-06-22 16:30:09 -070010942 if (result != buffer_size) {
10943 /* Can only shrink. */
10944 _PyBytes_Resize(&buffer, result);
10945 }
10946 break;
10947 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010948
Larry Hastings9cf065c2012-06-22 16:30:09 -070010949 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010950}
10951
Larry Hastings2f936352014-08-05 14:04:04 +100010952
10953/*[clinic input]
10954os.setxattr
10955
10956 path: path_t(allow_fd=True)
10957 attribute: path_t
10958 value: Py_buffer
10959 flags: int = 0
10960 *
10961 follow_symlinks: bool = True
10962
10963Set extended attribute attribute on path to value.
10964
10965path may be either a string or an open file descriptor.
10966If follow_symlinks is False, and the last element of the path is a symbolic
10967 link, setxattr will modify the symbolic link itself instead of the file
10968 the link points to.
10969
10970[clinic start generated code]*/
10971
Benjamin Peterson799bd802011-08-31 22:15:17 -040010972static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010973os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010974 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010975/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010976{
Larry Hastings2f936352014-08-05 14:04:04 +100010977 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010978
Larry Hastings2f936352014-08-05 14:04:04 +100010979 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010980 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010981
Benjamin Peterson799bd802011-08-31 22:15:17 -040010982 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010983 if (path->fd > -1)
10984 result = fsetxattr(path->fd, attribute->narrow,
10985 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010986 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010987 result = setxattr(path->narrow, attribute->narrow,
10988 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010989 else
Larry Hastings2f936352014-08-05 14:04:04 +100010990 result = lsetxattr(path->narrow, attribute->narrow,
10991 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010992 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010993
Larry Hastings9cf065c2012-06-22 16:30:09 -070010994 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010995 path_error(path);
10996 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010997 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010998
Larry Hastings2f936352014-08-05 14:04:04 +100010999 Py_RETURN_NONE;
11000}
11001
11002
11003/*[clinic input]
11004os.removexattr
11005
11006 path: path_t(allow_fd=True)
11007 attribute: path_t
11008 *
11009 follow_symlinks: bool = True
11010
11011Remove extended attribute attribute on path.
11012
11013path may be either a string or an open file descriptor.
11014If follow_symlinks is False, and the last element of the path is a symbolic
11015 link, removexattr will modify the symbolic link itself instead of the file
11016 the link points to.
11017
11018[clinic start generated code]*/
11019
Larry Hastings2f936352014-08-05 14:04:04 +100011020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011021os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011022 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011023/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011024{
11025 ssize_t result;
11026
11027 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11028 return NULL;
11029
11030 Py_BEGIN_ALLOW_THREADS;
11031 if (path->fd > -1)
11032 result = fremovexattr(path->fd, attribute->narrow);
11033 else if (follow_symlinks)
11034 result = removexattr(path->narrow, attribute->narrow);
11035 else
11036 result = lremovexattr(path->narrow, attribute->narrow);
11037 Py_END_ALLOW_THREADS;
11038
11039 if (result) {
11040 return path_error(path);
11041 }
11042
11043 Py_RETURN_NONE;
11044}
11045
11046
11047/*[clinic input]
11048os.listxattr
11049
11050 path: path_t(allow_fd=True, nullable=True) = None
11051 *
11052 follow_symlinks: bool = True
11053
11054Return a list of extended attributes on path.
11055
11056path may be either None, a string, or an open file descriptor.
11057if path is None, listxattr will examine the current directory.
11058If follow_symlinks is False, and the last element of the path is a symbolic
11059 link, listxattr will examine the symbolic link itself instead of the file
11060 the link points to.
11061[clinic start generated code]*/
11062
Larry Hastings2f936352014-08-05 14:04:04 +100011063static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011064os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11065/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011066{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011067 Py_ssize_t i;
11068 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011069 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011070 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011071
Larry Hastings2f936352014-08-05 14:04:04 +100011072 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011073 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011074
Larry Hastings2f936352014-08-05 14:04:04 +100011075 name = path->narrow ? path->narrow : ".";
11076
Larry Hastings9cf065c2012-06-22 16:30:09 -070011077 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011078 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011079 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011080 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011081 Py_ssize_t buffer_size = buffer_sizes[i];
11082 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011083 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011084 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011085 break;
11086 }
11087 buffer = PyMem_MALLOC(buffer_size);
11088 if (!buffer) {
11089 PyErr_NoMemory();
11090 break;
11091 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011092
Larry Hastings9cf065c2012-06-22 16:30:09 -070011093 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011094 if (path->fd > -1)
11095 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011096 else if (follow_symlinks)
11097 length = listxattr(name, buffer, buffer_size);
11098 else
11099 length = llistxattr(name, buffer, buffer_size);
11100 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011101
Larry Hastings9cf065c2012-06-22 16:30:09 -070011102 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011103 if (errno == ERANGE) {
11104 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011105 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011106 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011107 }
Larry Hastings2f936352014-08-05 14:04:04 +100011108 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011109 break;
11110 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011111
Larry Hastings9cf065c2012-06-22 16:30:09 -070011112 result = PyList_New(0);
11113 if (!result) {
11114 goto exit;
11115 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011116
Larry Hastings9cf065c2012-06-22 16:30:09 -070011117 end = buffer + length;
11118 for (trace = start = buffer; trace != end; trace++) {
11119 if (!*trace) {
11120 int error;
11121 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11122 trace - start);
11123 if (!attribute) {
11124 Py_DECREF(result);
11125 result = NULL;
11126 goto exit;
11127 }
11128 error = PyList_Append(result, attribute);
11129 Py_DECREF(attribute);
11130 if (error) {
11131 Py_DECREF(result);
11132 result = NULL;
11133 goto exit;
11134 }
11135 start = trace + 1;
11136 }
11137 }
11138 break;
11139 }
11140exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011141 if (buffer)
11142 PyMem_FREE(buffer);
11143 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011144}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011145#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011146
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011147
Larry Hastings2f936352014-08-05 14:04:04 +100011148/*[clinic input]
11149os.urandom
11150
11151 size: Py_ssize_t
11152 /
11153
11154Return a bytes object containing random bytes suitable for cryptographic use.
11155[clinic start generated code]*/
11156
Larry Hastings2f936352014-08-05 14:04:04 +100011157static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011158os_urandom_impl(PyObject *module, Py_ssize_t size)
11159/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011160{
11161 PyObject *bytes;
11162 int result;
11163
Georg Brandl2fb477c2012-02-21 00:33:36 +010011164 if (size < 0)
11165 return PyErr_Format(PyExc_ValueError,
11166 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011167 bytes = PyBytes_FromStringAndSize(NULL, size);
11168 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011169 return NULL;
11170
Victor Stinnere66987e2016-09-06 16:33:52 -070011171 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100011172 if (result == -1) {
11173 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011174 return NULL;
11175 }
Larry Hastings2f936352014-08-05 14:04:04 +100011176 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011177}
11178
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011179/* Terminal size querying */
11180
11181static PyTypeObject TerminalSizeType;
11182
11183PyDoc_STRVAR(TerminalSize_docstring,
11184 "A tuple of (columns, lines) for holding terminal window size");
11185
11186static PyStructSequence_Field TerminalSize_fields[] = {
11187 {"columns", "width of the terminal window in characters"},
11188 {"lines", "height of the terminal window in characters"},
11189 {NULL, NULL}
11190};
11191
11192static PyStructSequence_Desc TerminalSize_desc = {
11193 "os.terminal_size",
11194 TerminalSize_docstring,
11195 TerminalSize_fields,
11196 2,
11197};
11198
11199#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011200/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011201PyDoc_STRVAR(termsize__doc__,
11202 "Return the size of the terminal window as (columns, lines).\n" \
11203 "\n" \
11204 "The optional argument fd (default standard output) specifies\n" \
11205 "which file descriptor should be queried.\n" \
11206 "\n" \
11207 "If the file descriptor is not connected to a terminal, an OSError\n" \
11208 "is thrown.\n" \
11209 "\n" \
11210 "This function will only be defined if an implementation is\n" \
11211 "available for this system.\n" \
11212 "\n" \
11213 "shutil.get_terminal_size is the high-level function which should \n" \
11214 "normally be used, os.get_terminal_size is the low-level implementation.");
11215
11216static PyObject*
11217get_terminal_size(PyObject *self, PyObject *args)
11218{
11219 int columns, lines;
11220 PyObject *termsize;
11221
11222 int fd = fileno(stdout);
11223 /* Under some conditions stdout may not be connected and
11224 * fileno(stdout) may point to an invalid file descriptor. For example
11225 * GUI apps don't have valid standard streams by default.
11226 *
11227 * If this happens, and the optional fd argument is not present,
11228 * the ioctl below will fail returning EBADF. This is what we want.
11229 */
11230
11231 if (!PyArg_ParseTuple(args, "|i", &fd))
11232 return NULL;
11233
11234#ifdef TERMSIZE_USE_IOCTL
11235 {
11236 struct winsize w;
11237 if (ioctl(fd, TIOCGWINSZ, &w))
11238 return PyErr_SetFromErrno(PyExc_OSError);
11239 columns = w.ws_col;
11240 lines = w.ws_row;
11241 }
11242#endif /* TERMSIZE_USE_IOCTL */
11243
11244#ifdef TERMSIZE_USE_CONIO
11245 {
11246 DWORD nhandle;
11247 HANDLE handle;
11248 CONSOLE_SCREEN_BUFFER_INFO csbi;
11249 switch (fd) {
11250 case 0: nhandle = STD_INPUT_HANDLE;
11251 break;
11252 case 1: nhandle = STD_OUTPUT_HANDLE;
11253 break;
11254 case 2: nhandle = STD_ERROR_HANDLE;
11255 break;
11256 default:
11257 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11258 }
11259 handle = GetStdHandle(nhandle);
11260 if (handle == NULL)
11261 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11262 if (handle == INVALID_HANDLE_VALUE)
11263 return PyErr_SetFromWindowsErr(0);
11264
11265 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11266 return PyErr_SetFromWindowsErr(0);
11267
11268 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11269 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11270 }
11271#endif /* TERMSIZE_USE_CONIO */
11272
11273 termsize = PyStructSequence_New(&TerminalSizeType);
11274 if (termsize == NULL)
11275 return NULL;
11276 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11277 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11278 if (PyErr_Occurred()) {
11279 Py_DECREF(termsize);
11280 return NULL;
11281 }
11282 return termsize;
11283}
11284#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11285
Larry Hastings2f936352014-08-05 14:04:04 +100011286
11287/*[clinic input]
11288os.cpu_count
11289
Charles-François Natali80d62e62015-08-13 20:37:08 +010011290Return the number of CPUs in the system; return None if indeterminable.
11291
11292This number is not equivalent to the number of CPUs the current process can
11293use. The number of usable CPUs can be obtained with
11294``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011295[clinic start generated code]*/
11296
Larry Hastings2f936352014-08-05 14:04:04 +100011297static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011298os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011299/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011300{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011301 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011302#ifdef MS_WINDOWS
11303 SYSTEM_INFO sysinfo;
11304 GetSystemInfo(&sysinfo);
11305 ncpu = sysinfo.dwNumberOfProcessors;
11306#elif defined(__hpux)
11307 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11308#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11309 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011310#elif defined(__DragonFly__) || \
11311 defined(__OpenBSD__) || \
11312 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011313 defined(__NetBSD__) || \
11314 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011315 int mib[2];
11316 size_t len = sizeof(ncpu);
11317 mib[0] = CTL_HW;
11318 mib[1] = HW_NCPU;
11319 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11320 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011321#endif
11322 if (ncpu >= 1)
11323 return PyLong_FromLong(ncpu);
11324 else
11325 Py_RETURN_NONE;
11326}
11327
Victor Stinnerdaf45552013-08-28 00:53:59 +020011328
Larry Hastings2f936352014-08-05 14:04:04 +100011329/*[clinic input]
11330os.get_inheritable -> bool
11331
11332 fd: int
11333 /
11334
11335Get the close-on-exe flag of the specified file descriptor.
11336[clinic start generated code]*/
11337
Larry Hastings2f936352014-08-05 14:04:04 +100011338static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011339os_get_inheritable_impl(PyObject *module, int fd)
11340/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011341{
Steve Dower8fc89802015-04-12 00:26:27 -040011342 int return_value;
11343 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011344 posix_error();
11345 return -1;
11346 }
11347
Steve Dower8fc89802015-04-12 00:26:27 -040011348 _Py_BEGIN_SUPPRESS_IPH
11349 return_value = _Py_get_inheritable(fd);
11350 _Py_END_SUPPRESS_IPH
11351 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011352}
11353
11354
11355/*[clinic input]
11356os.set_inheritable
11357 fd: int
11358 inheritable: int
11359 /
11360
11361Set the inheritable flag of the specified file descriptor.
11362[clinic start generated code]*/
11363
Larry Hastings2f936352014-08-05 14:04:04 +100011364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011365os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11366/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011367{
Steve Dower8fc89802015-04-12 00:26:27 -040011368 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011369 if (!_PyVerify_fd(fd))
11370 return posix_error();
11371
Steve Dower8fc89802015-04-12 00:26:27 -040011372 _Py_BEGIN_SUPPRESS_IPH
11373 result = _Py_set_inheritable(fd, inheritable, NULL);
11374 _Py_END_SUPPRESS_IPH
11375 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011376 return NULL;
11377 Py_RETURN_NONE;
11378}
11379
11380
11381#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011382/*[clinic input]
11383os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011384 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011385 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011386
Larry Hastings2f936352014-08-05 14:04:04 +100011387Get the close-on-exe flag of the specified file descriptor.
11388[clinic start generated code]*/
11389
Larry Hastings2f936352014-08-05 14:04:04 +100011390static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011391os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011392/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011393{
11394 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011395
11396 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11397 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011398 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011399 }
11400
Larry Hastings2f936352014-08-05 14:04:04 +100011401 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011402}
11403
Victor Stinnerdaf45552013-08-28 00:53:59 +020011404
Larry Hastings2f936352014-08-05 14:04:04 +100011405/*[clinic input]
11406os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011407 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011408 inheritable: bool
11409 /
11410
11411Set the inheritable flag of the specified handle.
11412[clinic start generated code]*/
11413
Larry Hastings2f936352014-08-05 14:04:04 +100011414static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011415os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011416 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011417/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011418{
11419 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011420 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11421 PyErr_SetFromWindowsErr(0);
11422 return NULL;
11423 }
11424 Py_RETURN_NONE;
11425}
Larry Hastings2f936352014-08-05 14:04:04 +100011426#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011427
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011428#ifndef MS_WINDOWS
11429PyDoc_STRVAR(get_blocking__doc__,
11430 "get_blocking(fd) -> bool\n" \
11431 "\n" \
11432 "Get the blocking mode of the file descriptor:\n" \
11433 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11434
11435static PyObject*
11436posix_get_blocking(PyObject *self, PyObject *args)
11437{
11438 int fd;
11439 int blocking;
11440
11441 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11442 return NULL;
11443
11444 if (!_PyVerify_fd(fd))
11445 return posix_error();
11446
Steve Dower8fc89802015-04-12 00:26:27 -040011447 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011448 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011449 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011450 if (blocking < 0)
11451 return NULL;
11452 return PyBool_FromLong(blocking);
11453}
11454
11455PyDoc_STRVAR(set_blocking__doc__,
11456 "set_blocking(fd, blocking)\n" \
11457 "\n" \
11458 "Set the blocking mode of the specified file descriptor.\n" \
11459 "Set the O_NONBLOCK flag if blocking is False,\n" \
11460 "clear the O_NONBLOCK flag otherwise.");
11461
11462static PyObject*
11463posix_set_blocking(PyObject *self, PyObject *args)
11464{
Steve Dower8fc89802015-04-12 00:26:27 -040011465 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011466
11467 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11468 return NULL;
11469
11470 if (!_PyVerify_fd(fd))
11471 return posix_error();
11472
Steve Dower8fc89802015-04-12 00:26:27 -040011473 _Py_BEGIN_SUPPRESS_IPH
11474 result = _Py_set_blocking(fd, blocking);
11475 _Py_END_SUPPRESS_IPH
11476 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011477 return NULL;
11478 Py_RETURN_NONE;
11479}
11480#endif /* !MS_WINDOWS */
11481
11482
Victor Stinner6036e442015-03-08 01:58:04 +010011483PyDoc_STRVAR(posix_scandir__doc__,
11484"scandir(path='.') -> iterator of DirEntry objects for given path");
11485
11486static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11487
11488typedef struct {
11489 PyObject_HEAD
11490 PyObject *name;
11491 PyObject *path;
11492 PyObject *stat;
11493 PyObject *lstat;
11494#ifdef MS_WINDOWS
11495 struct _Py_stat_struct win32_lstat;
11496 __int64 win32_file_index;
11497 int got_file_index;
11498#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011499#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011500 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011501#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011502 ino_t d_ino;
11503#endif
11504} DirEntry;
11505
11506static void
11507DirEntry_dealloc(DirEntry *entry)
11508{
11509 Py_XDECREF(entry->name);
11510 Py_XDECREF(entry->path);
11511 Py_XDECREF(entry->stat);
11512 Py_XDECREF(entry->lstat);
11513 Py_TYPE(entry)->tp_free((PyObject *)entry);
11514}
11515
11516/* Forward reference */
11517static int
11518DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11519
11520/* Set exception and return -1 on error, 0 for False, 1 for True */
11521static int
11522DirEntry_is_symlink(DirEntry *self)
11523{
11524#ifdef MS_WINDOWS
11525 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011526#elif defined(HAVE_DIRENT_D_TYPE)
11527 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011528 if (self->d_type != DT_UNKNOWN)
11529 return self->d_type == DT_LNK;
11530 else
11531 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011532#else
11533 /* POSIX without d_type */
11534 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011535#endif
11536}
11537
11538static PyObject *
11539DirEntry_py_is_symlink(DirEntry *self)
11540{
11541 int result;
11542
11543 result = DirEntry_is_symlink(self);
11544 if (result == -1)
11545 return NULL;
11546 return PyBool_FromLong(result);
11547}
11548
11549static PyObject *
11550DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11551{
11552 int result;
11553 struct _Py_stat_struct st;
11554
11555#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011556 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011557
11558 path = PyUnicode_AsUnicode(self->path);
11559 if (!path)
11560 return NULL;
11561
11562 if (follow_symlinks)
11563 result = win32_stat_w(path, &st);
11564 else
11565 result = win32_lstat_w(path, &st);
11566
11567 if (result != 0) {
11568 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11569 0, self->path);
11570 }
11571#else /* POSIX */
11572 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011573 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011574
11575 if (!PyUnicode_FSConverter(self->path, &bytes))
11576 return NULL;
11577 path = PyBytes_AS_STRING(bytes);
11578
11579 if (follow_symlinks)
11580 result = STAT(path, &st);
11581 else
11582 result = LSTAT(path, &st);
11583 Py_DECREF(bytes);
11584
11585 if (result != 0)
11586 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11587#endif
11588
11589 return _pystat_fromstructstat(&st);
11590}
11591
11592static PyObject *
11593DirEntry_get_lstat(DirEntry *self)
11594{
11595 if (!self->lstat) {
11596#ifdef MS_WINDOWS
11597 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11598#else /* POSIX */
11599 self->lstat = DirEntry_fetch_stat(self, 0);
11600#endif
11601 }
11602 Py_XINCREF(self->lstat);
11603 return self->lstat;
11604}
11605
11606static PyObject *
11607DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11608{
11609 if (!follow_symlinks)
11610 return DirEntry_get_lstat(self);
11611
11612 if (!self->stat) {
11613 int result = DirEntry_is_symlink(self);
11614 if (result == -1)
11615 return NULL;
11616 else if (result)
11617 self->stat = DirEntry_fetch_stat(self, 1);
11618 else
11619 self->stat = DirEntry_get_lstat(self);
11620 }
11621
11622 Py_XINCREF(self->stat);
11623 return self->stat;
11624}
11625
11626static PyObject *
11627DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11628{
11629 int follow_symlinks = 1;
11630
11631 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11632 follow_symlinks_keywords, &follow_symlinks))
11633 return NULL;
11634
11635 return DirEntry_get_stat(self, follow_symlinks);
11636}
11637
11638/* Set exception and return -1 on error, 0 for False, 1 for True */
11639static int
11640DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11641{
11642 PyObject *stat = NULL;
11643 PyObject *st_mode = NULL;
11644 long mode;
11645 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011646#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011647 int is_symlink;
11648 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011649#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011650#ifdef MS_WINDOWS
11651 unsigned long dir_bits;
11652#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011653 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011654
11655#ifdef MS_WINDOWS
11656 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11657 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011658#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011659 is_symlink = self->d_type == DT_LNK;
11660 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11661#endif
11662
Victor Stinner35a97c02015-03-08 02:59:09 +010011663#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011664 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011665#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011666 stat = DirEntry_get_stat(self, follow_symlinks);
11667 if (!stat) {
11668 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11669 /* If file doesn't exist (anymore), then return False
11670 (i.e., say it's not a file/directory) */
11671 PyErr_Clear();
11672 return 0;
11673 }
11674 goto error;
11675 }
11676 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11677 if (!st_mode)
11678 goto error;
11679
11680 mode = PyLong_AsLong(st_mode);
11681 if (mode == -1 && PyErr_Occurred())
11682 goto error;
11683 Py_CLEAR(st_mode);
11684 Py_CLEAR(stat);
11685 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011686#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011687 }
11688 else if (is_symlink) {
11689 assert(mode_bits != S_IFLNK);
11690 result = 0;
11691 }
11692 else {
11693 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11694#ifdef MS_WINDOWS
11695 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11696 if (mode_bits == S_IFDIR)
11697 result = dir_bits != 0;
11698 else
11699 result = dir_bits == 0;
11700#else /* POSIX */
11701 if (mode_bits == S_IFDIR)
11702 result = self->d_type == DT_DIR;
11703 else
11704 result = self->d_type == DT_REG;
11705#endif
11706 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011707#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011708
11709 return result;
11710
11711error:
11712 Py_XDECREF(st_mode);
11713 Py_XDECREF(stat);
11714 return -1;
11715}
11716
11717static PyObject *
11718DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11719{
11720 int result;
11721
11722 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11723 if (result == -1)
11724 return NULL;
11725 return PyBool_FromLong(result);
11726}
11727
11728static PyObject *
11729DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11730{
11731 int follow_symlinks = 1;
11732
11733 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11734 follow_symlinks_keywords, &follow_symlinks))
11735 return NULL;
11736
11737 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11738}
11739
11740static PyObject *
11741DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11742{
11743 int follow_symlinks = 1;
11744
11745 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11746 follow_symlinks_keywords, &follow_symlinks))
11747 return NULL;
11748
11749 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11750}
11751
11752static PyObject *
11753DirEntry_inode(DirEntry *self)
11754{
11755#ifdef MS_WINDOWS
11756 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011757 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011758 struct _Py_stat_struct stat;
11759
11760 path = PyUnicode_AsUnicode(self->path);
11761 if (!path)
11762 return NULL;
11763
11764 if (win32_lstat_w(path, &stat) != 0) {
11765 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11766 0, self->path);
11767 }
11768
11769 self->win32_file_index = stat.st_ino;
11770 self->got_file_index = 1;
11771 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011772 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011773#else /* POSIX */
11774#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011775 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011776#else
11777 return PyLong_FromLong((long)self->d_ino);
11778#endif
11779#endif
11780}
11781
11782static PyObject *
11783DirEntry_repr(DirEntry *self)
11784{
11785 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11786}
11787
Brett Cannon96881cd2016-06-10 14:37:21 -070011788static PyObject *
11789DirEntry_fspath(DirEntry *self)
11790{
11791 Py_INCREF(self->path);
11792 return self->path;
11793}
11794
Victor Stinner6036e442015-03-08 01:58:04 +010011795static PyMemberDef DirEntry_members[] = {
11796 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11797 "the entry's base filename, relative to scandir() \"path\" argument"},
11798 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11799 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11800 {NULL}
11801};
11802
11803static PyMethodDef DirEntry_methods[] = {
11804 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11805 "return True if the entry is a directory; cached per entry"
11806 },
11807 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11808 "return True if the entry is a file; cached per entry"
11809 },
11810 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11811 "return True if the entry is a symbolic link; cached per entry"
11812 },
11813 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11814 "return stat_result object for the entry; cached per entry"
11815 },
11816 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11817 "return inode of the entry; cached per entry",
11818 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011819 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11820 "returns the path for the entry",
11821 },
Victor Stinner6036e442015-03-08 01:58:04 +010011822 {NULL}
11823};
11824
Benjamin Peterson5646de42015-04-12 17:56:34 -040011825static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011826 PyVarObject_HEAD_INIT(NULL, 0)
11827 MODNAME ".DirEntry", /* tp_name */
11828 sizeof(DirEntry), /* tp_basicsize */
11829 0, /* tp_itemsize */
11830 /* methods */
11831 (destructor)DirEntry_dealloc, /* tp_dealloc */
11832 0, /* tp_print */
11833 0, /* tp_getattr */
11834 0, /* tp_setattr */
11835 0, /* tp_compare */
11836 (reprfunc)DirEntry_repr, /* tp_repr */
11837 0, /* tp_as_number */
11838 0, /* tp_as_sequence */
11839 0, /* tp_as_mapping */
11840 0, /* tp_hash */
11841 0, /* tp_call */
11842 0, /* tp_str */
11843 0, /* tp_getattro */
11844 0, /* tp_setattro */
11845 0, /* tp_as_buffer */
11846 Py_TPFLAGS_DEFAULT, /* tp_flags */
11847 0, /* tp_doc */
11848 0, /* tp_traverse */
11849 0, /* tp_clear */
11850 0, /* tp_richcompare */
11851 0, /* tp_weaklistoffset */
11852 0, /* tp_iter */
11853 0, /* tp_iternext */
11854 DirEntry_methods, /* tp_methods */
11855 DirEntry_members, /* tp_members */
11856};
11857
11858#ifdef MS_WINDOWS
11859
11860static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011861join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011862{
11863 Py_ssize_t path_len;
11864 Py_ssize_t size;
11865 wchar_t *result;
11866 wchar_t ch;
11867
11868 if (!path_wide) { /* Default arg: "." */
11869 path_wide = L".";
11870 path_len = 1;
11871 }
11872 else {
11873 path_len = wcslen(path_wide);
11874 }
11875
11876 /* The +1's are for the path separator and the NUL */
11877 size = path_len + 1 + wcslen(filename) + 1;
11878 result = PyMem_New(wchar_t, size);
11879 if (!result) {
11880 PyErr_NoMemory();
11881 return NULL;
11882 }
11883 wcscpy(result, path_wide);
11884 if (path_len > 0) {
11885 ch = result[path_len - 1];
11886 if (ch != SEP && ch != ALTSEP && ch != L':')
11887 result[path_len++] = SEP;
11888 wcscpy(result + path_len, filename);
11889 }
11890 return result;
11891}
11892
11893static PyObject *
11894DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11895{
11896 DirEntry *entry;
11897 BY_HANDLE_FILE_INFORMATION file_info;
11898 ULONG reparse_tag;
11899 wchar_t *joined_path;
11900
11901 entry = PyObject_New(DirEntry, &DirEntryType);
11902 if (!entry)
11903 return NULL;
11904 entry->name = NULL;
11905 entry->path = NULL;
11906 entry->stat = NULL;
11907 entry->lstat = NULL;
11908 entry->got_file_index = 0;
11909
11910 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11911 if (!entry->name)
11912 goto error;
11913
11914 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11915 if (!joined_path)
11916 goto error;
11917
11918 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11919 PyMem_Free(joined_path);
11920 if (!entry->path)
11921 goto error;
11922
11923 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11924 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11925
11926 return (PyObject *)entry;
11927
11928error:
11929 Py_DECREF(entry);
11930 return NULL;
11931}
11932
11933#else /* POSIX */
11934
11935static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011936join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011937{
11938 Py_ssize_t path_len;
11939 Py_ssize_t size;
11940 char *result;
11941
11942 if (!path_narrow) { /* Default arg: "." */
11943 path_narrow = ".";
11944 path_len = 1;
11945 }
11946 else {
11947 path_len = strlen(path_narrow);
11948 }
11949
11950 if (filename_len == -1)
11951 filename_len = strlen(filename);
11952
11953 /* The +1's are for the path separator and the NUL */
11954 size = path_len + 1 + filename_len + 1;
11955 result = PyMem_New(char, size);
11956 if (!result) {
11957 PyErr_NoMemory();
11958 return NULL;
11959 }
11960 strcpy(result, path_narrow);
11961 if (path_len > 0 && result[path_len - 1] != '/')
11962 result[path_len++] = '/';
11963 strcpy(result + path_len, filename);
11964 return result;
11965}
11966
11967static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011968DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011969 ino_t d_ino
11970#ifdef HAVE_DIRENT_D_TYPE
11971 , unsigned char d_type
11972#endif
11973 )
Victor Stinner6036e442015-03-08 01:58:04 +010011974{
11975 DirEntry *entry;
11976 char *joined_path;
11977
11978 entry = PyObject_New(DirEntry, &DirEntryType);
11979 if (!entry)
11980 return NULL;
11981 entry->name = NULL;
11982 entry->path = NULL;
11983 entry->stat = NULL;
11984 entry->lstat = NULL;
11985
11986 joined_path = join_path_filename(path->narrow, name, name_len);
11987 if (!joined_path)
11988 goto error;
11989
11990 if (!path->narrow || !PyBytes_Check(path->object)) {
11991 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11992 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11993 }
11994 else {
11995 entry->name = PyBytes_FromStringAndSize(name, name_len);
11996 entry->path = PyBytes_FromString(joined_path);
11997 }
11998 PyMem_Free(joined_path);
11999 if (!entry->name || !entry->path)
12000 goto error;
12001
Victor Stinner35a97c02015-03-08 02:59:09 +010012002#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012003 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012004#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012005 entry->d_ino = d_ino;
12006
12007 return (PyObject *)entry;
12008
12009error:
12010 Py_XDECREF(entry);
12011 return NULL;
12012}
12013
12014#endif
12015
12016
12017typedef struct {
12018 PyObject_HEAD
12019 path_t path;
12020#ifdef MS_WINDOWS
12021 HANDLE handle;
12022 WIN32_FIND_DATAW file_data;
12023 int first_time;
12024#else /* POSIX */
12025 DIR *dirp;
12026#endif
12027} ScandirIterator;
12028
12029#ifdef MS_WINDOWS
12030
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012031static int
12032ScandirIterator_is_closed(ScandirIterator *iterator)
12033{
12034 return iterator->handle == INVALID_HANDLE_VALUE;
12035}
12036
Victor Stinner6036e442015-03-08 01:58:04 +010012037static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012038ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012039{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012040 HANDLE handle = iterator->handle;
12041
12042 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012043 return;
12044
Victor Stinner6036e442015-03-08 01:58:04 +010012045 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012046 Py_BEGIN_ALLOW_THREADS
12047 FindClose(handle);
12048 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012049}
12050
12051static PyObject *
12052ScandirIterator_iternext(ScandirIterator *iterator)
12053{
12054 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12055 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012056 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012057
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012058 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012059 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012060 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012061
12062 while (1) {
12063 if (!iterator->first_time) {
12064 Py_BEGIN_ALLOW_THREADS
12065 success = FindNextFileW(iterator->handle, file_data);
12066 Py_END_ALLOW_THREADS
12067 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012068 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012069 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012070 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012071 break;
12072 }
12073 }
12074 iterator->first_time = 0;
12075
12076 /* Skip over . and .. */
12077 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012078 wcscmp(file_data->cFileName, L"..") != 0) {
12079 entry = DirEntry_from_find_data(&iterator->path, file_data);
12080 if (!entry)
12081 break;
12082 return entry;
12083 }
Victor Stinner6036e442015-03-08 01:58:04 +010012084
12085 /* Loop till we get a non-dot directory or finish iterating */
12086 }
12087
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012088 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012089 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012090 return NULL;
12091}
12092
12093#else /* POSIX */
12094
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012095static int
12096ScandirIterator_is_closed(ScandirIterator *iterator)
12097{
12098 return !iterator->dirp;
12099}
12100
Victor Stinner6036e442015-03-08 01:58:04 +010012101static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012102ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012103{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012104 DIR *dirp = iterator->dirp;
12105
12106 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012107 return;
12108
Victor Stinner6036e442015-03-08 01:58:04 +010012109 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012110 Py_BEGIN_ALLOW_THREADS
12111 closedir(dirp);
12112 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012113 return;
12114}
12115
12116static PyObject *
12117ScandirIterator_iternext(ScandirIterator *iterator)
12118{
12119 struct dirent *direntp;
12120 Py_ssize_t name_len;
12121 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012122 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012123
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012124 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012125 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012126 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012127
12128 while (1) {
12129 errno = 0;
12130 Py_BEGIN_ALLOW_THREADS
12131 direntp = readdir(iterator->dirp);
12132 Py_END_ALLOW_THREADS
12133
12134 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012135 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012136 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012137 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012138 break;
12139 }
12140
12141 /* Skip over . and .. */
12142 name_len = NAMLEN(direntp);
12143 is_dot = direntp->d_name[0] == '.' &&
12144 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12145 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012146 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012147 name_len, direntp->d_ino
12148#ifdef HAVE_DIRENT_D_TYPE
12149 , direntp->d_type
12150#endif
12151 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012152 if (!entry)
12153 break;
12154 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012155 }
12156
12157 /* Loop till we get a non-dot directory or finish iterating */
12158 }
12159
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012160 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012161 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012162 return NULL;
12163}
12164
12165#endif
12166
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012167static PyObject *
12168ScandirIterator_close(ScandirIterator *self, PyObject *args)
12169{
12170 ScandirIterator_closedir(self);
12171 Py_RETURN_NONE;
12172}
12173
12174static PyObject *
12175ScandirIterator_enter(PyObject *self, PyObject *args)
12176{
12177 Py_INCREF(self);
12178 return self;
12179}
12180
12181static PyObject *
12182ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12183{
12184 ScandirIterator_closedir(self);
12185 Py_RETURN_NONE;
12186}
12187
Victor Stinner6036e442015-03-08 01:58:04 +010012188static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012189ScandirIterator_finalize(ScandirIterator *iterator)
12190{
12191 PyObject *error_type, *error_value, *error_traceback;
12192
12193 /* Save the current exception, if any. */
12194 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12195
12196 if (!ScandirIterator_is_closed(iterator)) {
12197 ScandirIterator_closedir(iterator);
12198
12199 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12200 "unclosed scandir iterator %R", iterator)) {
12201 /* Spurious errors can appear at shutdown */
12202 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12203 PyErr_WriteUnraisable((PyObject *) iterator);
12204 }
12205 }
12206 }
12207
12208 Py_CLEAR(iterator->path.object);
12209 path_cleanup(&iterator->path);
12210
12211 /* Restore the saved exception. */
12212 PyErr_Restore(error_type, error_value, error_traceback);
12213}
12214
12215static void
Victor Stinner6036e442015-03-08 01:58:04 +010012216ScandirIterator_dealloc(ScandirIterator *iterator)
12217{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012218 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12219 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012220
Victor Stinner6036e442015-03-08 01:58:04 +010012221 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12222}
12223
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012224static PyMethodDef ScandirIterator_methods[] = {
12225 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12226 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12227 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12228 {NULL}
12229};
12230
Benjamin Peterson5646de42015-04-12 17:56:34 -040012231static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012232 PyVarObject_HEAD_INIT(NULL, 0)
12233 MODNAME ".ScandirIterator", /* tp_name */
12234 sizeof(ScandirIterator), /* tp_basicsize */
12235 0, /* tp_itemsize */
12236 /* methods */
12237 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12238 0, /* tp_print */
12239 0, /* tp_getattr */
12240 0, /* tp_setattr */
12241 0, /* tp_compare */
12242 0, /* tp_repr */
12243 0, /* tp_as_number */
12244 0, /* tp_as_sequence */
12245 0, /* tp_as_mapping */
12246 0, /* tp_hash */
12247 0, /* tp_call */
12248 0, /* tp_str */
12249 0, /* tp_getattro */
12250 0, /* tp_setattro */
12251 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012252 Py_TPFLAGS_DEFAULT
12253 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012254 0, /* tp_doc */
12255 0, /* tp_traverse */
12256 0, /* tp_clear */
12257 0, /* tp_richcompare */
12258 0, /* tp_weaklistoffset */
12259 PyObject_SelfIter, /* tp_iter */
12260 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012261 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012262 0, /* tp_members */
12263 0, /* tp_getset */
12264 0, /* tp_base */
12265 0, /* tp_dict */
12266 0, /* tp_descr_get */
12267 0, /* tp_descr_set */
12268 0, /* tp_dictoffset */
12269 0, /* tp_init */
12270 0, /* tp_alloc */
12271 0, /* tp_new */
12272 0, /* tp_free */
12273 0, /* tp_is_gc */
12274 0, /* tp_bases */
12275 0, /* tp_mro */
12276 0, /* tp_cache */
12277 0, /* tp_subclasses */
12278 0, /* tp_weaklist */
12279 0, /* tp_del */
12280 0, /* tp_version_tag */
12281 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012282};
12283
12284static PyObject *
12285posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12286{
12287 ScandirIterator *iterator;
12288 static char *keywords[] = {"path", NULL};
12289#ifdef MS_WINDOWS
12290 wchar_t *path_strW;
12291#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012292 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010012293#endif
12294
12295 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12296 if (!iterator)
12297 return NULL;
12298 memset(&iterator->path, 0, sizeof(path_t));
12299 iterator->path.function_name = "scandir";
12300 iterator->path.nullable = 1;
12301
12302#ifdef MS_WINDOWS
12303 iterator->handle = INVALID_HANDLE_VALUE;
12304#else
12305 iterator->dirp = NULL;
12306#endif
12307
12308 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12309 path_converter, &iterator->path))
12310 goto error;
12311
12312 /* path_converter doesn't keep path.object around, so do it
12313 manually for the lifetime of the iterator here (the refcount
12314 is decremented in ScandirIterator_dealloc)
12315 */
12316 Py_XINCREF(iterator->path.object);
12317
12318#ifdef MS_WINDOWS
12319 if (iterator->path.narrow) {
12320 PyErr_SetString(PyExc_TypeError,
12321 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12322 goto error;
12323 }
12324 iterator->first_time = 1;
12325
12326 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12327 if (!path_strW)
12328 goto error;
12329
12330 Py_BEGIN_ALLOW_THREADS
12331 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12332 Py_END_ALLOW_THREADS
12333
12334 PyMem_Free(path_strW);
12335
12336 if (iterator->handle == INVALID_HANDLE_VALUE) {
12337 path_error(&iterator->path);
12338 goto error;
12339 }
12340#else /* POSIX */
12341 if (iterator->path.narrow)
12342 path = iterator->path.narrow;
12343 else
12344 path = ".";
12345
12346 errno = 0;
12347 Py_BEGIN_ALLOW_THREADS
12348 iterator->dirp = opendir(path);
12349 Py_END_ALLOW_THREADS
12350
12351 if (!iterator->dirp) {
12352 path_error(&iterator->path);
12353 goto error;
12354 }
12355#endif
12356
12357 return (PyObject *)iterator;
12358
12359error:
12360 Py_DECREF(iterator);
12361 return NULL;
12362}
12363
Ethan Furman410ef8e2016-06-04 12:06:26 -070012364/*
12365 Return the file system path representation of the object.
12366
12367 If the object is str or bytes, then allow it to pass through with
12368 an incremented refcount. If the object defines __fspath__(), then
12369 return the result of that method. All other types raise a TypeError.
12370*/
12371PyObject *
12372PyOS_FSPath(PyObject *path)
12373{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012374 /* For error message reasons, this function is manually inlined in
12375 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012376 _Py_IDENTIFIER(__fspath__);
12377 PyObject *func = NULL;
12378 PyObject *path_repr = NULL;
12379
12380 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12381 Py_INCREF(path);
12382 return path;
12383 }
12384
12385 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12386 if (NULL == func) {
12387 return PyErr_Format(PyExc_TypeError,
12388 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012389 "not %.200s",
12390 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012391 }
12392
12393 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12394 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012395 if (NULL == path_repr) {
12396 return NULL;
12397 }
12398
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012399 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12400 PyErr_Format(PyExc_TypeError,
12401 "expected %.200s.__fspath__() to return str or bytes, "
12402 "not %.200s", Py_TYPE(path)->tp_name,
12403 Py_TYPE(path_repr)->tp_name);
12404 Py_DECREF(path_repr);
12405 return NULL;
12406 }
12407
Ethan Furman410ef8e2016-06-04 12:06:26 -070012408 return path_repr;
12409}
12410
12411/*[clinic input]
12412os.fspath
12413
12414 path: object
12415
12416Return the file system path representation of the object.
12417
Brett Cannonb4f43e92016-06-09 14:32:08 -070012418If the object is str or bytes, then allow it to pass through as-is. If the
12419object defines __fspath__(), then return the result of that method. All other
12420types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012421[clinic start generated code]*/
12422
12423static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012424os_fspath_impl(PyObject *module, PyObject *path)
12425/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012426{
12427 return PyOS_FSPath(path);
12428}
Victor Stinner6036e442015-03-08 01:58:04 +010012429
Victor Stinner9b1f4742016-09-06 16:18:52 -070012430#ifdef HAVE_GETRANDOM_SYSCALL
12431/*[clinic input]
12432os.getrandom
12433
12434 size: Py_ssize_t
12435 flags: int=0
12436
12437Obtain a series of random bytes.
12438[clinic start generated code]*/
12439
12440static PyObject *
12441os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12442/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12443{
12444 char *buffer;
12445 Py_ssize_t n;
12446 PyObject *bytes;
12447
12448 if (size < 0) {
12449 errno = EINVAL;
12450 return posix_error();
12451 }
12452
12453 buffer = PyMem_Malloc(size);
12454 if (buffer == NULL) {
12455 PyErr_NoMemory();
12456 return NULL;
12457 }
12458
12459 while (1) {
12460 n = syscall(SYS_getrandom, buffer, size, flags);
12461 if (n < 0 && errno == EINTR) {
12462 if (PyErr_CheckSignals() < 0) {
12463 return NULL;
12464 }
12465 continue;
12466 }
12467 break;
12468 }
12469
12470 if (n < 0) {
12471 PyMem_Free(buffer);
12472 PyErr_SetFromErrno(PyExc_OSError);
12473 return NULL;
12474 }
12475
12476 bytes = PyBytes_FromStringAndSize(buffer, n);
12477 PyMem_Free(buffer);
12478
12479 return bytes;
12480}
12481#endif /* HAVE_GETRANDOM_SYSCALL */
12482
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012483#include "clinic/posixmodule.c.h"
12484
Larry Hastings7726ac92014-01-31 22:03:12 -080012485/*[clinic input]
12486dump buffer
12487[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012488/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012489
Larry Hastings31826802013-10-19 00:09:25 -070012490
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012491static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012492
12493 OS_STAT_METHODDEF
12494 OS_ACCESS_METHODDEF
12495 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012496 OS_CHDIR_METHODDEF
12497 OS_CHFLAGS_METHODDEF
12498 OS_CHMOD_METHODDEF
12499 OS_FCHMOD_METHODDEF
12500 OS_LCHMOD_METHODDEF
12501 OS_CHOWN_METHODDEF
12502 OS_FCHOWN_METHODDEF
12503 OS_LCHOWN_METHODDEF
12504 OS_LCHFLAGS_METHODDEF
12505 OS_CHROOT_METHODDEF
12506 OS_CTERMID_METHODDEF
12507 OS_GETCWD_METHODDEF
12508 OS_GETCWDB_METHODDEF
12509 OS_LINK_METHODDEF
12510 OS_LISTDIR_METHODDEF
12511 OS_LSTAT_METHODDEF
12512 OS_MKDIR_METHODDEF
12513 OS_NICE_METHODDEF
12514 OS_GETPRIORITY_METHODDEF
12515 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012516#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012517 {"readlink", (PyCFunction)posix_readlink,
12518 METH_VARARGS | METH_KEYWORDS,
12519 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012520#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012521#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012522 {"readlink", (PyCFunction)win_readlink,
12523 METH_VARARGS | METH_KEYWORDS,
12524 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012525#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012526 OS_RENAME_METHODDEF
12527 OS_REPLACE_METHODDEF
12528 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012529 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012530 OS_SYMLINK_METHODDEF
12531 OS_SYSTEM_METHODDEF
12532 OS_UMASK_METHODDEF
12533 OS_UNAME_METHODDEF
12534 OS_UNLINK_METHODDEF
12535 OS_REMOVE_METHODDEF
12536 OS_UTIME_METHODDEF
12537 OS_TIMES_METHODDEF
12538 OS__EXIT_METHODDEF
12539 OS_EXECV_METHODDEF
12540 OS_EXECVE_METHODDEF
12541 OS_SPAWNV_METHODDEF
12542 OS_SPAWNVE_METHODDEF
12543 OS_FORK1_METHODDEF
12544 OS_FORK_METHODDEF
12545 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12546 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12547 OS_SCHED_GETPARAM_METHODDEF
12548 OS_SCHED_GETSCHEDULER_METHODDEF
12549 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12550 OS_SCHED_SETPARAM_METHODDEF
12551 OS_SCHED_SETSCHEDULER_METHODDEF
12552 OS_SCHED_YIELD_METHODDEF
12553 OS_SCHED_SETAFFINITY_METHODDEF
12554 OS_SCHED_GETAFFINITY_METHODDEF
12555 OS_OPENPTY_METHODDEF
12556 OS_FORKPTY_METHODDEF
12557 OS_GETEGID_METHODDEF
12558 OS_GETEUID_METHODDEF
12559 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012560#ifdef HAVE_GETGROUPLIST
12561 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12562#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012563 OS_GETGROUPS_METHODDEF
12564 OS_GETPID_METHODDEF
12565 OS_GETPGRP_METHODDEF
12566 OS_GETPPID_METHODDEF
12567 OS_GETUID_METHODDEF
12568 OS_GETLOGIN_METHODDEF
12569 OS_KILL_METHODDEF
12570 OS_KILLPG_METHODDEF
12571 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012572#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012573 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012574#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012575 OS_SETUID_METHODDEF
12576 OS_SETEUID_METHODDEF
12577 OS_SETREUID_METHODDEF
12578 OS_SETGID_METHODDEF
12579 OS_SETEGID_METHODDEF
12580 OS_SETREGID_METHODDEF
12581 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012582#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012583 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012584#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012585 OS_GETPGID_METHODDEF
12586 OS_SETPGRP_METHODDEF
12587 OS_WAIT_METHODDEF
12588 OS_WAIT3_METHODDEF
12589 OS_WAIT4_METHODDEF
12590 OS_WAITID_METHODDEF
12591 OS_WAITPID_METHODDEF
12592 OS_GETSID_METHODDEF
12593 OS_SETSID_METHODDEF
12594 OS_SETPGID_METHODDEF
12595 OS_TCGETPGRP_METHODDEF
12596 OS_TCSETPGRP_METHODDEF
12597 OS_OPEN_METHODDEF
12598 OS_CLOSE_METHODDEF
12599 OS_CLOSERANGE_METHODDEF
12600 OS_DEVICE_ENCODING_METHODDEF
12601 OS_DUP_METHODDEF
12602 OS_DUP2_METHODDEF
12603 OS_LOCKF_METHODDEF
12604 OS_LSEEK_METHODDEF
12605 OS_READ_METHODDEF
12606 OS_READV_METHODDEF
12607 OS_PREAD_METHODDEF
12608 OS_WRITE_METHODDEF
12609 OS_WRITEV_METHODDEF
12610 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012611#ifdef HAVE_SENDFILE
12612 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12613 posix_sendfile__doc__},
12614#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012615 OS_FSTAT_METHODDEF
12616 OS_ISATTY_METHODDEF
12617 OS_PIPE_METHODDEF
12618 OS_PIPE2_METHODDEF
12619 OS_MKFIFO_METHODDEF
12620 OS_MKNOD_METHODDEF
12621 OS_MAJOR_METHODDEF
12622 OS_MINOR_METHODDEF
12623 OS_MAKEDEV_METHODDEF
12624 OS_FTRUNCATE_METHODDEF
12625 OS_TRUNCATE_METHODDEF
12626 OS_POSIX_FALLOCATE_METHODDEF
12627 OS_POSIX_FADVISE_METHODDEF
12628 OS_PUTENV_METHODDEF
12629 OS_UNSETENV_METHODDEF
12630 OS_STRERROR_METHODDEF
12631 OS_FCHDIR_METHODDEF
12632 OS_FSYNC_METHODDEF
12633 OS_SYNC_METHODDEF
12634 OS_FDATASYNC_METHODDEF
12635 OS_WCOREDUMP_METHODDEF
12636 OS_WIFCONTINUED_METHODDEF
12637 OS_WIFSTOPPED_METHODDEF
12638 OS_WIFSIGNALED_METHODDEF
12639 OS_WIFEXITED_METHODDEF
12640 OS_WEXITSTATUS_METHODDEF
12641 OS_WTERMSIG_METHODDEF
12642 OS_WSTOPSIG_METHODDEF
12643 OS_FSTATVFS_METHODDEF
12644 OS_STATVFS_METHODDEF
12645 OS_CONFSTR_METHODDEF
12646 OS_SYSCONF_METHODDEF
12647 OS_FPATHCONF_METHODDEF
12648 OS_PATHCONF_METHODDEF
12649 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012650 OS__GETFULLPATHNAME_METHODDEF
12651 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012652 OS__GETDISKUSAGE_METHODDEF
12653 OS__GETFINALPATHNAME_METHODDEF
12654 OS__GETVOLUMEPATHNAME_METHODDEF
12655 OS_GETLOADAVG_METHODDEF
12656 OS_URANDOM_METHODDEF
12657 OS_SETRESUID_METHODDEF
12658 OS_SETRESGID_METHODDEF
12659 OS_GETRESUID_METHODDEF
12660 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012661
Larry Hastings2f936352014-08-05 14:04:04 +100012662 OS_GETXATTR_METHODDEF
12663 OS_SETXATTR_METHODDEF
12664 OS_REMOVEXATTR_METHODDEF
12665 OS_LISTXATTR_METHODDEF
12666
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012667#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12668 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12669#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012670 OS_CPU_COUNT_METHODDEF
12671 OS_GET_INHERITABLE_METHODDEF
12672 OS_SET_INHERITABLE_METHODDEF
12673 OS_GET_HANDLE_INHERITABLE_METHODDEF
12674 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012675#ifndef MS_WINDOWS
12676 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12677 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12678#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012679 {"scandir", (PyCFunction)posix_scandir,
12680 METH_VARARGS | METH_KEYWORDS,
12681 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012682 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012683 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012684 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012685};
12686
12687
Brian Curtin52173d42010-12-02 18:29:18 +000012688#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012689static int
Brian Curtin52173d42010-12-02 18:29:18 +000012690enable_symlink()
12691{
12692 HANDLE tok;
12693 TOKEN_PRIVILEGES tok_priv;
12694 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012695
12696 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012697 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012698
12699 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012700 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012701
12702 tok_priv.PrivilegeCount = 1;
12703 tok_priv.Privileges[0].Luid = luid;
12704 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12705
12706 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12707 sizeof(TOKEN_PRIVILEGES),
12708 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012709 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012710
Brian Curtin3b4499c2010-12-28 14:31:47 +000012711 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12712 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012713}
12714#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12715
Barry Warsaw4a342091996-12-19 23:50:02 +000012716static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012718{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012719#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012721#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012722#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012724#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012725#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012727#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012728#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012730#endif
Fred Drakec9680921999-12-13 16:37:25 +000012731#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012733#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012734#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012736#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012737#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012739#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012740#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012742#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012743#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012745#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012746#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012748#endif
12749#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012751#endif
12752#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012754#endif
12755#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012757#endif
12758#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012760#endif
12761#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012763#endif
12764#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012766#endif
12767#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012769#endif
12770#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012772#endif
12773#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012775#endif
12776#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012777 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012778#endif
12779#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012781#endif
12782#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012783 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012784#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012785#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012786 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012787#endif
12788#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012789 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012790#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012791#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012792 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012793#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012794#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012795 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012796#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012797#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012798#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012799 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012800#endif
12801#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012802 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012803#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012804#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012805#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012806 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012807#endif
12808#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012809 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012810#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012811#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012812 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012813#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012814#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012815 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012816#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012817#ifdef O_TMPFILE
12818 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12819#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012820#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012821 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012822#endif
12823#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012824 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012825#endif
12826#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012827 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012828#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012829#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012830 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012831#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012832#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012833 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012834#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012835
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012836
Jesus Cea94363612012-06-22 18:32:07 +020012837#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012838 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012839#endif
12840#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012841 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012842#endif
12843
Tim Peters5aa91602002-01-30 05:46:57 +000012844/* MS Windows */
12845#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012846 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012847 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012848#endif
12849#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012850 /* Optimize for short life (keep in memory). */
12851 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012852 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012853#endif
12854#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012855 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012856 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012857#endif
12858#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012859 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012860 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012861#endif
12862#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012863 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012864 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012865#endif
12866
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012867/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012868#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012869 /* Send a SIGIO signal whenever input or output
12870 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012871 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012872#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012873#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012874 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012876#endif
12877#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012878 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012880#endif
12881#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012882 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012883 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012884#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012885#ifdef O_NOLINKS
12886 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012888#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012889#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012890 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012891 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012892#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012893
Victor Stinner8c62be82010-05-06 00:08:46 +000012894 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012895#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012896 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012897#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012898#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012900#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012901#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012903#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012904#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012906#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012907#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012909#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012910#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012911 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012912#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012913#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012915#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012916#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012917 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012918#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012919#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012920 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012921#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012922#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012923 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012924#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012925#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012926 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012927#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012928#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012929 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012930#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012931#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012932 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012933#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012934#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012935 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012936#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012937#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012938 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012939#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012940#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012941 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012942#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012943#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012944 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012945#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012946
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012947 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012948#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012950#endif /* ST_RDONLY */
12951#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012953#endif /* ST_NOSUID */
12954
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012955 /* GNU extensions */
12956#ifdef ST_NODEV
12957 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12958#endif /* ST_NODEV */
12959#ifdef ST_NOEXEC
12960 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12961#endif /* ST_NOEXEC */
12962#ifdef ST_SYNCHRONOUS
12963 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12964#endif /* ST_SYNCHRONOUS */
12965#ifdef ST_MANDLOCK
12966 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12967#endif /* ST_MANDLOCK */
12968#ifdef ST_WRITE
12969 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12970#endif /* ST_WRITE */
12971#ifdef ST_APPEND
12972 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12973#endif /* ST_APPEND */
12974#ifdef ST_NOATIME
12975 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12976#endif /* ST_NOATIME */
12977#ifdef ST_NODIRATIME
12978 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12979#endif /* ST_NODIRATIME */
12980#ifdef ST_RELATIME
12981 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12982#endif /* ST_RELATIME */
12983
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012984 /* FreeBSD sendfile() constants */
12985#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012986 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012987#endif
12988#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012989 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012990#endif
12991#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012992 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012993#endif
12994
Ross Lagerwall7807c352011-03-17 20:20:30 +020012995 /* constants for posix_fadvise */
12996#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012997 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012998#endif
12999#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013000 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013001#endif
13002#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013003 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013004#endif
13005#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013007#endif
13008#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013009 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013010#endif
13011#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013012 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013013#endif
13014
13015 /* constants for waitid */
13016#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013017 if (PyModule_AddIntMacro(m, P_PID)) return -1;
13018 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
13019 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013020#endif
13021#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013022 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013023#endif
13024#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013025 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013026#endif
13027#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013028 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013029#endif
13030#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013031 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013032#endif
13033#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013034 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013035#endif
13036#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013037 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013038#endif
13039#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013040 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013041#endif
13042
13043 /* constants for lockf */
13044#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013046#endif
13047#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013048 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013049#endif
13050#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013051 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013052#endif
13053#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013054 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013055#endif
13056
Guido van Rossum246bc171999-02-01 23:54:31 +000013057#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013058 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13059 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13060 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13061 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13062 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013063#endif
13064
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013065#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013066#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013067 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013068#endif
13069#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013070 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013071#endif
13072#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013073 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013074#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013075#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013076 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013077#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013078#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013079 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013080#endif
13081#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013082 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013083#endif
13084#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013085 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013086#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013087#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013088 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013089#endif
13090#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013091 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013092#endif
13093#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013094 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013095#endif
13096#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013097 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013098#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013099#endif
13100
Benjamin Peterson9428d532011-09-14 11:45:52 -040013101#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013102 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13103 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13104 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013105#endif
13106
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013107#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013108 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013109#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013110#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013111 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013112#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013113#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013114 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013115#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013116#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013117 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013118#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013119#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013120 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013121#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013122#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013123 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013124#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013125#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013126 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013127#endif
13128
Victor Stinner9b1f4742016-09-06 16:18:52 -070013129#ifdef HAVE_GETRANDOM_SYSCALL
13130 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
13131 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
13132#endif
13133
Victor Stinner8c62be82010-05-06 00:08:46 +000013134 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013135}
13136
13137
Martin v. Löwis1a214512008-06-11 05:26:20 +000013138static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013139 PyModuleDef_HEAD_INIT,
13140 MODNAME,
13141 posix__doc__,
13142 -1,
13143 posix_methods,
13144 NULL,
13145 NULL,
13146 NULL,
13147 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013148};
13149
13150
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013151static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013152
13153#ifdef HAVE_FACCESSAT
13154 "HAVE_FACCESSAT",
13155#endif
13156
13157#ifdef HAVE_FCHDIR
13158 "HAVE_FCHDIR",
13159#endif
13160
13161#ifdef HAVE_FCHMOD
13162 "HAVE_FCHMOD",
13163#endif
13164
13165#ifdef HAVE_FCHMODAT
13166 "HAVE_FCHMODAT",
13167#endif
13168
13169#ifdef HAVE_FCHOWN
13170 "HAVE_FCHOWN",
13171#endif
13172
Larry Hastings00964ed2013-08-12 13:49:30 -040013173#ifdef HAVE_FCHOWNAT
13174 "HAVE_FCHOWNAT",
13175#endif
13176
Larry Hastings9cf065c2012-06-22 16:30:09 -070013177#ifdef HAVE_FEXECVE
13178 "HAVE_FEXECVE",
13179#endif
13180
13181#ifdef HAVE_FDOPENDIR
13182 "HAVE_FDOPENDIR",
13183#endif
13184
Georg Brandl306336b2012-06-24 12:55:33 +020013185#ifdef HAVE_FPATHCONF
13186 "HAVE_FPATHCONF",
13187#endif
13188
Larry Hastings9cf065c2012-06-22 16:30:09 -070013189#ifdef HAVE_FSTATAT
13190 "HAVE_FSTATAT",
13191#endif
13192
13193#ifdef HAVE_FSTATVFS
13194 "HAVE_FSTATVFS",
13195#endif
13196
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013197#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013198 "HAVE_FTRUNCATE",
13199#endif
13200
Larry Hastings9cf065c2012-06-22 16:30:09 -070013201#ifdef HAVE_FUTIMENS
13202 "HAVE_FUTIMENS",
13203#endif
13204
13205#ifdef HAVE_FUTIMES
13206 "HAVE_FUTIMES",
13207#endif
13208
13209#ifdef HAVE_FUTIMESAT
13210 "HAVE_FUTIMESAT",
13211#endif
13212
13213#ifdef HAVE_LINKAT
13214 "HAVE_LINKAT",
13215#endif
13216
13217#ifdef HAVE_LCHFLAGS
13218 "HAVE_LCHFLAGS",
13219#endif
13220
13221#ifdef HAVE_LCHMOD
13222 "HAVE_LCHMOD",
13223#endif
13224
13225#ifdef HAVE_LCHOWN
13226 "HAVE_LCHOWN",
13227#endif
13228
13229#ifdef HAVE_LSTAT
13230 "HAVE_LSTAT",
13231#endif
13232
13233#ifdef HAVE_LUTIMES
13234 "HAVE_LUTIMES",
13235#endif
13236
13237#ifdef HAVE_MKDIRAT
13238 "HAVE_MKDIRAT",
13239#endif
13240
13241#ifdef HAVE_MKFIFOAT
13242 "HAVE_MKFIFOAT",
13243#endif
13244
13245#ifdef HAVE_MKNODAT
13246 "HAVE_MKNODAT",
13247#endif
13248
13249#ifdef HAVE_OPENAT
13250 "HAVE_OPENAT",
13251#endif
13252
13253#ifdef HAVE_READLINKAT
13254 "HAVE_READLINKAT",
13255#endif
13256
13257#ifdef HAVE_RENAMEAT
13258 "HAVE_RENAMEAT",
13259#endif
13260
13261#ifdef HAVE_SYMLINKAT
13262 "HAVE_SYMLINKAT",
13263#endif
13264
13265#ifdef HAVE_UNLINKAT
13266 "HAVE_UNLINKAT",
13267#endif
13268
13269#ifdef HAVE_UTIMENSAT
13270 "HAVE_UTIMENSAT",
13271#endif
13272
13273#ifdef MS_WINDOWS
13274 "MS_WINDOWS",
13275#endif
13276
13277 NULL
13278};
13279
13280
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013281PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013282INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013283{
Victor Stinner8c62be82010-05-06 00:08:46 +000013284 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013285 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013286 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013287
Brian Curtin52173d42010-12-02 18:29:18 +000013288#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013289 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013290#endif
13291
Victor Stinner8c62be82010-05-06 00:08:46 +000013292 m = PyModule_Create(&posixmodule);
13293 if (m == NULL)
13294 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013295
Victor Stinner8c62be82010-05-06 00:08:46 +000013296 /* Initialize environ dictionary */
13297 v = convertenviron();
13298 Py_XINCREF(v);
13299 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13300 return NULL;
13301 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013302
Victor Stinner8c62be82010-05-06 00:08:46 +000013303 if (all_ins(m))
13304 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013305
Victor Stinner8c62be82010-05-06 00:08:46 +000013306 if (setup_confname_tables(m))
13307 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013308
Victor Stinner8c62be82010-05-06 00:08:46 +000013309 Py_INCREF(PyExc_OSError);
13310 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013311
Guido van Rossumb3d39562000-01-31 18:41:26 +000013312#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013313 if (posix_putenv_garbage == NULL)
13314 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013315#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013316
Victor Stinner8c62be82010-05-06 00:08:46 +000013317 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013318#if defined(HAVE_WAITID) && !defined(__APPLE__)
13319 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013320 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13321 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013322#endif
13323
Christian Heimes25827622013-10-12 01:27:08 +020013324 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013325 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13326 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13327 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013328 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13329 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013330 structseq_new = StatResultType.tp_new;
13331 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013332
Christian Heimes25827622013-10-12 01:27:08 +020013333 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013334 if (PyStructSequence_InitType2(&StatVFSResultType,
13335 &statvfs_result_desc) < 0)
13336 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013337#ifdef NEED_TICKS_PER_SECOND
13338# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013339 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013340# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013341 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013342# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013343 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013344# endif
13345#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013346
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013347#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013348 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013349 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13350 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013351 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013352#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013353
13354 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013355 if (PyStructSequence_InitType2(&TerminalSizeType,
13356 &TerminalSize_desc) < 0)
13357 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013358
13359 /* initialize scandir types */
13360 if (PyType_Ready(&ScandirIteratorType) < 0)
13361 return NULL;
13362 if (PyType_Ready(&DirEntryType) < 0)
13363 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013364 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013365#if defined(HAVE_WAITID) && !defined(__APPLE__)
13366 Py_INCREF((PyObject*) &WaitidResultType);
13367 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13368#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013369 Py_INCREF((PyObject*) &StatResultType);
13370 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13371 Py_INCREF((PyObject*) &StatVFSResultType);
13372 PyModule_AddObject(m, "statvfs_result",
13373 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013374
13375#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013376 Py_INCREF(&SchedParamType);
13377 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013378#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013379
Larry Hastings605a62d2012-06-24 04:33:36 -070013380 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013381 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13382 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013383 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13384
13385 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013386 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13387 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013388 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13389
Thomas Wouters477c8d52006-05-27 19:21:47 +000013390#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013391 /*
13392 * Step 2 of weak-linking support on Mac OS X.
13393 *
13394 * The code below removes functions that are not available on the
13395 * currently active platform.
13396 *
13397 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013398 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013399 * OSX 10.4.
13400 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013401#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013402 if (fstatvfs == NULL) {
13403 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13404 return NULL;
13405 }
13406 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013407#endif /* HAVE_FSTATVFS */
13408
13409#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013410 if (statvfs == NULL) {
13411 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13412 return NULL;
13413 }
13414 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013415#endif /* HAVE_STATVFS */
13416
13417# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013418 if (lchown == NULL) {
13419 if (PyObject_DelAttrString(m, "lchown") == -1) {
13420 return NULL;
13421 }
13422 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013423#endif /* HAVE_LCHOWN */
13424
13425
13426#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013427
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013428 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013429 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13430
Larry Hastings6fe20b32012-04-19 15:07:49 -070013431 billion = PyLong_FromLong(1000000000);
13432 if (!billion)
13433 return NULL;
13434
Larry Hastings9cf065c2012-06-22 16:30:09 -070013435 /* suppress "function not used" warnings */
13436 {
13437 int ignored;
13438 fd_specified("", -1);
13439 follow_symlinks_specified("", 1);
13440 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13441 dir_fd_converter(Py_None, &ignored);
13442 dir_fd_unavailable(Py_None, &ignored);
13443 }
13444
13445 /*
13446 * provide list of locally available functions
13447 * so os.py can populate support_* lists
13448 */
13449 list = PyList_New(0);
13450 if (!list)
13451 return NULL;
13452 for (trace = have_functions; *trace; trace++) {
13453 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13454 if (!unicode)
13455 return NULL;
13456 if (PyList_Append(list, unicode))
13457 return NULL;
13458 Py_DECREF(unicode);
13459 }
13460 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013461
13462 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013463 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013464
13465 initialized = 1;
13466
Victor Stinner8c62be82010-05-06 00:08:46 +000013467 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013468}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013469
13470#ifdef __cplusplus
13471}
13472#endif